Browse Source

Use unmodified QtSingleApplication on Windows.

Get running application instance PID without QtSingleApplication
modification.
adaptive-webui-19844
Vladimir Golovnev (Glassez) 10 years ago
parent
commit
2dd473eb28
  1. 47
      src/app/application.cpp
  2. 17
      src/app/application.h
  3. 12
      src/app/main.cpp
  4. 47
      src/app/qtsingleapplication/qtlocalpeer.cpp
  5. 3
      src/app/qtsingleapplication/qtlocalpeer.h
  6. 6
      src/app/qtsingleapplication/qtsingleapplication.cpp
  7. 4
      src/app/qtsingleapplication/qtsingleapplication.h

47
src/app/application.cpp

@ -32,6 +32,10 @@
#include <QLocale> #include <QLocale>
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QSysInfo> #include <QSysInfo>
#ifdef Q_OS_WIN
#include <Windows.h>
#include <QSharedMemory>
#endif
#if (!defined(DISABLE_GUI) && defined(Q_OS_MAC)) #if (!defined(DISABLE_GUI) && defined(Q_OS_MAC))
#include <QFont> #include <QFont>
@ -41,11 +45,7 @@
#include "preferences.h" #include "preferences.h"
Application::Application(const QString &id, int &argc, char **argv) Application::Application(const QString &id, int &argc, char **argv)
#ifndef DISABLE_GUI : BaseApplication(id, argc, argv)
: SessionApplication(id, argc, argv)
#else
: QtSingleCoreApplication(id, argc, argv)
#endif
{ {
#if defined(Q_OS_MACX) && !defined(DISABLE_GUI) #if defined(Q_OS_MACX) && !defined(DISABLE_GUI)
if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_8) { if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_8) {
@ -62,6 +62,33 @@ Application::Application(const QString &id, int &argc, char **argv)
#endif #endif
} }
#ifdef Q_OS_WIN
bool Application::isRunning()
{
bool running = BaseApplication::isRunning();
QSharedMemory *sharedMem = new QSharedMemory(id() + QLatin1String("-shared-memory-key"), this);
if (!running) {
// First instance creates shared memory and store PID
if (sharedMem->create(sizeof(DWORD)) && sharedMem->lock()) {
*(static_cast<DWORD*>(sharedMem->data())) = ::GetCurrentProcessId();
sharedMem->unlock();
}
}
else {
// Later instances attach to shared memory and retrieve PID
if (sharedMem->attach() && sharedMem->lock()) {
::AllowSetForegroundWindow(*(static_cast<DWORD*>(sharedMem->data())));
sharedMem->unlock();
}
}
if (!sharedMem->isAttached())
qWarning() << "Failed to initialize shared memory: " << sharedMem->errorString();
return running;
}
#endif
void Application::initializeTranslation() void Application::initializeTranslation()
{ {
Preferences* const pref = Preferences::instance(); Preferences* const pref = Preferences::instance();
@ -72,10 +99,10 @@ void Application::initializeTranslation()
pref->setLocale(locale); pref->setLocale(locale);
} }
if (qtTranslator_.load( if (m_qtTranslator.load(
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
QString::fromUtf8("qtbase_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)) || QString::fromUtf8("qtbase_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)) ||
qtTranslator_.load( m_qtTranslator.load(
#endif #endif
QString::fromUtf8("qt_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { QString::fromUtf8("qt_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
qDebug("Qt %s locale recognized, using translation.", qPrintable(locale)); qDebug("Qt %s locale recognized, using translation.", qPrintable(locale));
@ -83,15 +110,15 @@ void Application::initializeTranslation()
else { else {
qDebug("Qt %s locale unrecognized, using default (en).", qPrintable(locale)); qDebug("Qt %s locale unrecognized, using default (en).", qPrintable(locale));
} }
installTranslator(&qtTranslator_); installTranslator(&m_qtTranslator);
if (translator_.load(QString::fromUtf8(":/lang/qbittorrent_") + locale)) { if (m_translator.load(QString::fromUtf8(":/lang/qbittorrent_") + locale)) {
qDebug("%s locale recognized, using translation.", qPrintable(locale)); qDebug("%s locale recognized, using translation.", qPrintable(locale));
} }
else { else {
qDebug("%s locale unrecognized, using default (en).", qPrintable(locale)); qDebug("%s locale unrecognized, using default (en).", qPrintable(locale));
} }
installTranslator(&translator_); installTranslator(&m_translator);
#ifndef DISABLE_GUI #ifndef DISABLE_GUI
if (locale.startsWith("ar") || locale.startsWith("he")) { if (locale.startsWith("ar") || locale.startsWith("he")) {

17
src/app/application.h

@ -35,23 +35,24 @@
#ifndef DISABLE_GUI #ifndef DISABLE_GUI
#include "sessionapplication.h" #include "sessionapplication.h"
typedef SessionApplication BaseApplication;
#else #else
#include "qtsinglecoreapplication.h" #include "qtsinglecoreapplication.h"
typedef QtSingleCoreApplication BaseApplication;
#endif #endif
class Application class Application : public BaseApplication
#ifndef DISABLE_GUI
: public SessionApplication
#else
: public QtSingleCoreApplication
#endif
{ {
public: public:
Application(const QString &id, int &argc, char **argv); Application(const QString &id, int &argc, char **argv);
#ifdef Q_OS_WIN
bool isRunning();
#endif
private: private:
QTranslator qtTranslator_; QTranslator m_qtTranslator;
QTranslator translator_; QTranslator m_translator;
void initializeTranslation(); void initializeTranslation();
}; };

12
src/app/main.cpp

@ -90,10 +90,6 @@ public:
#include "main.moc" #include "main.moc"
#if defined(Q_OS_WIN) && !defined(QBT_HAS_GETCURRENTPID)
#error You seem to have updated QtSingleApplication without porting our custom QtSingleApplication::getRunningPid() function. Please see previous version to understate how it works.
#endif
// Signal handlers // Signal handlers
#if defined(Q_OS_UNIX) || defined(STACKTRACE_WIN) #if defined(Q_OS_UNIX) || defined(STACKTRACE_WIN)
void sigintHandler(int); void sigintHandler(int);
@ -217,14 +213,8 @@ int main(int argc, char *argv[])
#else #else
qDebug("qBittorrent is already running for this user."); qDebug("qBittorrent is already running for this user.");
#endif #endif
misc::msleep(300); misc::msleep(300);
#ifdef Q_OS_WIN
DWORD pid = (DWORD)app->getRunningPid();
if (pid > 0) {
BOOL b = AllowSetForegroundWindow(pid);
qDebug("AllowSetForegroundWindow() returns %s", b ? "TRUE" : "FALSE");
}
#endif
if (!params.torrents.isEmpty()) { if (!params.torrents.isEmpty()) {
QString message = params.torrents.join("|"); QString message = params.torrents.join("|");
qDebug("Passing program parameters to running instance..."); qDebug("Passing program parameters to running instance...");

47
src/app/qtsingleapplication/qtlocalpeer.cpp

@ -195,56 +195,9 @@ void QtLocalPeer::receiveConnection()
return; return;
} }
QString message(QString::fromUtf8(uMsg)); QString message(QString::fromUtf8(uMsg));
#ifdef Q_OS_WIN
if (message == "qbt://pid") {
qint64 pid = GetCurrentProcessId();
socket->write((const char *)&pid, sizeof pid);
} else {
socket->write(ack, qstrlen(ack)); socket->write(ack, qstrlen(ack));
}
#else
socket->write(ack, qstrlen(ack));
#endif
socket->waitForBytesWritten(1000); socket->waitForBytesWritten(1000);
socket->waitForDisconnected(1000); // make sure client reads ack socket->waitForDisconnected(1000); // make sure client reads ack
delete socket; delete socket;
#ifdef Q_OS_WIN
if (message == "qbt://pid")
return;
#endif
emit messageReceived(message); //### (might take a long time to return) emit messageReceived(message); //### (might take a long time to return)
} }
#ifdef Q_OS_WIN
qint64 QtLocalPeer::getRunningPid() {
if (!isClient())
return 0;
QLocalSocket socket;
bool connOk = false;
for (int i = 0; i < 2; i++) {
// Try twice, in case the other instance is just starting up
socket.connectToServer(socketName);
connOk = socket.waitForConnected(5000/2);
if (connOk || i)
break;
Sleep(250);
}
if (!connOk) return -1;
const char* msg = "qbt://pid";
QDataStream ds(&socket);
ds.writeBytes(msg, qstrlen(msg));
bool res = socket.waitForBytesWritten(5000) && socket.waitForReadyRead(5000);
if (!res) return -1;
DWORD pid;
qint64 pid_size = sizeof pid;
while (socket.bytesAvailable() < pid_size)
socket.waitForReadyRead();
if (socket.read((char *)&pid, pid_size) < pid_size)
return -1;
return pid;
}
#endif

3
src/app/qtsingleapplication/qtlocalpeer.h

@ -57,9 +57,6 @@ public:
bool sendMessage(const QString &message, int timeout); bool sendMessage(const QString &message, int timeout);
QString applicationId() const QString applicationId() const
{ return id; } { return id; }
#ifdef Q_OS_WIN
qint64 getRunningPid();
#endif
Q_SIGNALS: Q_SIGNALS:
void messageReceived(const QString &message); void messageReceived(const QString &message);

6
src/app/qtsingleapplication/qtsingleapplication.cpp

@ -345,9 +345,3 @@ void QtSingleApplication::activateWindow()
\obsolete \obsolete
*/ */
#ifdef Q_OS_WIN
qint64 QtSingleApplication::getRunningPid() {
return peer->getRunningPid();
}
#endif

4
src/app/qtsingleapplication/qtsingleapplication.h

@ -86,10 +86,6 @@ public:
// Obsolete: // Obsolete:
void initialize(bool dummy = true) void initialize(bool dummy = true)
{ isRunning(); Q_UNUSED(dummy) } { isRunning(); Q_UNUSED(dummy) }
#ifdef Q_OS_WIN
#define QBT_HAS_GETCURRENTPID
qint64 getRunningPid();
#endif
public Q_SLOTS: public Q_SLOTS:
bool sendMessage(const QString &message, int timeout = 5000); bool sendMessage(const QString &message, int timeout = 5000);

Loading…
Cancel
Save