From cc669ac2cd2defa10ccf214a39f627299522e4c5 Mon Sep 17 00:00:00 2001 From: delia Date: Tue, 29 Apr 2025 01:06:13 +0200 Subject: [PATCH] Added SingleInstanceManager --- CMakeLists.txt | 7 +++++-- main.cpp | 23 ++++++++++++++--------- src/Qt/SingleInstanceManager.cpp | 32 ++++++++++++++++++++++++++++++++ src/Qt/SingleInstanceManager.h | 27 +++++++++++++++++++++++++++ src/Qt/UIWindow.cpp | 14 +++++++++++++- src/Qt/UIWindow.h | 5 ++++- 6 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 src/Qt/SingleInstanceManager.cpp create mode 100644 src/Qt/SingleInstanceManager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b42795..c9c1f5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ find_package(MPV REQUIRED) find_package(LZ4 REQUIRED) find_package(FFMPEG REQUIRED) find_package(PulseAudio REQUIRED) -find_package(Qt5 REQUIRED COMPONENTS Widgets) +find_package(Qt5 REQUIRED COMPONENTS Widgets Network) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) @@ -214,6 +214,8 @@ add_executable( src/Qt/UIWindow.h src/Qt/UIWindow.cpp + src/Qt/SingleInstanceManager.h + src/Qt/SingleInstanceManager.cpp src/External/Android/fft.cpp src/External/Android/fft.h @@ -474,7 +476,8 @@ target_link_libraries (linux-wallpaperengine PUBLIC ${PULSEAUDIO_LIBRARY} glfw libcef_lib libcef_dll_wrapper - Qt5::Widgets) + Qt5::Widgets + Qt5::Network) if (WAYLAND_SUPPORT_FOUND) diff --git a/main.cpp b/main.cpp index f1e33d6..2b691cc 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -10,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +28,7 @@ #include #include +#include "Qt/SingleInstanceManager.h" #include "Qt/UIWindow.h" #include "Steam/FileSystem/FileSystem.h" #include "WallpaperEngine/Application/CApplicationContext.h" @@ -34,6 +38,8 @@ WallpaperEngine::Application::CWallpaperApplication* appPointer; QCoreApplication* globalApp = nullptr; +SingleInstanceManager* g_instanceManager = nullptr; + class UIWindow; @@ -41,6 +47,7 @@ void signalhandler(int sig) { if (appPointer == nullptr) { if(globalApp != nullptr) { + if (g_instanceManager) g_instanceManager->cleanUpServer(); globalApp->quit(); } else return; } @@ -56,16 +63,14 @@ void initLogging () int main (int argc, char* argv[]) { initLogging (); - bool runGui = false; - for (int i = 1; i < argc; i++) { - if(std::strcmp(argv[i], "--gui") == 0) { - runGui = true; - break; + g_instanceManager = new SingleInstanceManager("linux-wallpaperengine"); + + if (argc <= 1) { + if (!g_instanceManager->tryListen()) { + std::cout << "App is already running!!!!\n"; + return 0; } - } - - if (runGui) { std::string path = Steam::FileSystem::workshopDirectory(431960); std::vector wallpaperPaths; @@ -81,7 +86,7 @@ int main (int argc, char* argv[]) { std::signal (SIGINT, signalhandler); std::signal (SIGTERM, signalhandler); - auto* uiWindow = new UIWindow(nullptr, &qapp); + auto* uiWindow = new UIWindow(nullptr, &qapp, g_instanceManager); uiWindow->setupUIWindow(wallpaperPaths); diff --git a/src/Qt/SingleInstanceManager.cpp b/src/Qt/SingleInstanceManager.cpp new file mode 100644 index 0000000..dd13821 --- /dev/null +++ b/src/Qt/SingleInstanceManager.cpp @@ -0,0 +1,32 @@ +#include "SingleInstanceManager.h" +#include +#include +#include +#include + +SingleInstanceManager::SingleInstanceManager(const QString& name, QObject* parent) : QObject(parent), m_serverName(name) { + this->server = new QLocalServer(this); +} + +SingleInstanceManager::~SingleInstanceManager() { + cleanUpServer(); +} + +void SingleInstanceManager::cleanUpServer() { + if(server->isListening()) { + server->close(); + } +} + +bool SingleInstanceManager::tryListen() { + if (!server->listen(m_serverName)) return false; + + connect(server, &QLocalServer::newConnection, this, [this]() { + auto client = server->nextPendingConnection(); + connect(client, &QLocalSocket::readyRead, client, [this, client]() { + emit messageReceived(client->readAll()); + client->disconnectFromServer(); + }); + }); + return true; +} diff --git a/src/Qt/SingleInstanceManager.h b/src/Qt/SingleInstanceManager.h new file mode 100644 index 0000000..0ae7471 --- /dev/null +++ b/src/Qt/SingleInstanceManager.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +class SingleInstanceManager : public QObject { + Q_OBJECT + + public: + SingleInstanceManager(const QString& serverName, QObject* parent = nullptr); + ~SingleInstanceManager() override; + + void cleanUpServer(); + + bool tryListen(); + void sendMessage(const QByteArray& message); + + signals: + void messageReceived(const QByteArray& message); + + private: + QLocalServer* server; + QString m_serverName; +}; diff --git a/src/Qt/UIWindow.cpp b/src/Qt/UIWindow.cpp index 17b6327..0bd24c6 100644 --- a/src/Qt/UIWindow.cpp +++ b/src/Qt/UIWindow.cpp @@ -1,26 +1,31 @@ #include "UIWindow.h" +#include "Qt/SingleInstanceManager.h" #include #include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #define PICTURE_SIZE 256 -UIWindow::UIWindow(QWidget* parent, QApplication* qapp) { +UIWindow::UIWindow(QWidget* parent, QApplication* qapp, SingleInstanceManager* ig) { this->qapp = qapp; this->screenSelector = new QComboBox(this); this->extraFlagsInput = new QLineEdit(this); this->wallpaperEngine = new QProcess(this); + this->instanceGuard = ig; } void UIWindow::setupUIWindow(std::vector wallpaperPaths) { @@ -67,6 +72,7 @@ void UIWindow::setupUIWindow(std::vector wallpaperPaths) { QAbstractButton::connect(button, &QPushButton::clicked, [button, this]() { QString clickedPath = button->property("path").toString(); + std::cout << clickedPath.toStdString() << "\n"; button->setEnabled(false); this->selectedWallpapers[this->screenSelector->currentText().toStdString()] = clickedPath.toStdString(); @@ -88,6 +94,12 @@ void UIWindow::setupUIWindow(std::vector wallpaperPaths) { QObject::connect(this->qapp, &QCoreApplication::aboutToQuit, this, [this]() { wallpaperEngine->terminate(); wallpaperEngine->waitForFinished(3000); + + instanceGuard->cleanUpServer(); + }); + + QObject::connect(instanceGuard, &SingleInstanceManager::messageReceived, [this](const QByteArray& msg) { + qDebug() << msg; }); container->setLayout(layout); diff --git a/src/Qt/UIWindow.h b/src/Qt/UIWindow.h index 6134cc5..b42a018 100644 --- a/src/Qt/UIWindow.h +++ b/src/Qt/UIWindow.h @@ -1,8 +1,10 @@ #pragma once +#include "Qt/SingleInstanceManager.h" #include #include #include +#include #include #include #include @@ -28,11 +30,12 @@ class UIWindow : public QWidget { Q_OBJECT public: - UIWindow(QWidget* parent, QApplication* qapp); + UIWindow(QWidget* parent, QApplication* qapp, SingleInstanceManager* instanceGuard); void setupUIWindow(std::vector wallpaperPaths); private: QApplication* qapp; + SingleInstanceManager* instanceGuard; QComboBox* screenSelector; QLineEdit* extraFlagsInput; std::map selectedWallpapers;