aboutsummaryrefslogtreecommitdiff
path: root/3rd-party/SingleApplication
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2018-10-02 14:12:01 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2018-10-02 14:12:01 +0200
commitc409efea81d6cdf5fd0e36671455267a0049df13 (patch)
tree9ce243c7ea1498449e667aead541e31311705d77 /3rd-party/SingleApplication
parentUpdate remaining repository paths in license headers (diff)
downloadsmolbote-c409efea81d6cdf5fd0e36671455267a0049df13.tar.xz
Add SingleApplication as a git submodule
Diffstat (limited to '3rd-party/SingleApplication')
-rw-r--r--3rd-party/SingleApplication/CHANGELOG.md162
-rw-r--r--3rd-party/SingleApplication/CMakeLists.txt12
-rw-r--r--3rd-party/SingleApplication/LICENSE24
-rw-r--r--3rd-party/SingleApplication/README.md287
m---------3rd-party/SingleApplication/SingleApplication.git0
-rw-r--r--3rd-party/SingleApplication/Windows.md46
-rw-r--r--3rd-party/SingleApplication/singleapplication.cpp468
-rw-r--r--3rd-party/SingleApplication/singleapplication.h135
-rw-r--r--3rd-party/SingleApplication/singleapplication.pri18
-rw-r--r--3rd-party/SingleApplication/singleapplication_p.h85
10 files changed, 8 insertions, 1229 deletions
diff --git a/3rd-party/SingleApplication/CHANGELOG.md b/3rd-party/SingleApplication/CHANGELOG.md
deleted file mode 100644
index 4665222..0000000
--- a/3rd-party/SingleApplication/CHANGELOG.md
+++ /dev/null
@@ -1,162 +0,0 @@
-Changelog
-=========
-
-__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__
----------
-
-* Depricated 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/3rd-party/SingleApplication/CMakeLists.txt b/3rd-party/SingleApplication/CMakeLists.txt
index 5de0253..97fe7d7 100644
--- a/3rd-party/SingleApplication/CMakeLists.txt
+++ b/3rd-party/SingleApplication/CMakeLists.txt
@@ -7,12 +7,16 @@ set(CMAKE_AUTOMOC ON)
#set(CMAKE_AUTORCC ON)
add_library(SingleApplication
- singleapplication.cpp
- singleapplication.h
- singleapplication_p.h)
+ SingleApplication.git/singleapplication.cpp
+ SingleApplication.git/singleapplication.h
+ SingleApplication.git/singleapplication_p.cpp
+ SingleApplication.git/singleapplication_p.h
+)
+
+target_include_directories(SingleApplication PUBLIC SingleApplication.git)
target_link_libraries(SingleApplication
- Qt5::Core Qt5::Network Qt5::Widgets
+ Qt5::Core Qt5::Network Qt5::Widgets
)
target_compile_definitions(SingleApplication
diff --git a/3rd-party/SingleApplication/LICENSE b/3rd-party/SingleApplication/LICENSE
deleted file mode 100644
index 85b2a14..0000000
--- a/3rd-party/SingleApplication/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Itay Grudev 2015 - 2016
-
-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/3rd-party/SingleApplication/README.md b/3rd-party/SingleApplication/README.md
deleted file mode 100644
index 82e7a5b..0000000
--- a/3rd-party/SingleApplication/README.md
+++ /dev/null
@@ -1,287 +0,0 @@
-SingleApplication
-=================
-
-This is a replacement of the QtSingleApplication for `Qt5`.
-
-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.
-
-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.
-
-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 and include it's contents with a `.pri` file. Here is
-how:
-
-```bash
-git submodule add git@github.com:itay-grudev/SingleApplication.git singleapplication
-```
-
-Then include the `singleapplication.pri` file in your `.pro` project file. Also
-don't forget to specify which `QCoreApplication` class your app is using if it
-is not `QCoreApplication`.
-
-```qmake
-include(singleapplication/singleapplication.pri)
-DEFINES += QAPPLICATION_CLASS=QApplication
-```
-
-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.*
-
-API
----
-
-### Members
-
-```cpp
-SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100 )
-```
-
-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.
-
-*__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
-
----
-
-```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.
-
-### 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.
-
-To handle an issue on `*nix` systems, where the operating system owns the shared
-memory block and if the program crashes the memory remains untouched, the
-library binds to the following signals and closes the program with
-`error code = 128 + signum` where signum is the number representation of the
-signal listed below. Handling the signal is required in order to safely delete
-the `QSharedMemory` block. Each of these signals are potentially lethal and will
-results in process termination.
-
-* `SIGHUP` - `1`, Hangup.
-* `SIGINT` - `2`, Terminal interrupt signal
-* `SIGQUIT` - `3`, Terminal quit signal.
-* `SIGILL` - `4`, Illegal instruction.
-* `SIGABRT` - `6`, Process abort signal.
-* `SIGBUS` - `7`, Access to an undefined portion of a memory object.
-* `SIGFPE` - `8`, Erroneous arithmetic operation (such as division by zero).
-* `SIGSEGV` - `11`, Invalid memory reference.
-* `SIGSYS` - `12`, Bad system call.
-* `SIGPIPE` - `13`, Write on a pipe with no one to read it.
-* `SIGALRM` - `14`, Alarm clock.
-* `SIGTERM` - `15`, Termination signal.
-* `SIGXCPU` - `24`, CPU time limit exceeded.
-* `SIGXFSZ` - `25`, File size limit exceeded.
-
-Additionally the library can recover from being killed with uncatchable signals
-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 some of the examples distributed
-under the BSD license.
diff --git a/3rd-party/SingleApplication/SingleApplication.git b/3rd-party/SingleApplication/SingleApplication.git
new file mode 160000
+Subproject 0db27016b0470b989f4fa114ae9dde5aa2a325f
diff --git a/3rd-party/SingleApplication/Windows.md b/3rd-party/SingleApplication/Windows.md
deleted file mode 100644
index 48b0748..0000000
--- a/3rd-party/SingleApplication/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.getPrimaryPid() ) );
-}
-
-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/3rd-party/SingleApplication/singleapplication.cpp b/3rd-party/SingleApplication/singleapplication.cpp
deleted file mode 100644
index c74d6db..0000000
--- a/3rd-party/SingleApplication/singleapplication.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-// The MIT License (MIT)
-//
-// Copyright (c) Itay Grudev 2015 - 2016
-//
-// 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 <cstdlib>
-
-#include <QtCore/QDir>
-#include <QtCore/QProcess>
-#include <QtCore/QByteArray>
-#include <QtCore/QSemaphore>
-#include <QtCore/QSharedMemory>
-#include <QtCore/QStandardPaths>
-#include <QtCore/QCryptographicHash>
-#include <QtCore/QDataStream>
-#include <QtNetwork/QLocalServer>
-#include <QtNetwork/QLocalSocket>
-
-#ifdef Q_OS_UNIX
- #include <signal.h>
- #include <unistd.h>
-#endif
-
-#ifdef Q_OS_WIN
- #include <windows.h>
- #include <lmcons.h>
-#endif
-
-#include "singleapplication.h"
-#include "singleapplication_p.h"
-
-
-SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr ) : q_ptr( q_ptr ) {
- server = nullptr;
- socket = nullptr;
-}
-
-SingleApplicationPrivate::~SingleApplicationPrivate()
-{
- if( socket != nullptr ) {
- socket->close();
- delete socket;
- }
-
- memory->lock();
- InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
- if( server != nullptr ) {
- server->close();
- delete server;
- inst->primary = false;
- inst->primaryPid = -1;
- }
- memory->unlock();
-
- delete memory;
-}
-
-void SingleApplicationPrivate::genBlockServerName( int timeout )
-{
- 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( ! (options & SingleApplication::Mode::ExcludeAppVersion) ) {
- appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() );
- }
-
- if( ! (options & SingleApplication::Mode::ExcludeAppPath) ) {
-#ifdef Q_OS_WIN
- appData.addData( SingleApplication::app_t::applicationFilePath().toLower().toUtf8() );
-#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 ) {
-#ifdef Q_OS_WIN
- Q_UNUSED(timeout);
- wchar_t username [ UNLEN + 1 ];
- // Specifies size of the buffer on input
- DWORD usernameLength = UNLEN + 1;
- if( GetUserNameW( username, &usernameLength ) ) {
- appData.addData( QString::fromWCharArray(username).toUtf8() );
- } else {
- appData.addData( QStandardPaths::standardLocations( QStandardPaths::HomeLocation ).join("").toUtf8() );
- }
-#endif
-#ifdef Q_OS_UNIX
- QProcess process;
- process.start( "whoami" );
- if( process.waitForFinished( timeout ) &&
- process.exitCode() == QProcess::NormalExit) {
- appData.addData( process.readLine() );
- } else {
- appData.addData(
- QDir(
- QStandardPaths::standardLocations( QStandardPaths::HomeLocation ).first()
- ).absolutePath().toUtf8()
- );
- }
-#endif
- }
-
- // Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
- // server naming requirements.
- blockServerName = appData.result().toBase64().replace("/", "_");
-}
-
-void SingleApplicationPrivate::startPrimary( bool resetMemory )
-{
- Q_Q(SingleApplication);
-
-#ifdef Q_OS_UNIX
- // Handle any further termination signals to ensure the
- // QSharedMemory block is deleted even if the process crashes
- crashHandler();
-#endif
- // 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
- );
-
- // Reset the number of connections
- memory->lock();
- InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
-
- if( resetMemory ) {
- inst->secondary = 0;
- }
-
- inst->primary = true;
- inst->primaryPid = q->applicationPid();
-
- memory->unlock();
-
- instanceNumber = 0;
-}
-
-void SingleApplicationPrivate::startSecondary()
-{
-#ifdef Q_OS_UNIX
- // Handle any further termination signals to ensure the
- // QSharedMemory block is deleted even if the process crashes
- crashHandler();
-#endif
-}
-
-void SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType )
-{
- // Connect to the Local Server of the Primary Instance if not already
- // connected.
- if( socket == nullptr ) {
- socket = new QLocalSocket();
- }
-
- // If already connected - we are done;
- if( socket->state() == QLocalSocket::ConnectedState )
- return;
-
- // If not connect
- if( socket->state() == QLocalSocket::UnconnectedState ||
- socket->state() == QLocalSocket::ClosingState ) {
- socket->connectToServer( blockServerName );
- }
-
- // Wait for being connected
- if( socket->state() == QLocalSocket::ConnectingState ) {
- socket->waitForConnected( msecs );
- }
-
- // Initialisation message according to the SingleApplication protocol
- if( socket->state() == QLocalSocket::ConnectedState ) {
- // Notify the parent that a new instance had been started;
- QByteArray initMsg;
- QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
- writeStream.setVersion(QDataStream::Qt_5_6);
- writeStream << blockServerName.toLatin1();
- writeStream << static_cast<quint8>(connectionType);
- writeStream << instanceNumber;
- quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
- writeStream << checksum;
-
- socket->write( initMsg );
- socket->flush();
- socket->waitForBytesWritten( msecs );
- }
-}
-
-qint64 SingleApplicationPrivate::primaryPid()
-{
- qint64 pid;
-
- memory->lock();
- InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
- pid = inst->primaryPid;
- memory->unlock();
-
- return pid;
-}
-
-#ifdef Q_OS_UNIX
- void SingleApplicationPrivate::crashHandler()
- {
- // Handle any further termination signals to ensure the
- // QSharedMemory block is deleted even if the process crashes
- signal( SIGHUP, SingleApplicationPrivate::terminate ); // 1
- signal( SIGINT, SingleApplicationPrivate::terminate ); // 2
- signal( SIGQUIT, SingleApplicationPrivate::terminate ); // 3
- signal( SIGILL, SingleApplicationPrivate::terminate ); // 4
- signal( SIGABRT, SingleApplicationPrivate::terminate ); // 6
- signal( SIGFPE, SingleApplicationPrivate::terminate ); // 8
- signal( SIGBUS, SingleApplicationPrivate::terminate ); // 10
- signal( SIGSEGV, SingleApplicationPrivate::terminate ); // 11
- signal( SIGSYS, SingleApplicationPrivate::terminate ); // 12
- signal( SIGPIPE, SingleApplicationPrivate::terminate ); // 13
- signal( SIGALRM, SingleApplicationPrivate::terminate ); // 14
- signal( SIGTERM, SingleApplicationPrivate::terminate ); // 15
- signal( SIGXCPU, SingleApplicationPrivate::terminate ); // 24
- signal( SIGXFSZ, SingleApplicationPrivate::terminate ); // 25
- }
-
- void SingleApplicationPrivate::terminate( int signum )
- {
- delete ((SingleApplication*)QCoreApplication::instance())->d_ptr;
- ::exit( 128 + signum );
- }
-#endif
-
-/**
- * @brief Executed when a connection has been made to the LocalServer
- */
-void SingleApplicationPrivate::slotConnectionEstablished()
-{
- Q_Q(SingleApplication);
-
- QLocalSocket *nextConnSocket = server->nextPendingConnection();
-
- quint32 instanceId = 0;
- ConnectionType connectionType = InvalidConnection;
- if( nextConnSocket->waitForReadyRead( 100 ) ) {
- // read all data from message in same order/format as written
- QByteArray msgBytes = nextConnSocket->read(nextConnSocket->bytesAvailable() - static_cast<qint64>(sizeof(quint16)));
- QByteArray checksumBytes = nextConnSocket->read(sizeof(quint16));
- QDataStream readStream(msgBytes);
- readStream.setVersion(QDataStream::Qt_5_6);
-
- // server name
- QByteArray latin1Name;
- readStream >> latin1Name;
- // connectioon type
- quint8 connType = InvalidConnection;
- readStream >> connType;
- connectionType = static_cast<ConnectionType>(connType);
- // instance id
- readStream >> instanceId;
- // checksum
- quint16 msgChecksum = 0;
- QDataStream checksumStream(checksumBytes);
- checksumStream.setVersion(QDataStream::Qt_5_6);
- checksumStream >> msgChecksum;
-
- const quint16 actualChecksum = qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length()));
-
- if (readStream.status() != QDataStream::Ok || QLatin1String(latin1Name) != blockServerName || msgChecksum != actualChecksum) {
- connectionType = InvalidConnection;
- }
- }
-
- if( connectionType == InvalidConnection ) {
- nextConnSocket->close();
- delete nextConnSocket;
- return;
- }
-
- QObject::connect(
- nextConnSocket,
- &QLocalSocket::aboutToClose,
- this,
- [nextConnSocket, instanceId, this]() {
- Q_EMIT this->slotClientConnectionClosed( nextConnSocket, instanceId );
- }
- );
-
- QObject::connect(
- nextConnSocket,
- &QLocalSocket::readyRead,
- this,
- [nextConnSocket, instanceId, this]() {
- Q_EMIT this->slotDataAvailable( nextConnSocket, instanceId );
- }
- );
-
- if( connectionType == NewInstance || (
- connectionType == SecondaryInstance &&
- options & SingleApplication::Mode::SecondaryNotification
- )
- ) {
- Q_EMIT q->instanceStarted();
- }
-
- if( nextConnSocket->bytesAvailable() > 0 ) {
- Q_EMIT this->slotDataAvailable( nextConnSocket, instanceId );
- }
-}
-
-void SingleApplicationPrivate::slotDataAvailable( QLocalSocket *dataSocket, quint32 instanceId )
-{
- Q_Q(SingleApplication);
- Q_EMIT q->receivedMessage( instanceId, dataSocket->readAll() );
-}
-
-void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedSocket, quint32 instanceId )
-{
- if( closedSocket->bytesAvailable() > 0 )
- Q_EMIT slotDataAvailable( closedSocket, instanceId );
- closedSocket->deleteLater();
-}
-
-/**
- * @brief Constructor. Checks and fires up LocalServer or closes the program
- * if another instance already exists
- * @param argc
- * @param argv
- * @param {bool} allowSecondaryInstances
- */
-SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout )
- : app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) )
-{
- Q_D(SingleApplication);
-
- // Store the current mode of the program
- d->options = options;
-
- // Generating an application ID used for identifying the shared memory
- // block and QLocalServer
- d->genBlockServerName( timeout );
-
- // Guarantee thread safe behaviour with a shared memory block. Also by
- // explicitly attaching it and then deleting it we make sure that the
- // memory is deleted even if the process had crashed on Unix.
-#ifdef Q_OS_UNIX
- d->memory = new QSharedMemory( d->blockServerName );
- d->memory->attach();
- delete d->memory;
-#endif
- d->memory = new QSharedMemory( d->blockServerName );
-
- // Create a shared memory block
- if( d->memory->create( sizeof( InstancesInfo ) ) ) {
- d->startPrimary( true );
- return;
- } else {
- // Attempt to attach to the memory segment
- if( d->memory->attach() ) {
- d->memory->lock();
- InstancesInfo* inst = static_cast<InstancesInfo*>(d->memory->data());
-
- if( ! inst->primary ) {
- d->startPrimary( false );
- d->memory->unlock();
- return;
- }
-
- // Check if another instance can be started
- if( allowSecondary ) {
- inst->secondary += 1;
- d->instanceNumber = inst->secondary;
- d->startSecondary();
- if( d->options & Mode::SecondaryNotification ) {
- d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance );
- }
- d->memory->unlock();
- return;
- }
-
- d->memory->unlock();
- }
- }
-
- d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance );
- delete d;
- ::exit( EXIT_SUCCESS );
-}
-
-/**
- * @brief Destructor
- */
-SingleApplication::~SingleApplication()
-{
- Q_D(SingleApplication);
- delete d;
-}
-
-bool SingleApplication::isPrimary()
-{
- Q_D(SingleApplication);
- return d->server != nullptr;
-}
-
-bool SingleApplication::isSecondary()
-{
- Q_D(SingleApplication);
- return d->server == nullptr;
-}
-
-quint32 SingleApplication::instanceId()
-{
- Q_D(SingleApplication);
- return d->instanceNumber;
-}
-
-qint64 SingleApplication::primaryPid()
-{
- Q_D(SingleApplication);
- return d->primaryPid();
-}
-
-bool SingleApplication::sendMessage( QByteArray message, int timeout )
-{
- Q_D(SingleApplication);
-
- // Nobody to connect to
- if( isPrimary() ) return false;
-
- // Make sure the socket is connected
- d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect );
-
- d->socket->write( message );
- bool dataWritten = d->socket->flush();
- d->socket->waitForBytesWritten( timeout );
- return dataWritten;
-}
diff --git a/3rd-party/SingleApplication/singleapplication.h b/3rd-party/SingleApplication/singleapplication.h
deleted file mode 100644
index 33a9898..0000000
--- a/3rd-party/SingleApplication/singleapplication.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// The MIT License (MIT)
-//
-// Copyright (c) Itay Grudev 2015 - 2016
-//
-// 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 multipe instances of the same
- * Application
- * @see QCoreApplication
- */
-class SingleApplication : public QAPPLICATION_CLASS
-{
- Q_OBJECT
-
- typedef QAPPLICATION_CLASS app_t;
-
-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 miliseconds.
- * @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 = 100 );
- ~SingleApplication();
-
- /**
- * @brief Returns if the instance is the primary instance
- * @returns {bool}
- */
- bool isPrimary();
-
- /**
- * @brief Returns if the instance is a secondary instance
- * @returns {bool}
- */
- bool isSecondary();
-
- /**
- * @brief Returns a unique identifier for the current instance
- * @returns {qint32}
- */
- quint32 instanceId();
-
- /**
- * @brief Returns the process ID (PID) of the primary instance
- * @returns {qint64}
- */
- qint64 primaryPid();
-
- /**
- * @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( QByteArray message, int timeout = 100 );
-
-Q_SIGNALS:
- void instanceStarted();
- void receivedMessage( quint32 instanceId, QByteArray message );
-
-private:
- SingleApplicationPrivate *d_ptr;
- Q_DECLARE_PRIVATE(SingleApplication)
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options)
-
-#endif // SINGLE_APPLICATION_H
diff --git a/3rd-party/SingleApplication/singleapplication.pri b/3rd-party/SingleApplication/singleapplication.pri
deleted file mode 100644
index a82ff28..0000000
--- a/3rd-party/SingleApplication/singleapplication.pri
+++ /dev/null
@@ -1,18 +0,0 @@
-QT += core network
-CONFIG += c++11
-
-HEADERS += $$PWD/singleapplication.h \
- $$PWD/singleapplication_p.h
-SOURCES += $$PWD/singleapplication.cpp
-
-INCLUDEPATH += $$PWD
-
-win32 {
- msvc:LIBS += Advapi32.lib
- gcc:LIBS += -lAdvapi32
-}
-
-DISTFILES += \
- $$PWD/README.md \
- $$PWD/CHANGELOG.md \
- $$PWD/Windows.md
diff --git a/3rd-party/SingleApplication/singleapplication_p.h b/3rd-party/SingleApplication/singleapplication_p.h
deleted file mode 100644
index a990a53..0000000
--- a/3rd-party/SingleApplication/singleapplication_p.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// The MIT License (MIT)
-//
-// Copyright (c) Itay Grudev 2015 - 2016
-//
-// 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;
-};
-
-class SingleApplicationPrivate : public QObject {
-Q_OBJECT
-public:
- enum ConnectionType : quint8 {
- InvalidConnection = 0,
- NewInstance = 1,
- SecondaryInstance = 2,
- Reconnect = 3
- };
- Q_DECLARE_PUBLIC(SingleApplication)
-
- SingleApplicationPrivate( SingleApplication *q_ptr );
- ~SingleApplicationPrivate();
-
- void genBlockServerName( int msecs );
- void startPrimary( bool resetMemory );
- void startSecondary();
- void connectToPrimary(int msecs, ConnectionType connectionType );
- qint64 primaryPid();
-
-#ifdef Q_OS_UNIX
- void crashHandler();
- static void terminate( int signum );
-#endif
-
- QSharedMemory *memory;
- SingleApplication *q_ptr;
- QLocalSocket *socket;
- QLocalServer *server;
- quint32 instanceNumber;
- QString blockServerName;
- SingleApplication::Options options;
-
-public Q_SLOTS:
- void slotConnectionEstablished();
- void slotDataAvailable( QLocalSocket*, quint32 );
- void slotClientConnectionClosed( QLocalSocket*, quint32 );
-};
-
-#endif // SINGLEAPPLICATION_P_H