Skip to content

Commit c7f3693

Browse files
committed
Implement "Application instances manager"
1 parent c0557c2 commit c7f3693

25 files changed

Lines changed: 163 additions & 863 deletions

configure

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,6 @@ ac_user_opts='
719719
enable_option_checking
720720
enable_dependency_tracking
721721
enable_silent_rules
722-
with_qtsingleapplication
723722
enable_debug
724723
enable_stacktrace
725724
enable_gui
@@ -1399,9 +1398,6 @@ Optional Features:
13991398
Optional Packages:
14001399
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
14011400
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
1402-
--with-qtsingleapplication=[system|shipped]
1403-
Use the shipped qtsingleapplication library or the
1404-
system one (default=shipped)
14051401
--with-boost[=ARG] use Boost library from a standard location
14061402
(ARG=yes), from the specified location (ARG=<path>),
14071403
or disable it (ARG=no) [ARG=yes]
@@ -4187,14 +4183,6 @@ QBT_CXX="$CXX"
41874183
# Define --wth-* and --enable-* arguments
41884184

41894185

4190-
# Check whether --with-qtsingleapplication was given.
4191-
if test "${with_qtsingleapplication+set}" = set; then :
4192-
withval=$with_qtsingleapplication;
4193-
else
4194-
with_qtsingleapplication=shipped
4195-
fi
4196-
4197-
41984186
# Check whether --enable-debug was given.
41994187
if test "${enable_debug+set}" = set; then :
42004188
enableval=$enable_debug;
@@ -5294,23 +5282,6 @@ fi
52945282
$as_echo "$as_me: Boost.System LIB: \"$BOOST_SYSTEM_LIB\"" >&6;}
52955283
LIBS="$BOOST_SYSTEM_LIB $LIBS"
52965284

5297-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which qtsingleapplication to use" >&5
5298-
$as_echo_n "checking which qtsingleapplication to use... " >&6; }
5299-
case "x$with_qtsingleapplication" in #(
5300-
"xshipped") :
5301-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: shipped" >&5
5302-
$as_echo "shipped" >&6; }
5303-
QBT_REMOVE_CONFIG="$QBT_REMOVE_CONFIG usesystemqtsingleapplication" ;; #(
5304-
"xsystem") :
5305-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: system" >&5
5306-
$as_echo "system" >&6; }
5307-
QBT_ADD_CONFIG="$QBT_ADD_CONFIG usesystemqtsingleapplication" ;; #(
5308-
*) :
5309-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_qtsingleapplication" >&5
5310-
$as_echo "$with_qtsingleapplication" >&6; }
5311-
as_fn_error $? "Unknown option \"$with_qtsingleapplication\". Use either \"system\" or \"shipped\"." "$LINENO" 5 ;;
5312-
esac
5313-
53145285

53155286
pkg_failed=no
53165287
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libtorrent" >&5

configure.ac

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@ QBT_CXX="$CXX"
1414

1515
# Define --wth-* and --enable-* arguments
1616

17-
AC_ARG_WITH(qtsingleapplication,
18-
[AS_HELP_STRING([--with-qtsingleapplication=@<:@system|shipped@:>@],
19-
[Use the shipped qtsingleapplication library or the system one (default=shipped)])],
20-
[],
21-
[with_qtsingleapplication=shipped])
22-
2317
AC_ARG_ENABLE(debug,
2418
[AS_HELP_STRING([--enable-debug],
2519
[Enable debug build])],
@@ -183,17 +177,6 @@ AX_BOOST_SYSTEM()
183177
AC_MSG_NOTICE([Boost.System LIB: "$BOOST_SYSTEM_LIB"])
184178
LIBS="$BOOST_SYSTEM_LIB $LIBS"
185179

186-
AC_MSG_CHECKING([which qtsingleapplication to use])
187-
AS_CASE(["x$with_qtsingleapplication"],
188-
["xshipped"],
189-
[AC_MSG_RESULT([shipped])
190-
QBT_REMOVE_CONFIG="$QBT_REMOVE_CONFIG usesystemqtsingleapplication"],
191-
["xsystem"],
192-
[AC_MSG_RESULT([system])
193-
QBT_ADD_CONFIG="$QBT_ADD_CONFIG usesystemqtsingleapplication"],
194-
[AC_MSG_RESULT([$with_qtsingleapplication])
195-
AC_MSG_ERROR([Unknown option "$with_qtsingleapplication". Use either "system" or "shipped".])])
196-
197180
PKG_CHECK_MODULES(libtorrent,
198181
[libtorrent-rasterbar >= 1.1.10],
199182
[CXXFLAGS="$libtorrent_CFLAGS $CXXFLAGS"

src/CMakeLists.txt

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,6 @@ endif()
6868

6969
configure_file(config.h.cmakein ${CMAKE_CURRENT_BINARY_DIR}/config.h)
7070

71-
find_package(QtSingleApplication)
72-
set_package_properties(QtSingleApplication PROPERTIES
73-
URL "https://code.qt.io/cgit/qt-solutions/qt-solutions.git/"
74-
DESCRIPTION "Qt library to start applications only once per user"
75-
TYPE RECOMMENDED
76-
PURPOSE "Use the system qtsingleapplication library or shipped one otherwise"
77-
)
78-
79-
if (NOT QtSingleApplication_FOUND)
80-
add_subdirectory(app/qtsingleapplication)
81-
endif ()
82-
8371
add_subdirectory(app)
8472
add_subdirectory(base)
8573

src/app/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
add_executable(qBittorrent
22
application.h
3+
applicationinstancemanager.h
34
cmdoptions.h
45
filelogger.h
6+
qtlocalpeer/qtlocalpeer.h
57
upgrade.h
68
application.cpp
9+
applicationinstancemanager.cpp
710
cmdoptions.cpp
811
filelogger.cpp
912
main.cpp
13+
qtlocalpeer/qtlocalpeer.cpp
1014
upgrade.cpp
1115
)
1216

@@ -135,8 +139,6 @@ target_sources(qBittorrent PRIVATE ${QBT_QM_FILES} ${QBT_APP_RESOURCE_SOURCE})
135139

136140
get_target_property(QBT_EXECUTABLE_NAME qBittorrent OUTPUT_NAME)
137141

138-
target_link_libraries(qBittorrent PRIVATE ${QBT_TARGET_LIBRARIES} QtSingleApplication::QtSingleApplication)
139-
140142
if (APPLE)
141143
set(qbt_BUNDLE_NAME ${QBT_EXECUTABLE_NAME})
142144

src/app/app.pri

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,20 @@
11
INCLUDEPATH += $$PWD
22

3-
usesystemqtsingleapplication {
4-
nogui {
5-
CONFIG += qtsinglecoreapplication
6-
} else {
7-
CONFIG += qtsingleapplication
8-
}
9-
} else {
10-
nogui {
11-
include(qtsingleapplication/qtsinglecoreapplication.pri)
12-
} else {
13-
include(qtsingleapplication/qtsingleapplication.pri)
14-
}
15-
}
16-
173
HEADERS += \
184
$$PWD/application.h \
5+
$$PWD/applicationinstancemanager.h \
196
$$PWD/cmdoptions.h \
207
$$PWD/filelogger.h \
8+
$$PWD/qtlocalpeer/qtlocalpeer.h \
219
$$PWD/upgrade.h
2210

2311
SOURCES += \
2412
$$PWD/application.cpp \
13+
$$PWD/applicationinstancemanager.cpp \
2514
$$PWD/cmdoptions.cpp \
2615
$$PWD/filelogger.cpp \
2716
$$PWD/main.cpp \
17+
$$PWD/qtlocalpeer/qtlocalpeer.cpp \
2818
$$PWD/upgrade.cpp
2919

3020
stacktrace {

src/app/application.cpp

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
#include "base/utils/fs.h"
8383
#include "base/utils/misc.h"
8484
#include "base/utils/string.h"
85+
#include "applicationinstancemanager.h"
8586
#include "filelogger.h"
8687

8788
#ifndef DISABLE_WEBUI
@@ -116,7 +117,8 @@ namespace
116117
}
117118

118119
Application::Application(const QString &id, int &argc, char **argv)
119-
: BaseApplication(id, argc, argv)
120+
: BaseApplication(argc, argv)
121+
, m_instanceManager(new ApplicationInstanceManager {id, this})
120122
, m_running(false)
121123
, m_shutdownAct(ShutdownDialogAction::Exit)
122124
, m_commandLineArgs(parseCommandLine(this->arguments()))
@@ -156,7 +158,7 @@ Application::Application(const QString &id, int &argc, char **argv)
156158
connect(this, &QGuiApplication::commitDataRequest, this, &Application::shutdownCleanup, Qt::DirectConnection);
157159
#endif
158160

159-
connect(this, &Application::messageReceived, this, &Application::processMessage);
161+
connect(m_instanceManager, &ApplicationInstanceManager::messageReceived, this, &Application::processMessage);
160162
connect(this, &QCoreApplication::aboutToQuit, this, &Application::cleanup);
161163

162164
if (isFileLoggerEnabled())
@@ -417,7 +419,7 @@ void Application::allTorrentsFinished()
417419

418420
bool Application::sendParams(const QStringList &params)
419421
{
420-
return sendMessage(params.join(PARAMS_SEPARATOR));
422+
return m_instanceManager->sendMessage(params.join(PARAMS_SEPARATOR));
421423
}
422424

423425
// As program parameters, we can get paths or urls.
@@ -572,34 +574,12 @@ int Application::exec(const QStringList &params)
572574
return BaseApplication::exec();
573575
}
574576

575-
#ifndef DISABLE_GUI
576-
#ifdef Q_OS_WIN
577577
bool Application::isRunning()
578578
{
579-
const bool running = BaseApplication::isRunning();
580-
QSharedMemory *sharedMem = new QSharedMemory(id() + QLatin1String("-shared-memory-key"), this);
581-
if (!running) {
582-
// First instance creates shared memory and store PID
583-
if (sharedMem->create(sizeof(DWORD)) && sharedMem->lock()) {
584-
*(static_cast<DWORD*>(sharedMem->data())) = ::GetCurrentProcessId();
585-
sharedMem->unlock();
586-
}
587-
}
588-
else {
589-
// Later instances attach to shared memory and retrieve PID
590-
if (sharedMem->attach() && sharedMem->lock()) {
591-
::AllowSetForegroundWindow(*(static_cast<DWORD*>(sharedMem->data())));
592-
sharedMem->unlock();
593-
}
594-
}
595-
596-
if (!sharedMem->isAttached())
597-
qWarning() << "Failed to initialize shared memory: " << sharedMem->errorString();
598-
599-
return running;
579+
return !m_instanceManager->isFirstInstance();
600580
}
601-
#endif // Q_OS_WIN
602581

582+
#ifndef DISABLE_GUI
603583
#ifdef Q_OS_MAC
604584
bool Application::event(QEvent *ev)
605585
{
@@ -740,11 +720,11 @@ void Application::cleanup()
740720
#ifndef DISABLE_GUI
741721
if (m_window) {
742722
#ifdef Q_OS_WIN
743-
typedef BOOL (WINAPI *PSHUTDOWNBRDESTROY)(HWND);
723+
using PSHUTDOWNBRDESTROY = BOOL (WINAPI *)(HWND);
744724
const auto shutdownBRDestroy = Utils::Misc::loadWinAPI<PSHUTDOWNBRDESTROY>("User32.dll", "ShutdownBlockReasonDestroy");
745725
// Only available on Vista+
746726
if (shutdownBRDestroy)
747-
shutdownBRDestroy((HWND)m_window->effectiveWinId());
727+
shutdownBRDestroy(reinterpret_cast<HWND>(m_window->effectiveWinId()));
748728
#endif // Q_OS_WIN
749729
delete m_window;
750730
}

src/app/application.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Bittorrent Client using Qt and libtorrent.
3-
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
3+
* Copyright (C) 2015, 2019 Vladimir Golovnev <glassez@yandex.ru>
44
* Copyright (C) 2006 Christophe Dumez
55
*
66
* This program is free software; you can redistribute it and/or
@@ -27,25 +27,24 @@
2727
* exception statement from your version.
2828
*/
2929

30-
#ifndef APPLICATION_H
31-
#define APPLICATION_H
30+
#pragma once
3231

3332
#include <QPointer>
3433
#include <QStringList>
3534
#include <QTranslator>
3635

3736
#ifndef DISABLE_GUI
38-
#include "qtsingleapplication.h"
39-
typedef QtSingleApplication BaseApplication;
37+
#include <QApplication>
38+
using BaseApplication = QApplication;
4039
class MainWindow;
4140

4241
#ifdef Q_OS_WIN
4342
class QSessionManager;
4443
#endif // Q_OS_WIN
4544

4645
#else
47-
#include "qtsinglecoreapplication.h"
48-
typedef QtSingleCoreApplication BaseApplication;
46+
#include <QCoreApplication>
47+
using BaseApplication = QCoreApplication;
4948
#endif // DISABLE_GUI
5049

5150
#include "base/types.h"
@@ -55,6 +54,7 @@ typedef QtSingleCoreApplication BaseApplication;
5554
class WebUI;
5655
#endif
5756

57+
class ApplicationInstanceManager;
5858
class FileLogger;
5959

6060
namespace BitTorrent
@@ -77,9 +77,7 @@ class Application : public BaseApplication
7777
Application(const QString &id, int &argc, char **argv);
7878
~Application() override;
7979

80-
#if (defined(Q_OS_WIN) && !defined(DISABLE_GUI))
8180
bool isRunning();
82-
#endif
8381
int exec(const QStringList &params);
8482
bool sendParams(const QStringList &params);
8583

@@ -122,6 +120,7 @@ private slots:
122120
#endif
123121

124122
private:
123+
ApplicationInstanceManager *m_instanceManager;
125124
bool m_running;
126125
ShutdownDialogAction m_shutdownAct;
127126
QBtCommandLineParameters m_commandLineArgs;
@@ -147,5 +146,3 @@ private slots:
147146
void sendNotificationEmail(const BitTorrent::TorrentHandle *torrent);
148147
void validateCommandLineParameters();
149148
};
150-
151-
#endif // APPLICATION_H

0 commit comments

Comments
 (0)