diff --git a/src/apps/deskflow-daemon/DaemonApp.cpp b/src/apps/deskflow-daemon/DaemonApp.cpp index ce317a3cd..246e74651 100644 --- a/src/apps/deskflow-daemon/DaemonApp.cpp +++ b/src/apps/deskflow-daemon/DaemonApp.cpp @@ -27,7 +27,8 @@ #endif -#include +#include +#include using namespace deskflow::core; @@ -45,26 +46,40 @@ void DaemonApp::saveLogLevel(const QString &logLevel) const Settings::setValue(Settings::Daemon::LogLevel, logLevel); } -void DaemonApp::setElevate(bool elevate) +void DaemonApp::setConfigFile(const QString &configFile) { - LOG_DEBUG("elevate value changed: %s", elevate ? "yes" : "no"); - m_elevate = elevate; - Settings::setValue(Settings::Daemon::Elevate, m_elevate); -} - -void DaemonApp::setCommand(const QString &command) -{ - LOG_DEBUG("service command updated"); - Settings::setValue(Settings::Daemon::Command, command); - m_command = command.toStdString(); + LOG_DEBUG("config file updated: %s", configFile.toUtf8().constData()); + m_configFile = configFile; + Settings::setValue(Settings::Daemon::ConfigFile, configFile); } void DaemonApp::applyWatchdogCommand() const { - LOG_DEBUG("applying watchdog command"); - #if defined(Q_OS_WIN) - m_pWatchdog->setProcessConfig(m_command, m_elevate); + if (m_configFile.isEmpty()) { + LOG_ERR("cannot apply watchdog command: no config file set"); + return; + } + + QSettings config(m_configFile, QSettings::IniFormat); + const auto coreMode = config.value(Settings::Core::CoreMode).toInt(); + const auto elevate = config.value(Settings::Daemon::Elevate, !Settings::isPortableMode()).toBool(); + + QString modeArg; + if (coreMode == Settings::CoreMode::Server) { + modeArg = QStringLiteral("server"); + } else if (coreMode == Settings::CoreMode::Client) { + modeArg = QStringLiteral("client"); + } else { + LOG_ERR("cannot apply watchdog command: invalid core mode in config: %d", coreMode); + return; + } + + const auto corePath = QStringLiteral("%1/%2").arg(QCoreApplication::applicationDirPath(), kCoreBinName); + const auto command = QStringLiteral("\"%1\" %2 --settings \"%3\"").arg(corePath, modeArg, m_configFile).toStdString(); + + LOG_DEBUG("applying watchdog command (elevate: %s)", elevate ? "yes" : "no"); + m_pWatchdog->setProcessConfig(command, elevate); #else LOG_ERR("applying watchdog command not implemented on this platform"); #endif @@ -74,8 +89,9 @@ void DaemonApp::clearWatchdogCommand() { LOG_DEBUG("clearing watchdog command"); - // Clear the setting to prevent it from being next time the daemon starts. - setCommand(""); + // Clear the persisted config path so the daemon does not auto-start the core on next boot. + m_configFile.clear(); + Settings::setValue(Settings::Daemon::ConfigFile); #if defined(Q_OS_WIN) m_pWatchdog->setProcessConfig("", false); @@ -84,11 +100,11 @@ void DaemonApp::clearWatchdogCommand() #endif } -void DaemonApp::clearSettings() const +void DaemonApp::clearSettings() { LOG_INFO("clearing daemon settings"); - Settings::setValue(Settings::Daemon::Command); - Settings::setValue(Settings::Daemon::Elevate); + m_configFile.clear(); + Settings::setValue(Settings::Daemon::ConfigFile); Settings::setValue(Settings::Daemon::LogFile); Settings::setValue(Settings::Daemon::LogLevel); } @@ -98,8 +114,7 @@ void DaemonApp::connectIpcServer(const ipc::DaemonIpcServer *ipcServer) const // Use direct connection as this object is on it's own thread, // and so is on a different event loop to the main Qt loop. connect(ipcServer, &ipc::DaemonIpcServer::logLevelChanged, this, &DaemonApp::saveLogLevel, Qt::DirectConnection); - connect(ipcServer, &ipc::DaemonIpcServer::elevateModeChanged, this, &DaemonApp::setElevate, Qt::DirectConnection); - connect(ipcServer, &ipc::DaemonIpcServer::commandChanged, this, &DaemonApp::setCommand, Qt::DirectConnection); + connect(ipcServer, &ipc::DaemonIpcServer::configFileChanged, this, &DaemonApp::setConfigFile, Qt::DirectConnection); connect( ipcServer, &ipc::DaemonIpcServer::startProcessRequested, this, &DaemonApp::applyWatchdogCommand, Qt::DirectConnection @@ -139,11 +154,11 @@ void DaemonApp::run(QThread &daemonThread) #if defined(Q_OS_WIN) m_pWatchdog = std::make_unique(m_foreground, *m_pFileLogOutputter); - auto command = Settings::value(Settings::Daemon::Command).toString().toStdString(); - bool elevate = Settings::value(Settings::Daemon::Elevate).toBool(); - if (!command.empty()) { - LOG_DEBUG("using last known command: %s", command.c_str()); - m_pWatchdog->setProcessConfig(command, elevate); + if (const auto persistedConfig = Settings::value(Settings::Daemon::ConfigFile).toString(); + !persistedConfig.isEmpty()) { + LOG_DEBUG("using last known config file: %s", persistedConfig.toUtf8().constData()); + m_configFile = persistedConfig; + applyWatchdogCommand(); } #endif diff --git a/src/apps/deskflow-daemon/DaemonApp.h b/src/apps/deskflow-daemon/DaemonApp.h index ca9a250fa..6c5739d2f 100644 --- a/src/apps/deskflow-daemon/DaemonApp.h +++ b/src/apps/deskflow-daemon/DaemonApp.h @@ -6,8 +6,6 @@ #pragma once -#include - #include #include @@ -48,11 +46,10 @@ private: int mainLoop(); int daemonLoop(); void saveLogLevel(const QString &logLevel) const; - void setElevate(bool elevate); - void setCommand(const QString &command); + void setConfigFile(const QString &configFile); void applyWatchdogCommand() const; void clearWatchdogCommand(); - void clearSettings() const; + void clearSettings(); static void showConsole(); @@ -63,7 +60,6 @@ private: IEventQueue &m_events; FileLogOutputter *m_pFileLogOutputter = nullptr; deskflow::core::ipc::DaemonIpcServer *m_ipcServer = nullptr; - std::string m_command = ""; - bool m_elevate = false; + QString m_configFile; bool m_foreground = false; }; diff --git a/src/lib/common/Settings.h b/src/lib/common/Settings.h index af1ceb6a8..53060c3d6 100644 --- a/src/lib/common/Settings.h +++ b/src/lib/common/Settings.h @@ -66,7 +66,7 @@ public: }; struct Daemon { - inline static const auto Command = QStringLiteral("daemon/command"); + inline static const auto ConfigFile = QStringLiteral("daemon/configFile"); inline static const auto Elevate = QStringLiteral("daemon/elevate"); inline static const auto LogFile = QStringLiteral("daemon/logFile"); inline static const auto LogLevel = QStringLiteral("daemon/logLevel"); @@ -225,7 +225,7 @@ private: , Settings::Core::UseHooks , Settings::Core::UseWlClipboard , Settings::Core::Language - , Settings::Daemon::Command + , Settings::Daemon::ConfigFile , Settings::Daemon::Elevate , Settings::Daemon::LogFile , Settings::Daemon::LogLevel diff --git a/src/lib/deskflow/ipc/DaemonIpcServer.cpp b/src/lib/deskflow/ipc/DaemonIpcServer.cpp index cd15de9af..e729c7739 100644 --- a/src/lib/deskflow/ipc/DaemonIpcServer.cpp +++ b/src/lib/deskflow/ipc/DaemonIpcServer.cpp @@ -27,10 +27,8 @@ void DaemonIpcServer::processCommand(QLocalSocket *clientSocket, const QString & { if (command == QStringLiteral("logLevel")) { processLogLevel(clientSocket, parts); - } else if (command == QStringLiteral("elevate")) { - processElevate(clientSocket, parts); - } else if (command == QStringLiteral("command")) { - processCommandMessage(clientSocket, parts); + } else if (command == QStringLiteral("configFile")) { + processConfigFile(clientSocket, parts); } else if (command == QStringLiteral("start")) { LOG_DEBUG("daemon ipc server got start message"); Q_EMIT startProcessRequested(); @@ -71,43 +69,23 @@ void DaemonIpcServer::processLogLevel(QLocalSocket *&clientSocket, const QString writeToClientSocket(clientSocket, kAckMessage); } -void DaemonIpcServer::processElevate(QLocalSocket *&clientSocket, const QStringList &messageParts) +void DaemonIpcServer::processConfigFile(QLocalSocket *&clientSocket, const QStringList &messageParts) { if (messageParts.size() < 2) { - LOG_ERR("daemon ipc server got invalid elevate message"); + LOG_ERR("daemon ipc server got invalid config file message"); writeToClientSocket(clientSocket, kErrorMessage); return; } - const auto &elevate = messageParts.at(1); - if (elevate != QStringLiteral("yes") && elevate != QStringLiteral("no")) { - LOG_ERR("daemon ipc server got invalid elevate value: %s", elevate.toUtf8().constData()); + const auto &configFile = messageParts.at(1); + if (configFile.isEmpty()) { + LOG_ERR("daemon ipc server got empty config file path"); writeToClientSocket(clientSocket, kErrorMessage); return; } - LOG_DEBUG("daemon ipc server got new elevate value: %s", elevate.toUtf8().constData()); - Q_EMIT elevateModeChanged(elevate == QStringLiteral("yes")); - writeToClientSocket(clientSocket, kAckMessage); -} - -void DaemonIpcServer::processCommandMessage(QLocalSocket *&clientSocket, const QStringList &messageParts) -{ - if (messageParts.size() < 2) { - LOG_ERR("daemon ipc server got invalid command message"); - writeToClientSocket(clientSocket, kErrorMessage); - return; - } - - const auto &command = messageParts.at(1); - if (command.isEmpty()) { - LOG_ERR("daemon ipc server got empty command"); - writeToClientSocket(clientSocket, kErrorMessage); - return; - } - - LOG_DEBUG("daemon ipc server got new command: %s", command.toUtf8().constData()); - Q_EMIT commandChanged(command); + LOG_DEBUG("daemon ipc server got config file: %s", configFile.toUtf8().constData()); + Q_EMIT configFileChanged(configFile); writeToClientSocket(clientSocket, kAckMessage); } diff --git a/src/lib/deskflow/ipc/DaemonIpcServer.h b/src/lib/deskflow/ipc/DaemonIpcServer.h index a4d205b5f..cf54a7659 100644 --- a/src/lib/deskflow/ipc/DaemonIpcServer.h +++ b/src/lib/deskflow/ipc/DaemonIpcServer.h @@ -25,8 +25,7 @@ public: private: void processCommand(QLocalSocket *clientSocket, const QString &command, const QStringList &parts) override; void processLogLevel(QLocalSocket *&clientSocket, const QStringList &messageParts); - void processElevate(QLocalSocket *&clientSocket, const QStringList &messageParts); - void processCommandMessage(QLocalSocket *&clientSocket, const QStringList &messageParts); + void processConfigFile(QLocalSocket *&clientSocket, const QStringList &messageParts); private: const QString m_logFilename; diff --git a/src/lib/deskflow/ipc/IpcServer.h b/src/lib/deskflow/ipc/IpcServer.h index e26000a69..a8c60dd69 100644 --- a/src/lib/deskflow/ipc/IpcServer.h +++ b/src/lib/deskflow/ipc/IpcServer.h @@ -27,8 +27,7 @@ public: Q_SIGNALS: void logLevelChanged(const QString &logLevel); - void elevateModeChanged(bool elevate); - void commandChanged(const QString &command); + void configFileChanged(const QString &configFile); void startProcessRequested(); void stopProcessRequested(); void clearSettingsRequested(); diff --git a/src/lib/gui/core/CoreProcess.cpp b/src/lib/gui/core/CoreProcess.cpp index ef634dfef..bd514a7ac 100644 --- a/src/lib/gui/core/CoreProcess.cpp +++ b/src/lib/gui/core/CoreProcess.cpp @@ -214,17 +214,18 @@ void CoreProcess::startForegroundProcess(const QStringList &args) } } -void CoreProcess::startProcessFromDaemon(const QStringList &args) +void CoreProcess::startProcessFromDaemon() { if (m_processState != ProcessState::Starting) { qFatal("core process must be in starting state"); } - QString commandQuoted = makeQuotedArgs(m_appPath, args); - qInfo("running command: %s", qPrintable(commandQuoted)); + const auto configFile = Settings::settingsFile(); + qInfo("sending start to daemon (config file: %s)", qPrintable(configFile)); - auto sendStart = [this, commandQuoted] { - m_daemonIpcClient->sendStartProcess(commandQuoted, Settings::value(Settings::Daemon::Elevate).toBool()); + auto sendStart = [this, configFile] { + m_daemonIpcClient->sendConfigFile(configFile); + m_daemonIpcClient->sendStartProcess(); setProcessState(ProcessState::Started); }; @@ -412,8 +413,7 @@ void CoreProcess::start(std::optional processModeOption) if (processMode == ProcessMode::Desktop) { startForegroundProcess(args); } else if (processMode == ProcessMode::Service) { - args.append({QStringLiteral("--settings"), Settings::settingsFile()}); - startProcessFromDaemon(args); + startProcessFromDaemon(); } m_lastProcessMode = processMode; diff --git a/src/lib/gui/core/CoreProcess.h b/src/lib/gui/core/CoreProcess.h index 71cebca01..4dc924d28 100644 --- a/src/lib/gui/core/CoreProcess.h +++ b/src/lib/gui/core/CoreProcess.h @@ -104,7 +104,7 @@ private Q_SLOTS: private: void startForegroundProcess(const QStringList &args); - void startProcessFromDaemon(const QStringList &args); + void startProcessFromDaemon(); void stopForegroundProcess() const; void stopProcessFromDaemon(); QPair persistServerConfig() const; diff --git a/src/lib/gui/ipc/DaemonIpcClient.cpp b/src/lib/gui/ipc/DaemonIpcClient.cpp index 82b345993..1d0f340c3 100644 --- a/src/lib/gui/ipc/DaemonIpcClient.cpp +++ b/src/lib/gui/ipc/DaemonIpcClient.cpp @@ -21,11 +21,13 @@ void DaemonIpcClient::sendLogLevel(const QString &logLevel) sendMessage(QStringLiteral("logLevel=%1").arg(logLevel)); } -void DaemonIpcClient::sendStartProcess(const QString &command, bool elevate) +void DaemonIpcClient::sendConfigFile(const QString &configFile) +{ + sendMessage(QStringLiteral("configFile=%1").arg(configFile)); +} + +void DaemonIpcClient::sendStartProcess() { - const auto elevateStr = elevate ? QStringLiteral("yes") : QStringLiteral("no"); - sendMessage(QStringLiteral("elevate=%1").arg(elevateStr)); - sendMessage(QStringLiteral("command=%1").arg(command)); sendMessage(QStringLiteral("start")); } diff --git a/src/lib/gui/ipc/DaemonIpcClient.h b/src/lib/gui/ipc/DaemonIpcClient.h index 9b72bfd48..357f639dc 100644 --- a/src/lib/gui/ipc/DaemonIpcClient.h +++ b/src/lib/gui/ipc/DaemonIpcClient.h @@ -19,7 +19,8 @@ class DaemonIpcClient : public IpcClient public: explicit DaemonIpcClient(QObject *parent = nullptr); void sendLogLevel(const QString &logLevel); - void sendStartProcess(const QString &command, bool elevate); + void sendConfigFile(const QString &configFile); + void sendStartProcess(); void sendStopProcess(); void sendClearSettings(); void requestLogPath();