diff --git a/.ci/macos/build.sh b/.ci/macos/build.sh index e4978231..34dee564 100755 --- a/.ci/macos/build.sh +++ b/.ci/macos/build.sh @@ -20,6 +20,7 @@ cmake -GNinja -S. -Bbuild \ -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF \ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHUNTER_CONFIGURATION_TYPES=RelWithDebInfo \ -DUSE_BUNDLED_OPENSSL=ON \ + -DUSE_BUNDLED_KDSINGLEAPPLICATION=ON \ -DQt6_DIR=${QT_BASEPATH}/lib/cmake \ -DCI_BUILD=ON cmake --build build diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a273b831..5476f1ac 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,7 +25,7 @@ build-clazy: - export CMAKE_BUILD_PARALLEL_LEVEL=$(cat /proc/cpuinfo | awk '/^processor/{print $3}' | wc -l) - cmake -GNinja -H. -Bbuild -DCMAKE_INSTALL_PREFIX=.deps/usr - -DHUNTER_ENABLED=OFF -DBUILD_SHARED_LIBS=OFF -DUSE_BUNDLED_OPENSSL=ON -DUSE_BUNDLED_MTXCLIENT=ON -DUSE_BUNDLED_COEURL=ON -DUSE_BUNDLED_OLM=ON -DUSE_BUNDLED_QTKEYCHAIN=ON + -DHUNTER_ENABLED=OFF -DBUILD_SHARED_LIBS=OFF -DUSE_BUNDLED_OPENSSL=ON -DUSE_BUNDLED_MTXCLIENT=ON -DUSE_BUNDLED_COEURL=ON -DUSE_BUNDLED_OLM=ON -DUSE_BUNDLED_QTKEYCHAIN=ON -DUSE_BUNDLED_KDSINGLEAPPLICATION=ON -DVOIP=OFF -DCMAKE_BUILD_TYPE=Release -DCI_BUILD=ON -DFETCHCONTENT_QUIET=OFF -DCMAKE_CXX_COMPILER=clazy @@ -62,7 +62,7 @@ build-clazy: - cmake -GNinja -H. -Bbuild -DCMAKE_INSTALL_PREFIX=.deps/usr -DHUNTER_ROOT="../.hunter" - -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF -DUSE_BUNDLED_OPENSSL=ON -DUSE_BUNDLED_LMDB=OFF -DUSE_BUNDLED_QTKEYCHAIN=OFF + -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF -DUSE_BUNDLED_OPENSSL=ON -DUSE_BUNDLED_LMDB=OFF -DUSE_BUNDLED_QTKEYCHAIN=OFF -DUSE_BUNDLED_KDSINGLEAPPLICATION=ON -DVOIP=OFF -DCMAKE_BUILD_TYPE=Release -DHUNTER_CONFIGURATION_TYPES=Release -DCI_BUILD=ON -DFETCHCONTENT_QUIET=OFF @@ -128,7 +128,7 @@ build-tw: - export PATH="/usr/lib64/ccache:${PATH}" - cmake -GNinja -H. -Bbuild -DCMAKE_INSTALL_PREFIX=.deps/usr - -DUSE_BUNDLED_MTXCLIENT=ON -DUSE_BUNDLED_COEURL=ON -DUSE_BUNDLED_LMDBXX=ON + -DUSE_BUNDLED_MTXCLIENT=ON -DUSE_BUNDLED_COEURL=ON -DUSE_BUNDLED_LMDBXX=ON -DUSE_BUNDLED_KDSINGLEAPPLICATION=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-Wno-error=array-bounds" -DCI_BUILD=ON -DFETCHCONTENT_QUIET=OFF @@ -283,7 +283,7 @@ build-flatpak: - cmake -GNinja -H. -Bbuild -DCMAKE_INSTALL_PREFIX=/usr -DHUNTER_ROOT=".hunter" - -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF -DUSE_BUNDLED_OPENSSL=ON -DUSE_BUNDLED_LMDB=OFF -DUSE_BUNDLED_QTKEYCHAIN=OFF -DUSE_BUNDLED_LIBEVENT=OFF + -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF -DUSE_BUNDLED_OPENSSL=ON -DUSE_BUNDLED_LMDB=OFF -DUSE_BUNDLED_QTKEYCHAIN=OFF -DUSE_BUNDLED_LIBEVENT=OFF -DUSE_BUNDLED_KDSINGLEAPPLICATION=ON -DVOIP=OFF -DMAN=OFF -DCMAKE_BUILD_TYPE=Release -DHUNTER_CONFIGURATION_TYPES=Release -DCI_BUILD=ON -DFETCHCONTENT_QUIET=OFF diff --git a/CMakeLists.txt b/CMakeLists.txt index af983590..7f7eb942 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,7 @@ option(USE_BUNDLED_COEURL "Use a bundled version of the Curl wrapper" option(USE_BUNDLED_LIBEVENT "Use the bundled version of libevent." ${HUNTER_ENABLED}) option(USE_BUNDLED_LIBCURL "Use the bundled version of libcurl." ${HUNTER_ENABLED}) option(USE_BUNDLED_RE2 "Use the bundled version of re2." ${HUNTER_ENABLED}) +option(USE_BUNDLED_KDSINGLEAPPLICATION "Use the bundled version of KDSingleApplication." ${HUNTER_ENABLED}) option(USE_BUNDLED_CPPHTTPLIB "Use the bundled version of cpp-httplib." ON) option(USE_BUNDLED_BLURHASH "Use the bundled version of blurhash." ON) @@ -251,17 +252,26 @@ if(USE_BUNDLED_QTKEYCHAIN) GIT_REPOSITORY https://github.com/frankosterfeld/qtkeychain.git GIT_TAG v0.14.0 ) - if(BUILD_SHARED_LIBS) - set(QTKEYCHAIN_STATIC OFF CACHE INTERNAL "") - else() - set(QTKEYCHAIN_STATIC ON CACHE INTERNAL "") - endif() set(BUILD_TEST_APPLICATION OFF CACHE INTERNAL "") FetchContent_MakeAvailable(qt6keychain) else() find_package(Qt6Keychain REQUIRED) endif() +if(USE_BUNDLED_KDSINGLEAPPLICATION) + include(FetchContent) + set(KDSingleApplication_QT6 ON CACHE BOOL INTERNAL) + set(KDSingleApplication_EXAMPLES OFF CACHE BOOL INTERNAL) + FetchContent_Declare( + kdsingleapplication + GIT_REPOSITORY https://github.com/KDAB/KDSingleApplication.git + GIT_TAG v1.0.0 + ) + FetchContent_MakeAvailable(kdsingleapplication) +else() + find_package(KDSingleApplication-qt6 REQUIRED) +endif() + if(Qt6Widgets_FOUND) if(Qt6Widgets_VERSION VERSION_LESS 6.5.0) message(STATUS "Qt version ${Qt6Widgets_VERSION}") @@ -613,10 +623,6 @@ if(X11 AND NOT WIN32 AND NOT APPLE AND NOT HAIKU) pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb xcb-ewmh) endif() -# single instance functionality -set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication") -add_subdirectory(third_party/SingleApplication-3.3.2/) - feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) # this must be defined here to make the moc work properly @@ -867,6 +873,9 @@ endif() if(USE_BUNDLED_QTKEYCHAIN) target_include_directories(nheko PRIVATE ${qt6keychain_SOURCE_DIR} ${qt6keychain_BINARY_DIR}) endif() +if(USE_BUNDLED_KDSINGLEAPPLICATION) + target_include_directories(nheko PRIVATE ${kdsingleapplication_SOURCE_DIR} ${kdsingleapplication_BINARY_DIR}) +endif() if(NOT JSON_ImplicitConversions) set_target_properties(nlohmann_json::nlohmann_json PROPERTIES @@ -888,10 +897,11 @@ target_link_libraries(nheko PRIVATE Qt::QmlPrivate Qt::QuickControls2 qt6keychain + KDAB::kdsingleapplication nlohmann_json::nlohmann_json lmdbxx::lmdbxx - liblmdb::lmdb - SingleApplication::SingleApplication) + liblmdb::lmdb) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0") target_precompile_headers(nheko diff --git a/README.md b/README.md index 73f8587d..99561e85 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,7 @@ KDE has similar plugins, that can extend the supported image types even more. - [libnice](https://gitlab.freedesktop.org/libnice/libnice) - XCB, XCB-EWMH: For screensharing support on X11 and setting window roles. Can be disabled with `-DSCREENSHARE_X11=OFF`. - [qtkeychain](https://github.com/frankosterfeld/qtkeychain) (You need at least version 0.12 for proper Gnome Keychain support. The bundled version requires libsecret, unless you pass `-DLIBSECRET_SUPPORT=OFF`.) +- [KDSingleApplication](https://github.com/KDAB/KDSingleApplication) (1.0 or greater with Qt6 support) - A compiler that supports C++ 20: - Clang 16 (Only clazy 16 is tested in CI) - GCC 11 (tested on Gitlab CI) @@ -276,6 +277,7 @@ The bundle flags are currently: - USE_BUNDLED_COEURL - USE_BUNDLED_LIBCURL - USE_BUNDLED_LIBEVENT +- USE_BUNDLED_KDSINGLEAPPLICATION A note on bundled OpenSSL: You need to explicitly enable it and it will not be using your system certificate directory by default, if you enable it. You need to override that at runtime with the SSL_CERT_FILE variable. On Windows it will still be using your system certificates though, since it loads them from the system store instead of the OpenSSL directory. @@ -442,7 +444,6 @@ Here are some screen shots to get a feel for the UI, but things will probably ch ### Third party -- [Single Application for Qt](https://github.com/itay-grudev/SingleApplication) - [Fluent Icons](https://github.com/microsoft/fluentui-system-icons) [Matrix]:https://matrix.org diff --git a/appveyor.yml b/appveyor.yml index 5e59117a..084e7179 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -45,7 +45,7 @@ build_script: # Build nheko - cmake -G "Visual Studio 17 2022" -A x64 -H. -Bbuild -DHUNTER_ROOT="C:\hunter" - -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF -DUSE_BUNDLED_OPENSSL=ON + -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF -DUSE_BUNDLED_OPENSSL=ON -DUSE_BUNDLED_KDSINGLEAPPLICATION=ON -DCMAKE_BUILD_TYPE=Release -DHUNTER_CONFIGURATION_TYPES=Release - cmake --build build --config Release diff --git a/im.nheko.Nheko.yaml b/im.nheko.Nheko.yaml index 979c6d2e..2b315692 100644 --- a/im.nheko.Nheko.yaml +++ b/im.nheko.Nheko.yaml @@ -16,8 +16,6 @@ finish-args: - --talk-name=org.freedesktop.secrets - --talk-name=org.freedesktop.StatusNotifierItem - --talk-name=org.kde.* - # needed for SingleApplication to work - - --allow=per-app-dev-shm cleanup: - /include - /lib/pkgconfig @@ -159,6 +157,15 @@ modules: - sha256: d69f9deb6a75e2580465c6c4c5111b89c4dc2fa94e3a85fcd2ffcd9a143d9273 type: archive url: https://github.com/nlohmann/json/archive/v3.11.2.tar.gz + - config-opts: + - -DKDSingleApplication_EXAMPLES=OFF + - -DKDSingleApplication_QT6=ON + buildsystem: cmake + name: kdsingleapplication + sources: + - sha256: c92355dc10f3ebd39363458458fb5bdd9662e080cf77d91f0437763c4d936520 + type: archive + url: https://github.com/KDAB/KDSingleApplication/releases/download/v1.0.0/kdsingleapplication-1.0.0.tar.gz - buildsystem: simple build-commands: - make static diff --git a/src/main.cpp b/src/main.cpp index 36326b13..e740b27a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,6 +20,8 @@ #include #include +#include + #include "Cache.h" #include "ChatPage.h" #include "Logging.h" @@ -27,7 +29,6 @@ #include "MatrixClient.h" #include "Utils.h" #include "config/nheko.h" -#include "singleapplication.h" #if defined(Q_OS_MAC) #include "emoji/MacHelper.h" @@ -196,14 +197,11 @@ main(int argc, char *argv[]) } } - SingleApplication app(argc, - argv, - true, - SingleApplication::Mode::User | SingleApplication::Mode::ExcludeAppPath | - SingleApplication::Mode::ExcludeAppVersion | - SingleApplication::Mode::SecondaryNotification, - 100, - userdata == QLatin1String("default") ? QLatin1String("") : userdata); + QApplication app(argc, argv); + + KDSingleApplication singleapp( + QStringLiteral("im.nheko.nheko-%1") + .arg(userdata == QLatin1String("default") ? QLatin1String("") : userdata)); QCommandLineParser parser; parser.addHelpOption(); @@ -249,11 +247,19 @@ main(int argc, char *argv[]) // This check needs to happen _after_ process(), so that we actually print help for --help when // Nheko is already running. - if (app.isSecondary()) { - std::cout << "Sending Matrix URL to main application: " << matrixUri.toStdString() - << std::endl; + if (!singleapp.isPrimaryInstance()) { + std::cout << "Activating main app (instead of opening it a second time)." << std::endl; // open uri in main instance - app.sendMessage(matrixUri.toUtf8()); + // TODO(Nico): Send also an activation token. + singleapp.sendMessage("activate"); + + if (!matrixUri.isEmpty()) { + std::cout << "Sending Matrix URL to main application: " << matrixUri.toStdString() + << std::endl; + // open uri in main instance + singleapp.sendMessage(matrixUri.toUtf8()); + } + return 0; } @@ -384,27 +390,28 @@ main(int argc, char *argv[]) nhlog::net()->debug("bye"); } }); - QObject::connect(&app, &SingleApplication::instanceStarted, &w, [&w]() { - w.show(); - w.raise(); - w.requestActivate(); - }); // It seems like handling the message in a blocking manner is a no-go. I have no idea how to // fix that, so just use a queued connection for now... (ASAN does not cooperate and just // hides the crash D:) QObject::connect( - &app, - &SingleApplication::receivedMessage, + &singleapp, + &KDSingleApplication::messageReceived, ChatPage::instance(), - [&](quint32, QByteArray message) { - QString m = QString::fromUtf8(message); - ChatPage::instance()->handleMatrixUri(m); + [&](QByteArray message) { + if (message.isEmpty() || message.startsWith("activate")) { + w.show(); + w.raise(); + w.requestActivate(); + } else { + QString m = QString::fromUtf8(message); + ChatPage::instance()->handleMatrixUri(m); + } }, Qt::QueuedConnection); QMetaObject::Connection uriConnection; - if (app.isPrimary() && !matrixUri.isEmpty()) { + if (singleapp.isPrimaryInstance() && !matrixUri.isEmpty()) { uriConnection = QObject::connect(ChatPage::instance(), &ChatPage::contentLoaded, ChatPage::instance(), diff --git a/third_party/SingleApplication-3.3.2/.github/FUNDING.yml b/third_party/SingleApplication-3.3.2/.github/FUNDING.yml deleted file mode 100644 index 3ca4d97a..00000000 --- a/third_party/SingleApplication-3.3.2/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -github: itay-grudev diff --git a/third_party/SingleApplication-3.3.2/.github/workflows/build.yml b/third_party/SingleApplication-3.3.2/.github/workflows/build.yml deleted file mode 100644 index ffc37f41..00000000 --- a/third_party/SingleApplication-3.3.2/.github/workflows/build.yml +++ /dev/null @@ -1,87 +0,0 @@ -name: "CI: Build Test" - -on: - push: - branches-ignore: - - "releases/**" - paths-ignore: - - "**.md" - -jobs: - build: - strategy: - matrix: - qt_version: [5.12.6, 5.13.2, 5.14.0, 5.15.0, 6.0.0] - platform: [ubuntu-20.04, windows-latest, macos-latest] - include: - - qt_version: 6.0.0 - additional_arguments: -D QT_DEFAULT_MAJOR_VERSION=6 - - platform: ubuntu-20.04 - make: make - CXXFLAGS: -Wall -Wextra -pedantic -Werror - MAKEFLAGS: -j2 - - platform: macos-latest - make: make - CXXFLAGS: -Wall -Wextra -pedantic -Werror - MAKEFLAGS: -j3 - - platform: windows-latest - make: nmake - CXXFLAGS: /W4 /WX /MP - - runs-on: ${{ matrix.platform }} - env: - CXXFLAGS: ${{ matrix.CXXFLAGS }} - MAKEFLAGS: ${{ matrix.MAKEFLAGS }} - - steps: - - name: Clone repo - uses: actions/checkout@v2.3.4 - - - name: Install Qt - uses: jurplel/install-qt-action@v2.14.0 - with: - version: ${{ matrix.qt_version }} - - - name: Build library with CMake - run: | - cmake . ${{ matrix.additional_arguments }} - cmake --build . - - - name: Build basic example with CMake - working-directory: examples/basic/ - run: | - cmake . ${{ matrix.additional_arguments }} - cmake --build . - - - name: Build calculator example CMake - working-directory: examples/calculator/ - run: | - cmake . ${{ matrix.additional_arguments }} - cmake --build . - - - name: Build sending_arguments example with CMake - working-directory: examples/sending_arguments/ - run: | - cmake . ${{ matrix.additional_arguments }} - cmake --build . - - - name: Setup MSVC environment for QMake - uses: ilammy/msvc-dev-cmd@v1 - - - name: Build basic example with QMake - working-directory: examples/basic/ - run: | - qmake - ${{ matrix.make }} - - - name: Build calculator example QMake - working-directory: examples/calculator/ - run: | - qmake - ${{ matrix.make }} - - - name: Build sending_arguments example with QMake - working-directory: examples/sending_arguments/ - run: | - qmake - ${{ matrix.make }} diff --git a/third_party/SingleApplication-3.3.2/.gitignore b/third_party/SingleApplication-3.3.2/.gitignore deleted file mode 100644 index 35533fe8..00000000 --- a/third_party/SingleApplication-3.3.2/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -/examples/*/*.o -/examples/*/Makefile -/examples/*/moc_*.cpp -/examples/*/moc_predefs.h -/examples/*/*.qmake.stash -/examples/basic/basic -/examples/calculator/calculator -/examples/sending_arguments/sending_arguments -/**/CMakeLists.txt.user -/**/CMakeCache.txt -/**/CMakeCache/* -/**/CMakeFiles/* -/**/Makefile -/**/cmake_install.cmake -/**/*_autogen/ -libSingleApplication.a diff --git a/third_party/SingleApplication-3.3.2/CHANGELOG.md b/third_party/SingleApplication-3.3.2/CHANGELOG.md deleted file mode 100644 index 348ca26d..00000000 --- a/third_party/SingleApplication-3.3.2/CHANGELOG.md +++ /dev/null @@ -1,310 +0,0 @@ -Changelog -========= - -If by accident I have forgotten to credit someone in the CHANGELOG, email me and I will fix it. - -__3.3.2__ ---------- - -* Fixed crash caused by sending a `writeAck` on a removed connection. - _Nicolas Werner_ - -__3.3.1__ ---------- - -* Added support for _AppImage_ dynamic executable paths. - _Michael Klein_ - -__3.3.0__ ---------- - -* Fixed message fragmentation issue causing crashes and incorrectly / inconsistently received messages. - _Nils Jeisecke_ - -__3.2.0__ ---------- - -* Added support for Qt 6 - _Jonas Kvinge_ -* Fixed warning in `Qt 5.9` with `min`/`max` functions on Windows - _Nick Korotysh_ -* Fix return value of connectToPrimary() when connect is successful - _Jonas Kvinge_ -* Fix build issue with MinGW GCC pedantic mode - _Iakov Kirilenko_ -* Fixed conversion from `int` to `quint32` and Clang Tidy warnings - _Hennadii Chernyshchyk_ - -__3.1.5__ ---------- - -* Improved library stability in edge cases and very rapid process initialisation -* Fixed Bug where the shared memory block may have been modified without a lock -* Fixed Bug causing `instanceStarted()` to not get emitted when a second instance - has been started before the primary has initiated it's `QLocalServer`. - -__3.1.4__ ---------- -* Officially supporting and build-testing against Qt 5.15 -* Fixed an MSVC C4996 warning that suggests using `strncpy_s`. - - _Hennadii Chernyshchyk_ - -__3.1.3.1__ ---------- -* CMake build system improvements -* Fixed Clang Tidy warnings - - _Hennadii Chernyshchyk_ - -__3.1.3__ ---------- -* Improved `CMakeLists.txt` - - _Hennadii Chernyshchyk_ - -__3.1.2__ ---------- - -* Fix a crash when exiting an application on Android and iOS - - _Emeric Grange_ - -__3.1.1a__ ----------- - -* Added currentUser() method that returns the user the current instance is running as. - - _Leander Schulten_ - -__3.1.0a__ ----------- - -* Added primaryUser() method that returns the user the primary instance is running as. - -__3.0.19__ ----------- - -* Fixed code warning for depricated functions in Qt 5.10 related to `QTime` and `qrand()`. - - _Hennadii Chernyshchyk_ - _Anton Filimonov_ - _Jonas Kvinge_ - -__3.0.18__ ----------- - -* Fallback to standard QApplication class on iOS and Android systems where - the library is not supported. - -* Added Build CI tests to verify the library builds successfully on Linux, Windows and MacOS across multiple Qt versions. - - _Anton Filimonov_ - -__3.0.17__ ----------- - -* Fixed compilation warning/error caused by `geteuid()` on unix based systems. - - _Iakov Kirilenko_ - -* Added CMake support - - _Hennadii Chernyshchyk_ - -__3.0.16__ ----------- - -* Use geteuid and getpwuid to get username on Unix, fallback to environment variable. - - _Jonas Kvinge_ - -__3.0.15__ ----------- - -* Bug Fix: sendMessage() might return false even though data was actually written. - - _Jonas Kvinge_ - -__3.0.14__ ----------- - -* Fixed uninitialised variables in the `SingleApplicationPrivate` constructor. - -__3.0.13a__ ----------- - -* Process socket events asynchronously -* Fix undefined variable error on Windows - - _Francis Giraldeau_ - -__3.0.12a__ ----------- - -* Removed signal handling. - -__3.0.11a__ ----------- - -* Fixed bug where the message sent by the second process was not received - correctly when the message is sent immediately following a connection. - - _Francis Giraldeau_ - -* Refactored code and implemented shared memory block consistency checks - via `qChecksum()` (CRC-16). -* Explicit `qWarning` and `qCritical` when the library is unable to initialise - correctly. - -__3.0.10__ ----------- - -* Removed C style casts and eliminated all clang warnings. Fixed `instanceId` - reading from only one byte in the message deserialization. Cleaned up - serialization code using `QDataStream`. Changed connection type to use - `quint8 enum` rather than `char`. -* Renamed `SingleAppConnectionType` to `ConnectionType`. Added initialization - values to all `ConnectionType` enum cases. - - _Jedidiah Buck McCready_ - -__3.0.9__ ---------- - -* Added SingleApplicationPrivate::primaryPid() as a solution to allow - bringing the primary window of an application to the foreground on - Windows. - - _Eelco van Dam from Peacs BV_ - -__3.0.8__ ---------- - -* Bug fix - changed QApplication::instance() to QCoreApplication::instance() - - _Evgeniy Bazhenov_ - -__3.0.7a__ ----------- - -* Fixed compilation error with Mingw32 in MXE thanks to Vitaly Tonkacheyev. -* Removed QMutex used for thread safe behaviour. The implementation now uses - QCoreApplication::instance() to get an instance to SingleApplication for - memory deallocation. - -__3.0.6a__ ----------- - -* Reverted GetUserName API usage on Windows. Fixed bug with missing library. -* Fixed bug in the Calculator example, preventing it's window to be raised - on Windows. - - Special thanks to Charles Gunawan. - -__3.0.5a__ ----------- - -* Fixed a memory leak in the SingleApplicationPrivate destructor. - - _Sergei Moiseev_ - -__3.0.4a__ ----------- - -* Fixed shadow and uninitialised variable warnings. - - _Paul Walmsley_ - -__3.0.3a__ ----------- - -* Removed Microsoft Windows specific code for getting username due to - multiple problems and compiler differences on Windows platforms. On - Windows the shared memory block in User mode now includes the user's - home path (which contains the user's username). - -* Explicitly getting absolute path of the user's home directory as on Unix - a relative path (`~`) may be returned. - -__3.0.2a__ ----------- - -* Fixed bug on Windows when username containing wide characters causes the - library to crash. - - _Le Liu_ - -__3.0.1a__ ----------- - -* Allows the application path and version to be excluded from the server name - hash. The following flags were added for this purpose: - * `SingleApplication::Mode::ExcludeAppVersion` - * `SingleApplication::Mode::ExcludeAppPath` -* Allow a non elevated process to connect to a local server created by an - elevated process run by the same user on Windows -* Fixes a problem with upper case letters in paths on Windows - - _Le Liu_ - -__v3.0a__ ---------- - -* Deprecated secondary instances count. -* Added a sendMessage() method to send a message to the primary instance. -* Added a receivedMessage() signal, emitted when a message is received from a - secondary instance. -* The SingleApplication constructor's third parameter is now a bool - specifying if the current instance should be allowed to run as a secondary - instance if there is already a primary instance. -* The SingleApplication constructor accept a fourth parameter specifying if - the SingleApplication block should be User-wide or System-wide. -* SingleApplication no longer relies on `applicationName` and - `organizationName` to be set. It instead concatenates all of the following - data and computes a `SHA256` hash which is used as the key of the - `QSharedMemory` block and the `QLocalServer`. Since at least - `applicationFilePath` is always present there is no need to explicitly set - any of the following prior to initialising `SingleApplication`. - * `QCoreApplication::applicationName` - * `QCoreApplication::applicationVersion` - * `QCoreApplication::applicationFilePath` - * `QCoreApplication::organizationName` - * `QCoreApplication::organizationDomain` - * User name or home directory path if in User mode -* The primary instance is no longer notified when a secondary instance had - been started by default. A `Mode` flag for this feature exists. -* Added `instanceNumber()` which represents a unique identifier for each - secondary instance started. When called from the primary instance will - return `0`. - -__v2.4__ --------- - -* Stability improvements -* Support for secondary instances. -* The library now recovers safely after the primary process has crashed -and the shared memory had not been deleted. - -__v2.3__ --------- - -* Improved pimpl design and inheritance safety. - - _Vladislav Pyatnichenko_ - -__v2.2__ --------- - -* The `QAPPLICATION_CLASS` macro can now be defined in the file including the -Single Application header or with a `DEFINES+=` statement in the project file. - -__v2.1__ --------- - -* A race condition can no longer occur when starting two processes nearly - simultaneously. - - Fix issue [#3](https://github.com/itay-grudev/SingleApplication/issues/3) - -__v2.0__ --------- - -* SingleApplication is now being passed a reference to `argc` instead of a - copy. - - Fix issue [#1](https://github.com/itay-grudev/SingleApplication/issues/1) - -* Improved documentation. diff --git a/third_party/SingleApplication-3.3.2/CMakeLists.txt b/third_party/SingleApplication-3.3.2/CMakeLists.txt deleted file mode 100644 index 0dc8d3e1..00000000 --- a/third_party/SingleApplication-3.3.2/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -cmake_minimum_required(VERSION 3.7.0) - -project(SingleApplication LANGUAGES CXX) - -add_library(${PROJECT_NAME} STATIC - singleapplication.cpp - singleapplication_p.cpp -) -add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) -set_target_properties(${PROJECT_NAME} PROPERTIES AUTOMOC ON) - -if(NOT QT_DEFAULT_MAJOR_VERSION) - set(QT_DEFAULT_MAJOR_VERSION 5 CACHE STRING "Qt version to use (5 or 6), defaults to 5") -endif() - -# Find dependencies -set(QT_COMPONENTS Core Network) -set(QT_LIBRARIES Qt${QT_DEFAULT_MAJOR_VERSION}::Core Qt${QT_DEFAULT_MAJOR_VERSION}::Network) - -if(QAPPLICATION_CLASS STREQUAL QApplication) - list(APPEND QT_COMPONENTS Widgets) - list(APPEND QT_LIBRARIES Qt${QT_DEFAULT_MAJOR_VERSION}::Widgets) -elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication) - list(APPEND QT_COMPONENTS Gui) - list(APPEND QT_LIBRARIES Qt${QT_DEFAULT_MAJOR_VERSION}::Gui) -else() - set(QAPPLICATION_CLASS QCoreApplication) -endif() - -find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS ${QT_COMPONENTS} REQUIRED) - -target_link_libraries(${PROJECT_NAME} PUBLIC ${QT_LIBRARIES}) - -if(WIN32) - target_link_libraries(${PROJECT_NAME} PRIVATE advapi32) -endif() - -target_compile_definitions(${PROJECT_NAME} PUBLIC QAPPLICATION_CLASS=${QAPPLICATION_CLASS}) -target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/third_party/SingleApplication-3.3.2/LICENSE b/third_party/SingleApplication-3.3.2/LICENSE deleted file mode 100644 index a82e5a68..00000000 --- a/third_party/SingleApplication-3.3.2/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Itay Grudev 2015 - 2020 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -Note: Some of the examples include code not distributed under the terms of the -MIT License. diff --git a/third_party/SingleApplication-3.3.2/README.md b/third_party/SingleApplication-3.3.2/README.md deleted file mode 100644 index a76bada3..00000000 --- a/third_party/SingleApplication-3.3.2/README.md +++ /dev/null @@ -1,305 +0,0 @@ -SingleApplication -================= -[![CI](https://github.com/itay-grudev/SingleApplication/workflows/CI:%20Build%20Test/badge.svg)](https://github.com/itay-grudev/SingleApplication/actions) - -This is a replacement of the QtSingleApplication for `Qt5` and `Qt6`. - -Keeps the Primary Instance of your Application and kills each subsequent -instances. It can (if enabled) spawn secondary (non-related to the primary) -instances and can send data to the primary instance from secondary instances. - -Usage ------ - -The `SingleApplication` class inherits from whatever `Q[Core|Gui]Application` -class you specify via the `QAPPLICATION_CLASS` macro (`QCoreApplication` is the -default). Further usage is similar to the use of the `Q[Core|Gui]Application` -classes. - -You can use the library as if you use any other `QCoreApplication` derived -class: - -```cpp -#include -#include - -int main( int argc, char* argv[] ) -{ - SingleApplication app( argc, argv ); - - return app.exec(); -} -``` - -To include the library files I would recommend that you add it as a git -submodule to your project. Here is how: - -```bash -git submodule add git@github.com:itay-grudev/SingleApplication.git singleapplication -``` - -**Qmake:** - -Then include the `singleapplication.pri` file in your `.pro` project file. - -```qmake -include(singleapplication/singleapplication.pri) -DEFINES += QAPPLICATION_CLASS=QApplication -``` - -**CMake:** - -Then include the subdirectory in your `CMakeLists.txt` project file. - -```cmake -set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication") -add_subdirectory(src/third-party/singleapplication) -target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication) -``` - - -The library sets up a `QLocalServer` and a `QSharedMemory` block. The first -instance of your Application is your Primary Instance. It would check if the -shared memory block exists and if not it will start a `QLocalServer` and listen -for connections. Each subsequent instance of your application would check if the -shared memory block exists and if it does, it will connect to the QLocalServer -to notify the primary instance that a new instance had been started, after which -it would terminate with status code `0`. In the Primary Instance -`SingleApplication` would emit the `instanceStarted()` signal upon detecting -that a new instance had been started. - -The library uses `stdlib` to terminate the program with the `exit()` function. - -Also don't forget to specify which `QCoreApplication` class your app is using if it -is not `QCoreApplication` as in examples above. - -The `Instance Started` signal ------------------------------ - -The SingleApplication class implements a `instanceStarted()` signal. You can -bind to that signal to raise your application's window when a new instance had -been started, for example. - -```cpp -// window is a QWindow instance -QObject::connect( - &app, - &SingleApplication::instanceStarted, - &window, - &QWindow::raise -); -``` - -Using `SingleApplication::instance()` is a neat way to get the -`SingleApplication` instance for binding to it's signals anywhere in your -program. - -__Note:__ On Windows the ability to bring the application windows to the -foreground is restricted. See [Windows specific implementations](Windows.md) -for a workaround and an example implementation. - - -Secondary Instances -------------------- - -If you want to be able to launch additional Secondary Instances (not related to -your Primary Instance) you have to enable that with the third parameter of the -`SingleApplication` constructor. The default is `false` meaning no Secondary -Instances. Here is an example of how you would start a Secondary Instance send -a message with the command line arguments to the primary instance and then shut -down. - -```cpp -int main(int argc, char *argv[]) -{ - SingleApplication app( argc, argv, true ); - - if( app.isSecondary() ) { - app.sendMessage( app.arguments().join(' ')).toUtf8() ); - app.exit( 0 ); - } - - return app.exec(); -} -``` - -*__Note:__ A secondary instance won't cause the emission of the -`instanceStarted()` signal by default. See `SingleApplication::Mode` for more -details.* - -You can check whether your instance is a primary or secondary with the following -methods: - -```cpp -app.isPrimary(); -// or -app.isSecondary(); -``` - -*__Note:__ If your Primary Instance is terminated a newly launched instance -will replace the Primary one even if the Secondary flag has been set.* - -Examples --------- - -There are three examples provided in this repository: - -* Basic example that prevents a secondary instance from starting [`examples/basic`](https://github.com/itay-grudev/SingleApplication/tree/master/examples/basic) -* An example of a graphical application raising it's parent window [`examples/calculator`](https://github.com/itay-grudev/SingleApplication/tree/master/examples/calculator) -* A console application sending the primary instance it's command line parameters [`examples/sending_arguments`](https://github.com/itay-grudev/SingleApplication/tree/master/examples/sending_arguments) - -API ---- - -### Members - -```cpp -SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100, QString userData = QString() ) -``` - -Depending on whether `allowSecondary` is set, this constructor may terminate -your app if there is already a primary instance running. Additional `Options` -can be specified to set whether the SingleApplication block should work -user-wide or system-wide. Additionally the `Mode::SecondaryNotification` may be -used to notify the primary instance whenever a secondary instance had been -started (disabled by default). `timeout` specifies the maximum time in -milliseconds to wait for blocking operations. Setting `userData` provides additional data that will isolate this instance from other instances that do not have the same (or any) user data set. - -*__Note:__ `argc` and `argv` may be changed as Qt removes arguments that it -recognizes.* - -*__Note:__ `Mode::SecondaryNotification` only works if set on both the primary -and the secondary instance.* - -*__Note:__ Operating system can restrict the shared memory blocks to the same -user, in which case the User/System modes will have no effect and the block will -be user wide.* - ---- - -```cpp -bool SingleApplication::sendMessage( QByteArray message, int timeout = 100 ) -``` - -Sends `message` to the Primary Instance. Uses `timeout` as a the maximum timeout -in milliseconds for blocking functions. Returns `true` if the message has been sent -successfully. If the message can't be sent or the function timeouts - returns `false`. - ---- - -```cpp -bool SingleApplication::isPrimary() -``` - -Returns if the instance is the primary instance. - ---- - -```cpp -bool SingleApplication::isSecondary() -``` -Returns if the instance is a secondary instance. - ---- - -```cpp -quint32 SingleApplication::instanceId() -``` - -Returns a unique identifier for the current instance. - ---- - -```cpp -qint64 SingleApplication::primaryPid() -``` - -Returns the process ID (PID) of the primary instance. - ---- - -```cpp -QString SingleApplication::primaryUser() -``` - -Returns the username the primary instance is running as. - ---- - -```cpp -QString SingleApplication::currentUser() -``` - -Returns the username the current instance is running as. - -### Signals - -```cpp -void SingleApplication::instanceStarted() -``` - -Triggered whenever a new instance had been started, except for secondary -instances if the `Mode::SecondaryNotification` flag is not specified. - ---- - -```cpp -void SingleApplication::receivedMessage( quint32 instanceId, QByteArray message ) -``` - -Triggered whenever there is a message received from a secondary instance. - ---- - -### Flags - -```cpp -enum SingleApplication::Mode -``` - -* `Mode::User` - The SingleApplication block should apply user wide. This adds - user specific data to the key used for the shared memory and server name. - This is the default functionality. -* `Mode::System` – The SingleApplication block applies system-wide. -* `Mode::SecondaryNotification` – Whether to trigger `instanceStarted()` even - whenever secondary instances are started. -* `Mode::ExcludeAppPath` – Excludes the application path from the server name - (and memory block) hash. -* `Mode::ExcludeAppVersion` – Excludes the application version from the server - name (and memory block) hash. - -*__Note:__ `Mode::SecondaryNotification` only works if set on both the primary -and the secondary instance.* - -*__Note:__ Operating system can restrict the shared memory blocks to the same -user, in which case the User/System modes will have no effect and the block will -be user wide.* - ---- - -Versioning ----------- - -Each major version introduces either very significant changes or is not -backwards compatible with the previous version. Minor versions only add -additional features, bug fixes or performance improvements and are backwards -compatible with the previous release. See [`CHANGELOG.md`](CHANGELOG.md) for -more details. - -Implementation --------------- - -The library is implemented with a QSharedMemory block which is thread safe and -guarantees a race condition will not occur. It also uses a QLocalSocket to -notify the main process that a new instance had been spawned and thus invoke the -`instanceStarted()` signal and for messaging the primary instance. - -Additionally the library can recover from being forcefully killed on *nix -systems and will reset the memory block given that there are no other -instances running. - -License -------- -This library and it's supporting documentation are released under -`The MIT License (MIT)` with the exception of the Qt calculator examples which -is distributed under the BSD license. diff --git a/third_party/SingleApplication-3.3.2/SingleApplication b/third_party/SingleApplication-3.3.2/SingleApplication deleted file mode 100644 index 8ead1a42..00000000 --- a/third_party/SingleApplication-3.3.2/SingleApplication +++ /dev/null @@ -1 +0,0 @@ -#include "singleapplication.h" diff --git a/third_party/SingleApplication-3.3.2/Windows.md b/third_party/SingleApplication-3.3.2/Windows.md deleted file mode 100644 index 13c52da0..00000000 --- a/third_party/SingleApplication-3.3.2/Windows.md +++ /dev/null @@ -1,46 +0,0 @@ -Windows Specific Implementations -================================ - -Setting the foreground window ------------------------------ - -In the `instanceStarted()` example in the `README` we demonstrated how an -application can bring it's primary instance window whenever a second copy -of the application is started. - -On Windows the ability to bring the application windows to the foreground is -restricted, see [`AllowSetForegroundWindow()`][AllowSetForegroundWindow] for more -details. - -The background process (the primary instance) can bring its windows to the -foreground if it is allowed by the current foreground process (the secondary -instance). To bypass this `SingleApplication` must be initialized with the -`allowSecondary` parameter set to `true` and the `options` parameter must -include `Mode::SecondaryNotification`, See `SingleApplication::Mode` for more -details. - -Here is an example: - -```cpp -if( app.isSecondary() ) { - // This API requires LIBS += User32.lib to be added to the project - AllowSetForegroundWindow( DWORD( app.primaryPid() ) ); -} - -if( app.isPrimary() ) { - QObject::connect( - &app, - &SingleApplication::instanceStarted, - this, - &App::instanceStarted - ); -} -``` - -```cpp -void App::instanceStarted() { - QApplication::setActiveWindow( [window/widget to set to the foreground] ); -} -``` - -[AllowSetForegroundWindow]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms632668.aspx diff --git a/third_party/SingleApplication-3.3.2/examples/basic/CMakeLists.txt b/third_party/SingleApplication-3.3.2/examples/basic/CMakeLists.txt deleted file mode 100644 index c1429230..00000000 --- a/third_party/SingleApplication-3.3.2/examples/basic/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -cmake_minimum_required(VERSION 3.7.0) - -project(basic LANGUAGES CXX) - -# SingleApplication base class -set(QAPPLICATION_CLASS QCoreApplication) -add_subdirectory(../.. SingleApplication) - -add_executable(basic main.cpp) - -target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication) - diff --git a/third_party/SingleApplication-3.3.2/examples/basic/basic.pro b/third_party/SingleApplication-3.3.2/examples/basic/basic.pro deleted file mode 100755 index b7af16cf..00000000 --- a/third_party/SingleApplication-3.3.2/examples/basic/basic.pro +++ /dev/null @@ -1,5 +0,0 @@ -# Single Application implementation -include(../../singleapplication.pri) -DEFINES += QAPPLICATION_CLASS=QCoreApplication - -SOURCES += main.cpp diff --git a/third_party/SingleApplication-3.3.2/examples/basic/main.cpp b/third_party/SingleApplication-3.3.2/examples/basic/main.cpp deleted file mode 100755 index b2092c6d..00000000 --- a/third_party/SingleApplication-3.3.2/examples/basic/main.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include - -int main(int argc, char *argv[]) -{ - SingleApplication app( argc, argv ); - - qWarning() << "Started a new instance"; - - return app.exec(); -} diff --git a/third_party/SingleApplication-3.3.2/examples/calculator/CMakeLists.txt b/third_party/SingleApplication-3.3.2/examples/calculator/CMakeLists.txt deleted file mode 100644 index 82305f04..00000000 --- a/third_party/SingleApplication-3.3.2/examples/calculator/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -cmake_minimum_required(VERSION 3.7.0) - -project(calculator LANGUAGES CXX) - -set(CMAKE_AUTOMOC ON) - -# SingleApplication base class -set(QAPPLICATION_CLASS QApplication) -add_subdirectory(../.. SingleApplication) - -find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS Core REQUIRED) - -add_executable(${PROJECT_NAME} - button.h - calculator.h - button.cpp - calculator.cpp - main.cpp -) - -target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication) diff --git a/third_party/SingleApplication-3.3.2/examples/calculator/button.cpp b/third_party/SingleApplication-3.3.2/examples/calculator/button.cpp deleted file mode 100644 index d6cca0a0..00000000 --- a/third_party/SingleApplication-3.3.2/examples/calculator/button.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "button.h" - -//! [0] -Button::Button(const QString &text, QWidget *parent) - : QToolButton(parent) -{ - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - setText(text); -} -//! [0] - -//! [1] -QSize Button::sizeHint() const -//! [1] //! [2] -{ - QSize size = QToolButton::sizeHint(); - size.rheight() += 20; - size.rwidth() = qMax(size.width(), size.height()); - return size; -} -//! [2] diff --git a/third_party/SingleApplication-3.3.2/examples/calculator/button.h b/third_party/SingleApplication-3.3.2/examples/calculator/button.h deleted file mode 100644 index 2c014c7b..00000000 --- a/third_party/SingleApplication-3.3.2/examples/calculator/button.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BUTTON_H -#define BUTTON_H - -#include - -//! [0] -class Button : public QToolButton -{ - Q_OBJECT - -public: - explicit Button(const QString &text, QWidget *parent = 0); - - QSize sizeHint() const Q_DECL_OVERRIDE; -}; -//! [0] - -#endif diff --git a/third_party/SingleApplication-3.3.2/examples/calculator/calculator.cpp b/third_party/SingleApplication-3.3.2/examples/calculator/calculator.cpp deleted file mode 100644 index 3d34c2a7..00000000 --- a/third_party/SingleApplication-3.3.2/examples/calculator/calculator.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include - -#include "button.h" -#include "calculator.h" - -//! [0] -Calculator::Calculator(QWidget *parent) - : QWidget(parent) -{ - sumInMemory = 0.0; - sumSoFar = 0.0; - factorSoFar = 0.0; - waitingForOperand = true; -//! [0] - -//! [1] - display = new QLineEdit("0"); -//! [1] //! [2] - display->setReadOnly(true); - display->setAlignment(Qt::AlignRight); - display->setMaxLength(15); - - QFont font = display->font(); - font.setPointSize(font.pointSize() + 8); - display->setFont(font); -//! [2] - -//! [4] - for (int i = 0; i < NumDigitButtons; ++i) { - digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked())); - } - - Button *pointButton = createButton(".", SLOT(pointClicked())); - Button *changeSignButton = createButton("\302\261", SLOT(changeSignClicked())); - - Button *backspaceButton = createButton("Backspace", SLOT(backspaceClicked())); - Button *clearButton = createButton("Clear", SLOT(clear())); - Button *clearAllButton = createButton("Clear All", SLOT(clearAll())); - - Button *clearMemoryButton = createButton("MC", SLOT(clearMemory())); - Button *readMemoryButton = createButton("MR", SLOT(readMemory())); - Button *setMemoryButton = createButton("MS", SLOT(setMemory())); - Button *addToMemoryButton = createButton("M+", SLOT(addToMemory())); - - Button *divisionButton = createButton("\303\267", SLOT(multiplicativeOperatorClicked())); - Button *timesButton = createButton("\303\227", SLOT(multiplicativeOperatorClicked())); - Button *minusButton = createButton("-", SLOT(additiveOperatorClicked())); - Button *plusButton = createButton("+", SLOT(additiveOperatorClicked())); - - Button *squareRootButton = createButton("Sqrt", SLOT(unaryOperatorClicked())); - Button *powerButton = createButton("x\302\262", SLOT(unaryOperatorClicked())); - Button *reciprocalButton = createButton("1/x", SLOT(unaryOperatorClicked())); - Button *equalButton = createButton("=", SLOT(equalClicked())); -//! [4] - -//! [5] - QGridLayout *mainLayout = new QGridLayout; -//! [5] //! [6] - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - mainLayout->addWidget(display, 0, 0, 1, 6); - mainLayout->addWidget(backspaceButton, 1, 0, 1, 2); - mainLayout->addWidget(clearButton, 1, 2, 1, 2); - mainLayout->addWidget(clearAllButton, 1, 4, 1, 2); - - mainLayout->addWidget(clearMemoryButton, 2, 0); - mainLayout->addWidget(readMemoryButton, 3, 0); - mainLayout->addWidget(setMemoryButton, 4, 0); - mainLayout->addWidget(addToMemoryButton, 5, 0); - - for (int i = 1; i < NumDigitButtons; ++i) { - int row = ((9 - i) / 3) + 2; - int column = ((i - 1) % 3) + 1; - mainLayout->addWidget(digitButtons[i], row, column); - } - - mainLayout->addWidget(digitButtons[0], 5, 1); - mainLayout->addWidget(pointButton, 5, 2); - mainLayout->addWidget(changeSignButton, 5, 3); - - mainLayout->addWidget(divisionButton, 2, 4); - mainLayout->addWidget(timesButton, 3, 4); - mainLayout->addWidget(minusButton, 4, 4); - mainLayout->addWidget(plusButton, 5, 4); - - mainLayout->addWidget(squareRootButton, 2, 5); - mainLayout->addWidget(powerButton, 3, 5); - mainLayout->addWidget(reciprocalButton, 4, 5); - mainLayout->addWidget(equalButton, 5, 5); - setLayout(mainLayout); - - setWindowTitle("Calculator"); -} -//! [6] - -//! [7] -void Calculator::digitClicked() -{ - Button *clickedButton = qobject_cast