From 89b82778e6ca1f73bead400cef2d4bfb82ff9ad2 Mon Sep 17 00:00:00 2001 From: sledgehammer999 Date: Sun, 15 Sep 2013 00:10:01 +0300 Subject: [PATCH 1/3] Add interface to request the pid of the running instance. --- src/qtsingleapp/qtlocalpeer.cpp | 54 +++++++++++++++++++++++++ src/qtsingleapp/qtlocalpeer.h | 3 ++ src/qtsingleapp/qtsingleapplication.cpp | 6 +++ src/qtsingleapp/qtsingleapplication.h | 3 ++ 4 files changed, 66 insertions(+) diff --git a/src/qtsingleapp/qtlocalpeer.cpp b/src/qtsingleapp/qtlocalpeer.cpp index 72f8cd6db..fcf2d4a83 100644 --- a/src/qtsingleapp/qtlocalpeer.cpp +++ b/src/qtsingleapp/qtlocalpeer.cpp @@ -201,8 +201,62 @@ void QtLocalPeer::receiveConnection() return; } QString message(QString::fromUtf8(uMsg)); +#ifdef Q_OS_WIN + if (message == "qbt://pid") + socket->write(QByteArray::number(qApp->applicationPid())); + else + socket->write(ack, qstrlen(ack)); +#else socket->write(ack, qstrlen(ack)); +#endif socket->waitForBytesWritten(1000); delete socket; +#ifdef Q_OS_WIN + if (message == "qbt://pid") + return; +#endif emit messageReceived(message); //### (might take a long time to return) } + +#ifdef Q_OS_WIN +ulong QtLocalPeer::getRunningPid() { + if (!isClient()) + return false; + + 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(DWORD(250)); + } + if (!connOk) + return false; + QByteArray uMsg("qbt://pid"); + QDataStream ds(&socket); + ds.writeBytes(uMsg.constData(), uMsg.size()); + bool res = socket.waitForBytesWritten(5000); + res &= socket.waitForReadyRead(5000); + if (!res) + return -1; + while (socket.bytesAvailable() < (int)sizeof(quint32)) + socket.waitForReadyRead(); + uMsg.clear(); + quint32 remaining = socket.bytesAvailable(); + uMsg.resize(remaining); + int got = 0; + char* uMsgBuf = uMsg.data(); + do { + got = ds.readRawData(uMsgBuf, remaining); + remaining -= got; + uMsgBuf += got; + } while (remaining && got >= 0 && socket.waitForReadyRead(2000)); + if (got < 0) + return -1; + + return uMsg.toULong(); +} +#endif diff --git a/src/qtsingleapp/qtlocalpeer.h b/src/qtsingleapp/qtlocalpeer.h index b81dbd11a..3a6d46959 100644 --- a/src/qtsingleapp/qtlocalpeer.h +++ b/src/qtsingleapp/qtlocalpeer.h @@ -64,6 +64,9 @@ public: bool sendMessage(const QString &message, int timeout); QString applicationId() const { return id; } +#ifdef Q_OS_WIN + ulong getRunningPid(); +#endif Q_SIGNALS: void messageReceived(const QString &message); diff --git a/src/qtsingleapp/qtsingleapplication.cpp b/src/qtsingleapp/qtsingleapplication.cpp index a3a1fd7fd..fa0b0b6a6 100644 --- a/src/qtsingleapp/qtsingleapplication.cpp +++ b/src/qtsingleapp/qtsingleapplication.cpp @@ -349,3 +349,9 @@ void QtSingleApplication::activateWindow() \obsolete */ + +#ifdef Q_OS_WIN +ulong QtSingleApplication::getRunningPid() { + return peer->getRunningPid(); +} +#endif diff --git a/src/qtsingleapp/qtsingleapplication.h b/src/qtsingleapp/qtsingleapplication.h index 5df916561..e45e373c9 100644 --- a/src/qtsingleapp/qtsingleapplication.h +++ b/src/qtsingleapp/qtsingleapplication.h @@ -88,6 +88,9 @@ public: // Obsolete: void initialize(bool dummy = true) { isRunning(); Q_UNUSED(dummy) } +#ifdef Q_OS_WIN + ulong getRunningPid(); +#endif public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000); From b78ea79d30808857b6c8be23a27d19c373de2934 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Tue, 17 Sep 2013 16:18:01 +0400 Subject: [PATCH 2/3] Bringing the AddNewTorrentDialog to the front. --- src/addnewtorrentdialog.cpp | 7 +++++++ src/addnewtorrentdialog.h | 3 +++ src/main.cpp | 7 +++++++ src/mainwindow.cpp | 22 ++++++++++------------ 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/addnewtorrentdialog.cpp b/src/addnewtorrentdialog.cpp index 883e31032..8df66315d 100644 --- a/src/addnewtorrentdialog.cpp +++ b/src/addnewtorrentdialog.cpp @@ -140,6 +140,13 @@ void AddNewTorrentDialog::showMagnet(const QString& link) dlg.exec(); } +void AddNewTorrentDialog::showEvent(QShowEvent *event) { + QDialog::showEvent(event); + activateWindow(); + raise(); +} + + void AddNewTorrentDialog::showAdvancedSettings(bool show) { if (show) { diff --git a/src/addnewtorrentdialog.h b/src/addnewtorrentdialog.h index 9ce3d9791..dec472805 100644 --- a/src/addnewtorrentdialog.h +++ b/src/addnewtorrentdialog.h @@ -56,6 +56,9 @@ public: static void showTorrent(const QString& torrent_path, const QString& from_url = QString()); static void showMagnet(const QString& torrent_link); +protected: + void showEvent(QShowEvent *event); + private slots: void showAdvancedSettings(bool show); void displayContentTreeMenu(const QPoint&); diff --git a/src/main.cpp b/src/main.cpp index 637dd43bf..a1912fb48 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -206,6 +206,13 @@ int main(int argc, char *argv[]) { if (app.isRunning()) { qDebug("qBittorrent is already running for this user."); // Read torrents given on command line +#ifdef Q_OS_WIN + DWORD pid = app.getRunningPid(); + if (pid > 0) { + BOOL b = AllowSetForegroundWindow(pid); + qDebug("AllowSetForegroundWindow() returns %s", b ? "TRUE" : "FALSE"); + } +#endif QStringList torrentCmdLine = app.arguments(); //Pass program parameters if any QString message; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 241ab69b0..7ad6a0b49 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -263,14 +263,8 @@ MainWindow::MainWindow(QWidget *parent, const QStringList& torrentCmdLine) : QMa // Load Window state and sizes readSettings(); - if (!ui_locked) { - if (pref.startMinimized() && systrayIcon) { - show(); - minimizeWindow(); - // XXX: Using showMinimized() makes it impossible to restore - // the window if "Minimize to systray" is enabled. - //showMinimized(); - } else { + if (systrayIcon) { + if (!(pref.startMinimized() || ui_locked)) { show(); activateWindow(); raise(); @@ -323,10 +317,14 @@ MainWindow::MainWindow(QWidget *parent, const QStringList& torrentCmdLine) : QMa #endif // Make sure the Window is visible if we don't have a tray icon - if (!systrayIcon && isHidden()) { - show(); - activateWindow(); - raise(); + if (!systrayIcon) { + if (pref.startMinimized()) { + showMinimized(); + } else { + show(); + activateWindow(); + raise(); + } } } From dbf8675de3a29643676f779340c79d4fc98b81b7 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Tue, 17 Sep 2013 16:21:23 +0400 Subject: [PATCH 3/3] Some improvements of requesting pid of running instance code. --- src/main.cpp | 6 ++- src/qtsingleapp/qtlocalpeer.cpp | 49 +++++++++++-------------- src/qtsingleapp/qtlocalpeer.h | 2 +- src/qtsingleapp/qtsingleapplication.cpp | 2 +- src/qtsingleapp/qtsingleapplication.h | 3 +- 5 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a1912fb48..809e3a084 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -75,6 +75,10 @@ Q_IMPORT_PLUGIN(qico) #include "misc.h" #include "preferences.h" +#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 + class UsageDisplay: public QObject { Q_OBJECT @@ -207,7 +211,7 @@ int main(int argc, char *argv[]) { qDebug("qBittorrent is already running for this user."); // Read torrents given on command line #ifdef Q_OS_WIN - DWORD pid = app.getRunningPid(); + DWORD pid = (DWORD)app.getRunningPid(); if (pid > 0) { BOOL b = AllowSetForegroundWindow(pid); qDebug("AllowSetForegroundWindow() returns %s", b ? "TRUE" : "FALSE"); diff --git a/src/qtsingleapp/qtlocalpeer.cpp b/src/qtsingleapp/qtlocalpeer.cpp index fcf2d4a83..fe770c6e1 100644 --- a/src/qtsingleapp/qtlocalpeer.cpp +++ b/src/qtsingleapp/qtlocalpeer.cpp @@ -202,10 +202,12 @@ void QtLocalPeer::receiveConnection() } QString message(QString::fromUtf8(uMsg)); #ifdef Q_OS_WIN - if (message == "qbt://pid") - socket->write(QByteArray::number(qApp->applicationPid())); - else + if (message == "qbt://pid") { + qint64 pid = GetCurrentProcessId(); + socket->write((const char *)&pid, sizeof pid); + } else { socket->write(ack, qstrlen(ack)); + } #else socket->write(ack, qstrlen(ack)); #endif @@ -219,9 +221,9 @@ void QtLocalPeer::receiveConnection() } #ifdef Q_OS_WIN -ulong QtLocalPeer::getRunningPid() { +qint64 QtLocalPeer::getRunningPid() { if (!isClient()) - return false; + return 0; QLocalSocket socket; bool connOk = false; @@ -231,32 +233,23 @@ ulong QtLocalPeer::getRunningPid() { connOk = socket.waitForConnected(5000/2); if (connOk || i) break; - Sleep(DWORD(250)); + Sleep(250); } - if (!connOk) - return false; - QByteArray uMsg("qbt://pid"); + if (!connOk) return -1; + + const char* msg = "qbt://pid"; QDataStream ds(&socket); - ds.writeBytes(uMsg.constData(), uMsg.size()); - bool res = socket.waitForBytesWritten(5000); - res &= socket.waitForReadyRead(5000); - if (!res) - return -1; - while (socket.bytesAvailable() < (int)sizeof(quint32)) + 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(); - uMsg.clear(); - quint32 remaining = socket.bytesAvailable(); - uMsg.resize(remaining); - int got = 0; - char* uMsgBuf = uMsg.data(); - do { - got = ds.readRawData(uMsgBuf, remaining); - remaining -= got; - uMsgBuf += got; - } while (remaining && got >= 0 && socket.waitForReadyRead(2000)); - if (got < 0) - return -1; + if (socket.read((char *)&pid, pid_size) < pid_size) + return -1; - return uMsg.toULong(); + return pid; } #endif diff --git a/src/qtsingleapp/qtlocalpeer.h b/src/qtsingleapp/qtlocalpeer.h index 3a6d46959..2fa091f3f 100644 --- a/src/qtsingleapp/qtlocalpeer.h +++ b/src/qtsingleapp/qtlocalpeer.h @@ -65,7 +65,7 @@ public: QString applicationId() const { return id; } #ifdef Q_OS_WIN - ulong getRunningPid(); + qint64 getRunningPid(); #endif Q_SIGNALS: diff --git a/src/qtsingleapp/qtsingleapplication.cpp b/src/qtsingleapp/qtsingleapplication.cpp index fa0b0b6a6..c3b894348 100644 --- a/src/qtsingleapp/qtsingleapplication.cpp +++ b/src/qtsingleapp/qtsingleapplication.cpp @@ -351,7 +351,7 @@ void QtSingleApplication::activateWindow() */ #ifdef Q_OS_WIN -ulong QtSingleApplication::getRunningPid() { +qint64 QtSingleApplication::getRunningPid() { return peer->getRunningPid(); } #endif diff --git a/src/qtsingleapp/qtsingleapplication.h b/src/qtsingleapp/qtsingleapplication.h index e45e373c9..0ffd8f6ee 100644 --- a/src/qtsingleapp/qtsingleapplication.h +++ b/src/qtsingleapp/qtsingleapplication.h @@ -89,7 +89,8 @@ public: void initialize(bool dummy = true) { isRunning(); Q_UNUSED(dummy) } #ifdef Q_OS_WIN - ulong getRunningPid(); +#define QBT_HAS_GETCURRENTPID + qint64 getRunningPid(); #endif public Q_SLOTS: