diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-11-20 02:38:58 +0100 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-11-20 02:56:42 +0100 |
commit | 8ea03e41e063314ea712f4b81db80c2a4cd85c2d (patch) | |
tree | 8b4b37014345cd4004d525adb942c8675c8b2730 /third_party | |
parent | Automatically increase database limits when hit (diff) | |
download | nheko-8ea03e41e063314ea712f4b81db80c2a4cd85c2d.tar.xz |
Switch to KDSingleApplication
Diffstat (limited to 'third_party')
29 files changed, 0 insertions, 2801 deletions
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 <QApplication> -#include <SingleApplication.h> - -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 <singleapplication.h> - -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 <QtWidgets> - -#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 <QToolButton> - -//! [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 <QtWidgets> - -#include <cmath> - -#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<Button *>(sender()); - int digitValue = clickedButton->text().toInt(); - if (display->text() == "0" && digitValue == 0.0) - return; - - if (waitingForOperand) { - display->clear(); - waitingForOperand = false; - } - display->setText(display->text() + QString::number(digitValue)); -} -//! [7] - -//! [8] -void Calculator::unaryOperatorClicked() -//! [8] //! [9] -{ - Button *clickedButton = qobject_cast<Button *>(sender()); - QString clickedOperator = clickedButton->text(); - double operand = display->text().toDouble(); - double result = 0.0; - - if (clickedOperator == "Sqrt") { - if (operand < 0.0) { - abortOperation(); - return; - } - result = std::sqrt(operand); - } else if (clickedOperator == "x\302\262") { - result = std::pow(operand, 2.0); - } else if (clickedOperator == "1/x") { - if (operand == 0.0) { - abortOperation(); - return; - } - result = 1.0 / operand; - } - display->setText(QString::number(result)); - waitingForOperand = true; -} -//! [9] - -//! [10] -void Calculator::additiveOperatorClicked() -//! [10] //! [11] -{ - Button *clickedButton = qobject_cast<Button *>(sender()); - QString clickedOperator = clickedButton->text(); - double operand = display->text().toDouble(); - -//! [11] //! [12] - if (!pendingMultiplicativeOperator.isEmpty()) { -//! [12] //! [13] - if (!calculate(operand, pendingMultiplicativeOperator)) { - abortOperation(); - return; - } - display->setText(QString::number(factorSoFar)); - operand = factorSoFar; - factorSoFar = 0.0; - pendingMultiplicativeOperator.clear(); - } - -//! [13] //! [14] - if (!pendingAdditiveOperator.isEmpty()) { -//! [14] //! [15] - if (!calculate(operand, pendingAdditiveOperator)) { - abortOperation(); - return; - } - display->setText(QString::number(sumSoFar)); - } else { - sumSoFar = operand; - } - -//! [15] //! [16] - pendingAdditiveOperator = clickedOperator; -//! [16] //! [17] - waitingForOperand = true; -} -//! [17] - -//! [18] -void Calculator::multiplicativeOperatorClicked() -{ - Button *clickedButton = qobject_cast<Button *>(sender()); - QString clickedOperator = clickedButton->text(); - double operand = display->text().toDouble(); - - if (!pendingMultiplicativeOperator.isEmpty()) { - if (!calculate(operand, pendingMultiplicativeOperator)) { - abortOperation(); - return; - } - display->setText(QString::number(factorSoFar)); - } else { - factorSoFar = operand; - } - - pendingMultiplicativeOperator = clickedOperator; - waitingForOperand = true; -} -//! [18] - -//! [20] -void Calculator::equalClicked() -{ - double operand = display->text().toDouble(); - - if (!pendingMultiplicativeOperator.isEmpty()) { - if (!calculate(operand, pendingMultiplicativeOperator)) { - abortOperation(); - return; - } - operand = factorSoFar; - factorSoFar = 0.0; - pendingMultiplicativeOperator.clear(); - } - if (!pendingAdditiveOperator.isEmpty()) { - if (!calculate(operand, pendingAdditiveOperator)) { - abortOperation(); - return; - } - pendingAdditiveOperator.clear(); - } else { - sumSoFar = operand; - } - - display->setText(QString::number(sumSoFar)); - sumSoFar = 0.0; - waitingForOperand = true; -} -//! [20] - -//! [22] -void Calculator::pointClicked() -{ - if (waitingForOperand) - display->setText("0"); - if (!display->text().contains('.')) - display->setText(display->text() + "."); - waitingForOperand = false; -} -//! [22] - -//! [24] -void Calculator::changeSignClicked() -{ - QString text = display->text(); - double value = text.toDouble(); - - if (value > 0.0) { - text.prepend("-"); - } else if (value < 0.0) { - text.remove(0, 1); - } - display->setText(text); -} -//! [24] - -//! [26] -void Calculator::backspaceClicked() -{ - if (waitingForOperand) - return; - - QString text = display->text(); - text.chop(1); - if (text.isEmpty()) { - text = "0"; - waitingForOperand = true; - } - display->setText(text); -} -//! [26] - -//! [28] -void Calculator::clear() -{ - if (waitingForOperand) - return; - - display->setText("0"); - waitingForOperand = true; -} -//! [28] - -//! [30] -void Calculator::clearAll() -{ - sumSoFar = 0.0; - factorSoFar = 0.0; - pendingAdditiveOperator.clear(); - pendingMultiplicativeOperator.clear(); - display->setText("0"); - waitingForOperand = true; -} -//! [30] - -//! [32] -void Calculator::clearMemory() -{ - sumInMemory = 0.0; -} - -void Calculator::readMemory() -{ - display->setText(QString::number(sumInMemory)); - waitingForOperand = true; -} - -void Calculator::setMemory() -{ - equalClicked(); - sumInMemory = display->text().toDouble(); -} - -void Calculator::addToMemory() -{ - equalClicked(); - sumInMemory += display->text().toDouble(); -} -//! [32] -//! [34] -Button *Calculator::createButton(const QString &text, const char *member) -{ - Button *button = new Button(text); - connect(button, SIGNAL(clicked()), this, member); - return button; -} -//! [34] - -//! [36] -void Calculator::abortOperation() -{ - clearAll(); - display->setText("####"); -} -//! [36] - -//! [38] -bool Calculator::calculate(double rightOperand, const QString &pendingOperator) -{ - if (pendingOperator == "+") { - sumSoFar += rightOperand; - } else if (pendingOperator == "-") { - sumSoFar -= rightOperand; - } else if (pendingOperator == "\303\227") { - factorSoFar *= rightOperand; - } else if (pendingOperator == "\303\267") { - if (rightOperand == 0.0) - return false; - factorSoFar /= rightOperand; - } - return true; -} -//! [38] diff --git a/third_party/SingleApplication-3.3.2/examples/calculator/calculator.h b/third_party/SingleApplication-3.3.2/examples/calculator/calculator.h deleted file mode 100644 index 250a2f3e..00000000 --- a/third_party/SingleApplication-3.3.2/examples/calculator/calculator.h +++ /dev/null @@ -1,117 +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 CALCULATOR_H -#define CALCULATOR_H - -#include <QWidget> - -QT_BEGIN_NAMESPACE -class QLineEdit; -QT_END_NAMESPACE -class Button; - -//! [0] -class Calculator : public QWidget -{ - Q_OBJECT - -public: - Calculator(QWidget *parent = 0); - -private slots: - void digitClicked(); - void unaryOperatorClicked(); - void additiveOperatorClicked(); - void multiplicativeOperatorClicked(); - void equalClicked(); - void pointClicked(); - void changeSignClicked(); - void backspaceClicked(); - void clear(); - void clearAll(); - void clearMemory(); - void readMemory(); - void setMemory(); - void addToMemory(); -//! [0] - -//! [1] -private: -//! [1] //! [2] - Button *createButton(const QString &text, const char *member); - void abortOperation(); - bool calculate(double rightOperand, const QString &pendingOperator); -//! [2] - -//! [3] - double sumInMemory; -//! [3] //! [4] - double sumSoFar; -//! [4] //! [5] - double factorSoFar; -//! [5] //! [6] - QString pendingAdditiveOperator; -//! [6] //! [7] - QString pendingMultiplicativeOperator; -//! [7] //! [8] - bool waitingForOperand; -//! [8] - -//! [9] - QLineEdit *display; -//! [9] //! [10] - - enum { NumDigitButtons = 10 }; - Button *digitButtons[NumDigitButtons]; -}; -//! [10] - -#endif diff --git a/third_party/SingleApplication-3.3.2/examples/calculator/calculator.pro b/third_party/SingleApplication-3.3.2/examples/calculator/calculator.pro deleted file mode 100644 index 8f132609..00000000 --- a/third_party/SingleApplication-3.3.2/examples/calculator/calculator.pro +++ /dev/null @@ -1,11 +0,0 @@ -QT += widgets - -HEADERS = button.h \ - calculator.h -SOURCES = button.cpp \ - calculator.cpp \ - main.cpp - -# Single Application implementation -include(../../singleapplication.pri) -DEFINES += QAPPLICATION_CLASS=QApplication diff --git a/third_party/SingleApplication-3.3.2/examples/calculator/main.cpp b/third_party/SingleApplication-3.3.2/examples/calculator/main.cpp deleted file mode 100644 index d45438f4..00000000 --- a/third_party/SingleApplication-3.3.2/examples/calculator/main.cpp +++ /dev/null @@ -1,71 +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 <QApplication> - -#include <singleapplication.h> - -#include "calculator.h" - -int main(int argc, char *argv[]) -{ - SingleApplication app(argc, argv); - - Calculator calc; - - QObject::connect( &app, &SingleApplication::instanceStarted, [ &calc ]() { - calc.raise(); - calc.activateWindow(); - }); - - calc.show(); - - return app.exec(); -} diff --git a/third_party/SingleApplication-3.3.2/examples/sending_arguments/CMakeLists.txt b/third_party/SingleApplication-3.3.2/examples/sending_arguments/CMakeLists.txt deleted file mode 100644 index 2cc55975..00000000 --- a/third_party/SingleApplication-3.3.2/examples/sending_arguments/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -cmake_minimum_required(VERSION 3.7.0) - -project(sending_arguments LANGUAGES CXX) - -set(CMAKE_AUTOMOC ON) - -# SingleApplication base class -set(QAPPLICATION_CLASS QCoreApplication) -add_subdirectory(../.. SingleApplication) - -find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS Core REQUIRED) - -add_executable(${PROJECT_NAME} - main.cpp - messagereceiver.cpp - messagereceiver.h - main.cpp -) - -target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication) diff --git a/third_party/SingleApplication-3.3.2/examples/sending_arguments/main.cpp b/third_party/SingleApplication-3.3.2/examples/sending_arguments/main.cpp deleted file mode 100755 index a9d34dd9..00000000 --- a/third_party/SingleApplication-3.3.2/examples/sending_arguments/main.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include <singleapplication.h> -#include "messagereceiver.h" - -int main(int argc, char *argv[]) -{ - // Allow secondary instances - SingleApplication app( argc, argv, true ); - - MessageReceiver msgReceiver; - - // If this is a secondary instance - if( app.isSecondary() ) { - app.sendMessage( app.arguments().join(' ').toUtf8() ); - qDebug() << "App already running."; - qDebug() << "Primary instance PID: " << app.primaryPid(); - qDebug() << "Primary instance user: " << app.primaryUser(); - return 0; - } else { - QObject::connect( - &app, - &SingleApplication::receivedMessage, - &msgReceiver, - &MessageReceiver::receivedMessage - ); - } - - return app.exec(); -} diff --git a/third_party/SingleApplication-3.3.2/examples/sending_arguments/messagereceiver.cpp b/third_party/SingleApplication-3.3.2/examples/sending_arguments/messagereceiver.cpp deleted file mode 100644 index 0560b072..00000000 --- a/third_party/SingleApplication-3.3.2/examples/sending_arguments/messagereceiver.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include <QDebug> -#include "messagereceiver.h" - -MessageReceiver::MessageReceiver(QObject *parent) : QObject(parent) -{ -} - -void MessageReceiver::receivedMessage(int instanceId, QByteArray message) -{ - qDebug() << "Received message from instance: " << instanceId; - qDebug() << "Message Text: " << message; -} diff --git a/third_party/SingleApplication-3.3.2/examples/sending_arguments/messagereceiver.h b/third_party/SingleApplication-3.3.2/examples/sending_arguments/messagereceiver.h deleted file mode 100644 index 50a970c8..00000000 --- a/third_party/SingleApplication-3.3.2/examples/sending_arguments/messagereceiver.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef MESSAGERECEIVER_H -#define MESSAGERECEIVER_H - -#include <QObject> - -class MessageReceiver : public QObject -{ - Q_OBJECT -public: - explicit MessageReceiver(QObject *parent = 0); -public slots: - void receivedMessage( int instanceId, QByteArray message ); -}; - -#endif // MESSAGERECEIVER_H diff --git a/third_party/SingleApplication-3.3.2/examples/sending_arguments/sending_arguments.pro b/third_party/SingleApplication-3.3.2/examples/sending_arguments/sending_arguments.pro deleted file mode 100755 index 897636a9..00000000 --- a/third_party/SingleApplication-3.3.2/examples/sending_arguments/sending_arguments.pro +++ /dev/null @@ -1,9 +0,0 @@ -# Single Application implementation -include(../../singleapplication.pri) -DEFINES += QAPPLICATION_CLASS=QCoreApplication - -SOURCES += main.cpp \ - messagereceiver.cpp - -HEADERS += \ - messagereceiver.h diff --git a/third_party/SingleApplication-3.3.2/singleapplication.cpp b/third_party/SingleApplication-3.3.2/singleapplication.cpp deleted file mode 100644 index 09e264ef..00000000 --- a/third_party/SingleApplication-3.3.2/singleapplication.cpp +++ /dev/null @@ -1,271 +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. - -#include <QtCore/QElapsedTimer> -#include <QtCore/QByteArray> -#include <QtCore/QSharedMemory> - -#include "singleapplication.h" -#include "singleapplication_p.h" - -/** - * @brief Constructor. Checks and fires up LocalServer or closes the program - * if another instance already exists - * @param argc - * @param argv - * @param allowSecondary Whether to enable secondary instance support - * @param options Optional flags to toggle specific behaviour - * @param timeout Maximum time blocking functions are allowed during app load - */ -SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout, const QString &userData ) - : app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) ) -{ - Q_D( SingleApplication ); - -#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) - // On Android and iOS since the library is not supported fallback to - // standard QApplication behaviour by simply returning at this point. - qWarning() << "SingleApplication is not supported on Android and iOS systems."; - return; -#endif - - // Store the current mode of the program - d->options = options; - - // Add any unique user data - if ( ! userData.isEmpty() ) - d->addAppData( userData ); - - // Generating an application ID used for identifying the shared memory - // block and QLocalServer - d->genBlockServerName(); - - // To mitigate QSharedMemory issues with large amount of processes - // attempting to attach at the same time - SingleApplicationPrivate::randomSleep(); - -#ifdef Q_OS_UNIX - // By explicitly attaching it and then deleting it we make sure that the - // memory is deleted even after the process has crashed on Unix. - d->memory = new QSharedMemory( d->blockServerName ); - d->memory->attach(); - delete d->memory; -#endif - // Guarantee thread safe behaviour with a shared memory block. - d->memory = new QSharedMemory( d->blockServerName ); - - // Create a shared memory block - if( d->memory->create( sizeof( InstancesInfo ) )){ - // Initialize the shared memory block - if( ! d->memory->lock() ){ - qCritical() << "SingleApplication: Unable to lock memory block after create."; - abortSafely(); - } - d->initializeMemoryBlock(); - } else { - if( d->memory->error() == QSharedMemory::AlreadyExists ){ - // Attempt to attach to the memory segment - if( ! d->memory->attach() ){ - qCritical() << "SingleApplication: Unable to attach to shared memory block."; - abortSafely(); - } - if( ! d->memory->lock() ){ - qCritical() << "SingleApplication: Unable to lock memory block after attach."; - abortSafely(); - } - } else { - qCritical() << "SingleApplication: Unable to create block."; - abortSafely(); - } - } - - auto *inst = static_cast<InstancesInfo*>( d->memory->data() ); - QElapsedTimer time; - time.start(); - - // Make sure the shared memory block is initialised and in consistent state - while( true ){ - // If the shared memory block's checksum is valid continue - if( d->blockChecksum() == inst->checksum ) break; - - // If more than 5s have elapsed, assume the primary instance crashed and - // assume it's position - if( time.elapsed() > 5000 ){ - qWarning() << "SingleApplication: Shared memory block has been in an inconsistent state from more than 5s. Assuming primary instance failure."; - d->initializeMemoryBlock(); - } - - // Otherwise wait for a random period and try again. The random sleep here - // limits the probability of a collision between two racing apps and - // allows the app to initialise faster - if( ! d->memory->unlock() ){ - qDebug() << "SingleApplication: Unable to unlock memory for random wait."; - qDebug() << d->memory->errorString(); - } - SingleApplicationPrivate::randomSleep(); - if( ! d->memory->lock() ){ - qCritical() << "SingleApplication: Unable to lock memory after random wait."; - abortSafely(); - } - } - - if( inst->primary == false ){ - d->startPrimary(); - if( ! d->memory->unlock() ){ - qDebug() << "SingleApplication: Unable to unlock memory after primary start."; - qDebug() << d->memory->errorString(); - } - return; - } - - // Check if another instance can be started - if( allowSecondary ){ - d->startSecondary(); - if( d->options & Mode::SecondaryNotification ){ - d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance ); - } - if( ! d->memory->unlock() ){ - qDebug() << "SingleApplication: Unable to unlock memory after secondary start."; - qDebug() << d->memory->errorString(); - } - return; - } - - if( ! d->memory->unlock() ){ - qDebug() << "SingleApplication: Unable to unlock memory at end of execution."; - qDebug() << d->memory->errorString(); - } - - d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance ); - - delete d; - - ::exit( EXIT_SUCCESS ); -} - -SingleApplication::~SingleApplication() -{ - Q_D( SingleApplication ); - delete d; -} - -/** - * Checks if the current application instance is primary. - * @return Returns true if the instance is primary, false otherwise. - */ -bool SingleApplication::isPrimary() const -{ - Q_D( const SingleApplication ); - return d->server != nullptr; -} - -/** - * Checks if the current application instance is secondary. - * @return Returns true if the instance is secondary, false otherwise. - */ -bool SingleApplication::isSecondary() const -{ - Q_D( const SingleApplication ); - return d->server == nullptr; -} - -/** - * Allows you to identify an instance by returning unique consecutive instance - * ids. It is reset when the first (primary) instance of your app starts and - * only incremented afterwards. - * @return Returns a unique instance id. - */ -quint32 SingleApplication::instanceId() const -{ - Q_D( const SingleApplication ); - return d->instanceNumber; -} - -/** - * Returns the OS PID (Process Identifier) of the process running the primary - * instance. Especially useful when SingleApplication is coupled with OS. - * specific APIs. - * @return Returns the primary instance PID. - */ -qint64 SingleApplication::primaryPid() const -{ - Q_D( const SingleApplication ); - return d->primaryPid(); -} - -/** - * Returns the username the primary instance is running as. - * @return Returns the username the primary instance is running as. - */ -QString SingleApplication::primaryUser() const -{ - Q_D( const SingleApplication ); - return d->primaryUser(); -} - -/** - * Returns the username the current instance is running as. - * @return Returns the username the current instance is running as. - */ -QString SingleApplication::currentUser() const -{ - return SingleApplicationPrivate::getUsername(); -} - -/** - * Sends message to the Primary Instance. - * @param message The message to send. - * @param timeout the maximum timeout in milliseconds for blocking functions. - * @return true if the message was sent successfuly, false otherwise. - */ -bool SingleApplication::sendMessage( const QByteArray &message, int timeout ) -{ - Q_D( SingleApplication ); - - // Nobody to connect to - if( isPrimary() ) return false; - - // Make sure the socket is connected - if( ! d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect ) ) - return false; - - return d->writeConfirmedMessage( timeout, message ); -} - -/** - * Cleans up the shared memory block and exits with a failure. - * This function halts program execution. - */ -void SingleApplication::abortSafely() -{ - Q_D( SingleApplication ); - - qCritical() << "SingleApplication: " << d->memory->error() << d->memory->errorString(); - delete d; - ::exit( EXIT_FAILURE ); -} - -QStringList SingleApplication::userData() const -{ - Q_D( const SingleApplication ); - return d->appData(); -} diff --git a/third_party/SingleApplication-3.3.2/singleapplication.h b/third_party/SingleApplication-3.3.2/singleapplication.h deleted file mode 100644 index 91cabf93..00000000 --- a/third_party/SingleApplication-3.3.2/singleapplication.h +++ /dev/null @@ -1,154 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) Itay Grudev 2015 - 2018 -// -// 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. - -#ifndef SINGLE_APPLICATION_H -#define SINGLE_APPLICATION_H - -#include <QtCore/QtGlobal> -#include <QtNetwork/QLocalSocket> - -#ifndef QAPPLICATION_CLASS - #define QAPPLICATION_CLASS QCoreApplication -#endif - -#include QT_STRINGIFY(QAPPLICATION_CLASS) - -class SingleApplicationPrivate; - -/** - * @brief The SingleApplication class handles multiple instances of the same - * Application - * @see QCoreApplication - */ -class SingleApplication : public QAPPLICATION_CLASS -{ - Q_OBJECT - - using app_t = QAPPLICATION_CLASS; - -public: - /** - * @brief Mode of operation of SingleApplication. - * Whether the block should be user-wide or system-wide and whether the - * primary instance should be notified when a secondary instance had been - * started. - * @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. - * @enum - */ - enum Mode { - User = 1 << 0, - System = 1 << 1, - SecondaryNotification = 1 << 2, - ExcludeAppVersion = 1 << 3, - ExcludeAppPath = 1 << 4 - }; - Q_DECLARE_FLAGS(Options, Mode) - - /** - * @brief Intitializes a SingleApplication instance with argc command line - * arguments in argv - * @arg {int &} argc - Number of arguments in argv - * @arg {const char *[]} argv - Supplied command line arguments - * @arg {bool} allowSecondary - Whether to start the instance as secondary - * if there is already a primary instance. - * @arg {Mode} mode - Whether for the SingleApplication block to be applied - * User wide or System wide. - * @arg {int} timeout - Timeout to wait in milliseconds. - * @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 - * instance and the secondary instance. - * @note The timeout is just a hint for the maximum time of blocking - * operations. It does not guarantee that the SingleApplication - * initialisation will be completed in given time, though is a good hint. - * Usually 4*timeout would be the worst case (fail) scenario. - * @see See the corresponding QAPPLICATION_CLASS constructor for reference - */ - explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000, const QString &userData = {} ); - ~SingleApplication() override; - - /** - * @brief Returns if the instance is the primary instance - * @returns {bool} - */ - bool isPrimary() const; - - /** - * @brief Returns if the instance is a secondary instance - * @returns {bool} - */ - bool isSecondary() const; - - /** - * @brief Returns a unique identifier for the current instance - * @returns {qint32} - */ - quint32 instanceId() const; - - /** - * @brief Returns the process ID (PID) of the primary instance - * @returns {qint64} - */ - qint64 primaryPid() const; - - /** - * @brief Returns the username of the user running the primary instance - * @returns {QString} - */ - QString primaryUser() const; - - /** - * @brief Returns the username of the current user - * @returns {QString} - */ - QString currentUser() const; - - /** - * @brief Sends a message to the primary instance. Returns true on success. - * @param {int} timeout - Timeout for connecting - * @returns {bool} - * @note sendMessage() will return false if invoked from the primary - * instance. - */ - bool sendMessage( const QByteArray &message, int timeout = 100 ); - - /** - * @brief Get the set user data. - * @returns {QStringList} - */ - QStringList userData() const; - -Q_SIGNALS: - void instanceStarted(); - void receivedMessage( quint32 instanceId, QByteArray message ); - -private: - SingleApplicationPrivate *d_ptr; - Q_DECLARE_PRIVATE(SingleApplication) - void abortSafely(); -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options) - -#endif // SINGLE_APPLICATION_H diff --git a/third_party/SingleApplication-3.3.2/singleapplication.pri b/third_party/SingleApplication-3.3.2/singleapplication.pri deleted file mode 100644 index ae81f599..00000000 --- a/third_party/SingleApplication-3.3.2/singleapplication.pri +++ /dev/null @@ -1,20 +0,0 @@ -QT += core network -CONFIG += c++11 - -HEADERS += $$PWD/SingleApplication \ - $$PWD/singleapplication.h \ - $$PWD/singleapplication_p.h -SOURCES += $$PWD/singleapplication.cpp \ - $$PWD/singleapplication_p.cpp - -INCLUDEPATH += $$PWD - -win32 { - msvc:LIBS += Advapi32.lib - gcc:LIBS += -ladvapi32 -} - -DISTFILES += \ - $$PWD/README.md \ - $$PWD/CHANGELOG.md \ - $$PWD/Windows.md diff --git a/third_party/SingleApplication-3.3.2/singleapplication_p.cpp b/third_party/SingleApplication-3.3.2/singleapplication_p.cpp deleted file mode 100644 index 6702b943..00000000 --- a/third_party/SingleApplication-3.3.2/singleapplication_p.cpp +++ /dev/null @@ -1,540 +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. - -// -// W A R N I N G !!! -// ----------------- -// -// This file is not part of the SingleApplication API. It is used purely as an -// implementation detail. This header file may change from version to -// version without notice, or may even be removed. -// - -#include <cstdlib> -#include <cstddef> - -#include <QtCore/QDir> -#include <QtCore/QThread> -#include <QtCore/QByteArray> -#include <QtCore/QDataStream> -#include <QtCore/QElapsedTimer> -#include <QtCore/QCryptographicHash> -#include <QtNetwork/QLocalServer> -#include <QtNetwork/QLocalSocket> - -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) -#include <QtCore/QRandomGenerator> -#else -#include <QtCore/QDateTime> -#endif - -#include "singleapplication.h" -#include "singleapplication_p.h" - -#ifdef Q_OS_UNIX - #include <unistd.h> - #include <sys/types.h> - #include <pwd.h> -#endif - -#ifdef Q_OS_WIN - #ifndef NOMINMAX - #define NOMINMAX 1 - #endif - #include <windows.h> - #include <lmcons.h> -#endif - -SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr ) - : q_ptr( q_ptr ) -{ - server = nullptr; - socket = nullptr; - memory = nullptr; - instanceNumber = 0; -} - -SingleApplicationPrivate::~SingleApplicationPrivate() -{ - if( socket != nullptr ){ - socket->close(); - delete socket; - } - - if( memory != nullptr ){ - memory->lock(); - auto *inst = static_cast<InstancesInfo*>(memory->data()); - if( server != nullptr ){ - server->close(); - delete server; - inst->primary = false; - inst->primaryPid = -1; - inst->primaryUser[0] = '\0'; - inst->checksum = blockChecksum(); - } - memory->unlock(); - - delete memory; - } -} - -QString SingleApplicationPrivate::getUsername() -{ -#ifdef Q_OS_WIN - wchar_t username[UNLEN + 1]; - // Specifies size of the buffer on input - DWORD usernameLength = UNLEN + 1; - if( GetUserNameW( username, &usernameLength ) ) - return QString::fromWCharArray( username ); -#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) - return QString::fromLocal8Bit( qgetenv( "USERNAME" ) ); -#else - return qEnvironmentVariable( "USERNAME" ); -#endif -#endif -#ifdef Q_OS_UNIX - QString username; - uid_t uid = geteuid(); - struct passwd *pw = getpwuid( uid ); - if( pw ) - username = QString::fromLocal8Bit( pw->pw_name ); - if ( username.isEmpty() ){ -#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) - username = QString::fromLocal8Bit( qgetenv( "USER" ) ); -#else - username = qEnvironmentVariable( "USER" ); -#endif - } - return username; -#endif -} - -void SingleApplicationPrivate::genBlockServerName() -{ - QCryptographicHash appData( QCryptographicHash::Sha256 ); - appData.addData( "SingleApplication", 17 ); - appData.addData( SingleApplication::app_t::applicationName().toUtf8() ); - appData.addData( SingleApplication::app_t::organizationName().toUtf8() ); - appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() ); - - if ( ! appDataList.isEmpty() ) - appData.addData( appDataList.join( "" ).toUtf8() ); - - if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ){ - appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() ); - } - - if( ! (options & SingleApplication::Mode::ExcludeAppPath) ){ -#if defined(Q_OS_WIN) - appData.addData( SingleApplication::app_t::applicationFilePath().toLower().toUtf8() ); -#elif defined(Q_OS_LINUX) - // If the application is running as an AppImage then the APPIMAGE env var should be used - // instead of applicationPath() as each instance is launched with its own executable path - const QByteArray appImagePath = qgetenv( "APPIMAGE" ); - if( appImagePath.isEmpty() ){ // Not running as AppImage: use path to executable file - appData.addData( SingleApplication::app_t::applicationFilePath().toUtf8() ); - } else { // Running as AppImage: Use absolute path to AppImage file - appData.addData( appImagePath ); - }; -#else - appData.addData( SingleApplication::app_t::applicationFilePath().toUtf8() ); -#endif - } - - // User level block requires a user specific data in the hash - if( options & SingleApplication::Mode::User ){ - appData.addData( getUsername().toUtf8() ); - } - - // Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with - // server naming requirements. - blockServerName = appData.result().toBase64().replace("/", "_"); -} - -void SingleApplicationPrivate::initializeMemoryBlock() const -{ - auto *inst = static_cast<InstancesInfo*>( memory->data() ); - inst->primary = false; - inst->secondary = 0; - inst->primaryPid = -1; - inst->primaryUser[0] = '\0'; - inst->checksum = blockChecksum(); -} - -void SingleApplicationPrivate::startPrimary() -{ - // Reset the number of connections - auto *inst = static_cast <InstancesInfo*>( memory->data() ); - - inst->primary = true; - inst->primaryPid = QCoreApplication::applicationPid(); - qstrncpy( inst->primaryUser, getUsername().toUtf8().data(), sizeof(inst->primaryUser) ); - inst->checksum = blockChecksum(); - instanceNumber = 0; - // Successful creation means that no main process exists - // So we start a QLocalServer to listen for connections - QLocalServer::removeServer( blockServerName ); - server = new QLocalServer(); - - // Restrict access to the socket according to the - // SingleApplication::Mode::User flag on User level or no restrictions - if( options & SingleApplication::Mode::User ){ - server->setSocketOptions( QLocalServer::UserAccessOption ); - } else { - server->setSocketOptions( QLocalServer::WorldAccessOption ); - } - - server->listen( blockServerName ); - QObject::connect( - server, - &QLocalServer::newConnection, - this, - &SingleApplicationPrivate::slotConnectionEstablished - ); -} - -void SingleApplicationPrivate::startSecondary() -{ - auto *inst = static_cast <InstancesInfo*>( memory->data() ); - - inst->secondary += 1; - inst->checksum = blockChecksum(); - instanceNumber = inst->secondary; -} - -bool SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType ) -{ - QElapsedTimer time; - time.start(); - - // Connect to the Local Server of the Primary Instance if not already - // connected. - if( socket == nullptr ){ - socket = new QLocalSocket(); - } - - if( socket->state() == QLocalSocket::ConnectedState ) return true; - - if( socket->state() != QLocalSocket::ConnectedState ){ - - while( true ){ - randomSleep(); - - if( socket->state() != QLocalSocket::ConnectingState ) - socket->connectToServer( blockServerName ); - - if( socket->state() == QLocalSocket::ConnectingState ){ - socket->waitForConnected( static_cast<int>(msecs - time.elapsed()) ); - } - - // If connected break out of the loop - if( socket->state() == QLocalSocket::ConnectedState ) break; - - // If elapsed time since start is longer than the method timeout return - if( time.elapsed() >= msecs ) return false; - } - } - - // Initialisation message according to the SingleApplication protocol - QByteArray initMsg; - QDataStream writeStream(&initMsg, QIODevice::WriteOnly); - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - writeStream.setVersion(QDataStream::Qt_5_6); -#endif - - writeStream << blockServerName.toLatin1(); - writeStream << static_cast<quint8>(connectionType); - writeStream << instanceNumber; -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - quint16 checksum = qChecksum(QByteArray(initMsg, static_cast<quint32>(initMsg.length()))); -#else - quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length())); -#endif - writeStream << checksum; - - return writeConfirmedMessage( static_cast<int>(msecs - time.elapsed()), initMsg ); -} - -void SingleApplicationPrivate::writeAck( QLocalSocket *sock ) { - sock->putChar('\n'); -} - -bool SingleApplicationPrivate::writeConfirmedMessage (int msecs, const QByteArray &msg) -{ - QElapsedTimer time; - time.start(); - - // Frame 1: The header indicates the message length that follows - QByteArray header; - QDataStream headerStream(&header, QIODevice::WriteOnly); - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - headerStream.setVersion(QDataStream::Qt_5_6); -#endif - headerStream << static_cast <quint64>( msg.length() ); - - if( ! writeConfirmedFrame( static_cast<int>(msecs - time.elapsed()), header )) - return false; - - // Frame 2: The message - return writeConfirmedFrame( static_cast<int>(msecs - time.elapsed()), msg ); -} - -bool SingleApplicationPrivate::writeConfirmedFrame( int msecs, const QByteArray &msg ) -{ - socket->write( msg ); - socket->flush(); - - bool result = socket->waitForReadyRead( msecs ); // await ack byte - if (result) { - socket->read( 1 ); - return true; - } - - return false; -} - -quint16 SingleApplicationPrivate::blockChecksum() const -{ -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - quint16 checksum = qChecksum(QByteArray(static_cast<const char*>(memory->constData()), offsetof(InstancesInfo, checksum))); -#else - quint16 checksum = qChecksum(static_cast<const char*>(memory->constData()), offsetof(InstancesInfo, checksum)); -#endif - return checksum; -} - -qint64 SingleApplicationPrivate::primaryPid() const -{ - qint64 pid; - - memory->lock(); - auto *inst = static_cast<InstancesInfo*>( memory->data() ); - pid = inst->primaryPid; - memory->unlock(); - - return pid; -} - -QString SingleApplicationPrivate::primaryUser() const -{ - QByteArray username; - - memory->lock(); - auto *inst = static_cast<InstancesInfo*>( memory->data() ); - username = inst->primaryUser; - memory->unlock(); - - return QString::fromUtf8( username ); -} - -/** - * @brief Executed when a connection has been made to the LocalServer - */ -void SingleApplicationPrivate::slotConnectionEstablished() -{ - QLocalSocket *nextConnSocket = server->nextPendingConnection(); - connectionMap.insert(nextConnSocket, ConnectionInfo()); - - QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose, this, - [nextConnSocket, this](){ - auto &info = connectionMap[nextConnSocket]; - this->slotClientConnectionClosed( nextConnSocket, info.instanceId ); - } - ); - - QObject::connect(nextConnSocket, &QLocalSocket::disconnected, nextConnSocket, &QLocalSocket::deleteLater); - - QObject::connect(nextConnSocket, &QLocalSocket::destroyed, this, - [nextConnSocket, this](){ - connectionMap.remove(nextConnSocket); - } - ); - - QObject::connect(nextConnSocket, &QLocalSocket::readyRead, this, - [nextConnSocket, this](){ - auto &info = connectionMap[nextConnSocket]; - switch(info.stage){ - case StageInitHeader: - readMessageHeader( nextConnSocket, StageInitBody ); - break; - case StageInitBody: - readInitMessageBody(nextConnSocket); - break; - case StageConnectedHeader: - readMessageHeader( nextConnSocket, StageConnectedBody ); - break; - case StageConnectedBody: - this->slotDataAvailable( nextConnSocket, info.instanceId ); - break; - default: - break; - }; - } - ); -} - -void SingleApplicationPrivate::readMessageHeader( QLocalSocket *sock, SingleApplicationPrivate::ConnectionStage nextStage ) -{ - if (!connectionMap.contains( sock )){ - return; - } - - if( sock->bytesAvailable() < ( qint64 )sizeof( quint64 ) ){ - return; - } - - QDataStream headerStream( sock ); - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - headerStream.setVersion( QDataStream::Qt_5_6 ); -#endif - - // Read the header to know the message length - quint64 msgLen = 0; - headerStream >> msgLen; - ConnectionInfo &info = connectionMap[sock]; - info.stage = nextStage; - info.msgLen = msgLen; - - writeAck( sock ); -} - -bool SingleApplicationPrivate::isFrameComplete( QLocalSocket *sock ) -{ - if (!connectionMap.contains( sock )){ - return false; - } - - ConnectionInfo &info = connectionMap[sock]; - if( sock->bytesAvailable() < ( qint64 )info.msgLen ){ - return false; - } - - return true; -} - -void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock ) -{ - Q_Q(SingleApplication); - - if( !isFrameComplete( sock ) ) - return; - - // Read the message body - QByteArray msgBytes = sock->readAll(); - QDataStream readStream(msgBytes); - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - readStream.setVersion( QDataStream::Qt_5_6 ); -#endif - - // server name - QByteArray latin1Name; - readStream >> latin1Name; - - // connection type - ConnectionType connectionType = InvalidConnection; - quint8 connTypeVal = InvalidConnection; - readStream >> connTypeVal; - connectionType = static_cast <ConnectionType>( connTypeVal ); - - // instance id - quint32 instanceId = 0; - readStream >> instanceId; - - // checksum - quint16 msgChecksum = 0; - readStream >> msgChecksum; - -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - const quint16 actualChecksum = qChecksum(QByteArray(msgBytes, static_cast<quint32>(msgBytes.length() - sizeof(quint16)))); -#else - const quint16 actualChecksum = qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length() - sizeof(quint16))); -#endif - - bool isValid = readStream.status() == QDataStream::Ok && - QLatin1String(latin1Name) == blockServerName && - msgChecksum == actualChecksum; - - if( !isValid ){ - sock->close(); - return; - } - - ConnectionInfo &info = connectionMap[sock]; - info.instanceId = instanceId; - info.stage = StageConnectedHeader; - - if( connectionType == NewInstance || - ( connectionType == SecondaryInstance && - options & SingleApplication::Mode::SecondaryNotification ) ) - { - Q_EMIT q->instanceStarted(); - } - - writeAck( sock ); -} - -void SingleApplicationPrivate::slotDataAvailable( QLocalSocket *dataSocket, quint32 instanceId ) -{ - Q_Q(SingleApplication); - - if ( !isFrameComplete( dataSocket ) ) - return; - - const QByteArray message = dataSocket->readAll(); - - writeAck( dataSocket ); - - ConnectionInfo &info = connectionMap[dataSocket]; - info.stage = StageConnectedHeader; - - Q_EMIT q->receivedMessage( instanceId, message); -} - -void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedSocket, quint32 instanceId ) -{ - if( closedSocket->bytesAvailable() > 0 ) - slotDataAvailable( closedSocket, instanceId ); -} - -void SingleApplicationPrivate::randomSleep() -{ -#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 ) - QThread::msleep( QRandomGenerator::global()->bounded( 8u, 18u )); -#else - qsrand( QDateTime::currentMSecsSinceEpoch() % std::numeric_limits<uint>::max() ); - QThread::msleep( qrand() % 11 + 8); -#endif -} - -void SingleApplicationPrivate::addAppData(const QString &data) -{ - appDataList.push_back(data); -} - -QStringList SingleApplicationPrivate::appData() const -{ - return appDataList; -} diff --git a/third_party/SingleApplication-3.3.2/singleapplication_p.h b/third_party/SingleApplication-3.3.2/singleapplication_p.h deleted file mode 100644 index 58507cf3..00000000 --- a/third_party/SingleApplication-3.3.2/singleapplication_p.h +++ /dev/null @@ -1,109 +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. - -// -// W A R N I N G !!! -// ----------------- -// -// This file is not part of the SingleApplication API. It is used purely as an -// implementation detail. This header file may change from version to -// version without notice, or may even be removed. -// - -#ifndef SINGLEAPPLICATION_P_H -#define SINGLEAPPLICATION_P_H - -#include <QtCore/QSharedMemory> -#include <QtNetwork/QLocalServer> -#include <QtNetwork/QLocalSocket> -#include "singleapplication.h" - -struct InstancesInfo { - bool primary; - quint32 secondary; - qint64 primaryPid; - char primaryUser[128]; - quint16 checksum; // Must be the last field -}; - -struct ConnectionInfo { - qint64 msgLen = 0; - quint32 instanceId = 0; - quint8 stage = 0; -}; - -class SingleApplicationPrivate : public QObject { -Q_OBJECT -public: - enum ConnectionType : quint8 { - InvalidConnection = 0, - NewInstance = 1, - SecondaryInstance = 2, - Reconnect = 3 - }; - enum ConnectionStage : quint8 { - StageInitHeader = 0, - StageInitBody = 1, - StageConnectedHeader = 2, - StageConnectedBody = 3, - }; - Q_DECLARE_PUBLIC(SingleApplication) - - SingleApplicationPrivate( SingleApplication *q_ptr ); - ~SingleApplicationPrivate() override; - - static QString getUsername(); - void genBlockServerName(); - void initializeMemoryBlock() const; - void startPrimary(); - void startSecondary(); - bool connectToPrimary( int msecs, ConnectionType connectionType ); - quint16 blockChecksum() const; - qint64 primaryPid() const; - QString primaryUser() const; - bool isFrameComplete(QLocalSocket *sock); - void readMessageHeader(QLocalSocket *socket, ConnectionStage nextStage); - void readInitMessageBody(QLocalSocket *socket); - void writeAck(QLocalSocket *sock); - bool writeConfirmedFrame(int msecs, const QByteArray &msg); - bool writeConfirmedMessage(int msecs, const QByteArray &msg); - static void randomSleep(); - void addAppData(const QString &data); - QStringList appData() const; - - SingleApplication *q_ptr; - QSharedMemory *memory; - QLocalSocket *socket; - QLocalServer *server; - quint32 instanceNumber; - QString blockServerName; - SingleApplication::Options options; - QMap<QLocalSocket*, ConnectionInfo> connectionMap; - QStringList appDataList; - -public Q_SLOTS: - void slotConnectionEstablished(); - void slotDataAvailable( QLocalSocket*, quint32 ); - void slotClientConnectionClosed( QLocalSocket*, quint32 ); -}; - -#endif // SINGLEAPPLICATION_P_H |