From 5e63ac316caaedc9c5e2a2a831f8284084245ce7 Mon Sep 17 00:00:00 2001 From: Laurent Trinques Date: Wed, 8 Jan 2020 14:27:52 +0100 Subject: [PATCH] Update SingleApplication to latest upstream sources --- SingleApplication/CHANGELOG.md | 50 ++++++++++++++++++++++- SingleApplication/CMakeLists.txt | 43 +++++++++++++++++++ SingleApplication/README.md | 18 ++++++-- SingleApplication/Windows.md | 2 +- SingleApplication/singleapplication.cpp | 11 ++++- SingleApplication/singleapplication.h | 4 +- SingleApplication/singleapplication_p.cpp | 36 ++++++++-------- 7 files changed, 138 insertions(+), 26 deletions(-) create mode 100644 SingleApplication/CMakeLists.txt diff --git a/SingleApplication/CHANGELOG.md b/SingleApplication/CHANGELOG.md index 8ae3a036d..45c197e3d 100644 --- a/SingleApplication/CHANGELOG.md +++ b/SingleApplication/CHANGELOG.md @@ -1,6 +1,54 @@ Changelog ========= +__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__ ---------- @@ -113,7 +161,7 @@ __3.0.1a__ __v3.0a__ --------- -* Depricated secondary instances count. +* 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. diff --git a/SingleApplication/CMakeLists.txt b/SingleApplication/CMakeLists.txt new file mode 100644 index 000000000..d61923043 --- /dev/null +++ b/SingleApplication/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.1.0) + +project(SingleApplication) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) + +# SingleApplication base class +set(QAPPLICATION_CLASS QCoreApplication CACHE STRING "Inheritance class for SingleApplication") +set_property(CACHE QAPPLICATION_CLASS PROPERTY STRINGS QApplication QGuiApplication QCoreApplication) + +# Libary target +add_library(${PROJECT_NAME} STATIC + singleapplication.cpp + singleapplication_p.cpp + ) + +# Find dependencies +find_package(Qt5Network) +if(QAPPLICATION_CLASS STREQUAL QApplication) + find_package(Qt5 COMPONENTS Widgets REQUIRED) +elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication) + find_package(Qt5 COMPONENTS Gui REQUIRED) +else() + find_package(Qt5 COMPONENTS Core REQUIRED) +endif() +add_compile_definitions(QAPPLICATION_CLASS=${QAPPLICATION_CLASS}) + +# Link dependencies +target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Network) +if(QAPPLICATION_CLASS STREQUAL QApplication) + target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets) +elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication) + target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Gui) +else() + target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core) +endif() + +if(WIN32) + target_link_libraries(${PROJECT_NAME} PRIVATE advapi32) +endif() + +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/SingleApplication/README.md b/SingleApplication/README.md index 0b1a35520..5d6098654 100644 --- a/SingleApplication/README.md +++ b/SingleApplication/README.md @@ -50,15 +50,27 @@ how: 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:** + +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) +``` + +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 ------------------------ diff --git a/SingleApplication/Windows.md b/SingleApplication/Windows.md index 48b0748ce..13c52da0e 100644 --- a/SingleApplication/Windows.md +++ b/SingleApplication/Windows.md @@ -24,7 +24,7 @@ Here is an example: ```cpp if( app.isSecondary() ) { // This API requires LIBS += User32.lib to be added to the project - AllowSetForegroundWindow( DWORD( app.getPrimaryPid() ) ); + AllowSetForegroundWindow( DWORD( app.primaryPid() ) ); } if( app.isPrimary() ) { diff --git a/SingleApplication/singleapplication.cpp b/SingleApplication/singleapplication.cpp index a7972314b..ba35c3a5d 100644 --- a/SingleApplication/singleapplication.cpp +++ b/SingleApplication/singleapplication.cpp @@ -41,6 +41,13 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda { 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; @@ -168,7 +175,7 @@ bool SingleApplication::sendMessage( QByteArray message, int timeout ) d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect ); d->socket->write( message ); - bool dataWritten = d->socket->flush(); - d->socket->waitForBytesWritten( timeout ); + bool dataWritten = d->socket->waitForBytesWritten( timeout ); + d->socket->flush(); return dataWritten; } diff --git a/SingleApplication/singleapplication.h b/SingleApplication/singleapplication.h index f123abdb2..cb5059710 100644 --- a/SingleApplication/singleapplication.h +++ b/SingleApplication/singleapplication.h @@ -35,7 +35,7 @@ class SingleApplicationPrivate; /** - * @brief The SingleApplication class handles multipe instances of the same + * @brief The SingleApplication class handles multiple instances of the same * Application * @see QCoreApplication */ @@ -74,7 +74,7 @@ public: * 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. + * @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 diff --git a/SingleApplication/singleapplication_p.cpp b/SingleApplication/singleapplication_p.cpp index c511f70fe..884fe6314 100644 --- a/SingleApplication/singleapplication_p.cpp +++ b/SingleApplication/singleapplication_p.cpp @@ -33,11 +33,8 @@ #include #include -#include #include -#include #include -#include #include #include #include @@ -45,6 +42,12 @@ #include "singleapplication.h" #include "singleapplication_p.h" +#ifdef Q_OS_UNIX + #include + #include + #include +#endif + #ifdef Q_OS_WIN #include #include @@ -55,6 +58,8 @@ SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr ) { server = nullptr; socket = nullptr; + memory = nullptr; + instanceNumber = -1; } SingleApplicationPrivate::~SingleApplicationPrivate() @@ -107,22 +112,20 @@ void SingleApplicationPrivate::genBlockServerName() if( GetUserNameW( username, &usernameLength ) ) { appData.addData( QString::fromWCharArray(username).toUtf8() ); } else { - appData.addData( QStandardPaths::standardLocations( QStandardPaths::HomeLocation ).join("").toUtf8() ); + appData.addData( qgetenv("USERNAME") ); } #endif #ifdef Q_OS_UNIX - QProcess process; - process.start( "whoami" ); - if( process.waitForFinished( 100 ) && - process.exitCode() == QProcess::NormalExit) { - appData.addData( process.readLine() ); - } else { - appData.addData( - QDir( - QStandardPaths::standardLocations( QStandardPaths::HomeLocation ).first() - ).absolutePath().toUtf8() - ); + QByteArray username; + uid_t uid = geteuid(); + struct passwd *pw = getpwuid(uid); + if( pw ) { + username = pw->pw_name; } + if( username.isEmpty() ) { + username = qgetenv("USER"); + } + appData.addData(username); #endif } @@ -385,8 +388,7 @@ void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock ) } if (sock->bytesAvailable() > 0) { - //This line crash - //Q_EMIT this->slotDataAvailable( sock, instanceId ); + Q_EMIT this->slotDataAvailable( sock, instanceId ); } }