deskflow/src/apps/deskflow-gui/deskflow-gui.cpp

172 lines
5.2 KiB
C++
Raw Normal View History

2012-06-10 16:50:54 +00:00
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithord48@gmail.com>
* SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2008 Volker Lanz <vl@fidra.de>
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
2012-06-10 16:50:54 +00:00
*/
#include "common/Constants.h"
#include "common/UrlConstants.h"
2025-03-28 21:58:30 +00:00
#include "gui/Diagnostic.h"
#include "gui/DotEnv.h"
Refactored core process management and IPC client (#7425) * Also ignore `command_pre` for Fedora itself * Improve warning message * Fixed layout issues on main window * Restore fusion theme for Windows dark mode * Further correct main window layout * Set CWD for launch on Windows to same dir as .env * Use signals for tray icon instead of callback * Reduce complexity for setting tray icon * Further reduce tray icon complexity * Reduce tray retry time * Fixed tray not showing on macOS * Refactor function names * Move tray icon to lib * Decouple server connection class * Move server connection to lib * Move client config to lib * Remove redundant forward declarations * Fixed some namespaces in the new lib * Move core process code to new class * Improve member names on new process class * Remove copy/pasta code * Move OSX helpers to lib * Add .mm to lib config * Fixed copyright * Improve reliability of log line handling * Fixed TLS certificate generate bugs * Remove client list * Refactor core process handling to fix various problems * Fixed process/connection status bugs * Fixed function signature issue on macOS * Fixed override warnings * Fixed string format warning * Save `wasStarted` state and use that instead * Use only filename in dialog * Use lambda for simple slot * Scroll to bottom if at bottome * Set value based on position before text added and set horizontal scroll too * Add 1px tollerance for Linux * Simplify start/stop mutex * Always stop service on restart * Increase scroll bottom threshold to 2 * Log warning instead of critical * Fixed long-standing dir CD-up hack * Remove include * Remove include * Fixed rogue dumbisense includes * Account for optional distro_like * Add QAction include to solve incomplete type * Remove rogue #pragma * Static cast log value * Solve event queue delete warning * Fixed integ test on Windows 10 * Reduce enum verbosity * Use static instance instead of global * Make function const * Use unique_ptr instead of new and delete, and made some functions const * Fixed smart pointer use * Fixed variable shadowing * Fixed wrong use of using * Fixed missing namespace using * Simplify TLS error handling * Improve UX around certificate errors and success * Decouple app config from core process through interface * First iteration of core process test * Mark dtor as override * Rename attach launch entry * Add TODO * Create proxy for process * Move IPC client to deps * Fixed warnings * Reorganize new GUI lib dir structure * Update includes to reflect new paths * Reorg GUI tests * Abstract IPC client * Refactor about screen * Fixed .ui warnings * Remove redundant include * Fixed typo * Fixed typos and add spelling * Fixed misleading function name * Improve comment * Improve code coverage for core process * Remove noisy log line * Make global const * Use default dtor * Use vector instead of new * Make ctor explicit * Make ctor explicit (2) * Use enum class * Fixed bad enum * Stub out core tool * Stub out dir operation * Extract byte functions * Add missing return path * Simplify byte/int functions * Fix truncation * Use ctor member assignment * Fixed segfault in process proxy * Fixed print warning * Make function const * Cleanup header * Fixed missing name * Update ChangeLog * Make more functions const
2024-08-07 14:05:18 +00:00
#include "gui/Logger.h"
2025-03-28 21:58:30 +00:00
#include "gui/MainWindow.h"
#include "gui/Messages.h"
2025-03-28 21:58:30 +00:00
#include "gui/StyleUtils.h"
#include <QApplication>
#include <QCommandLineParser>
#include <QLocalSocket>
#include <QMessageBox>
#include <QSharedMemory>
2012-06-10 16:50:54 +00:00
2014-01-24 17:53:03 +00:00
#if defined(Q_OS_MAC)
#include <Carbon/Carbon.h>
2017-05-10 14:25:21 +00:00
#include <cstdlib>
#endif
2024-12-16 15:52:34 +00:00
#if defined(Q_OS_UNIX) && defined(QT_DEBUG)
#include <QLoggingCategory>
#endif
using namespace deskflow::gui;
Implement safer memory use, improve dev env, fixed GUI bugs (#7407) * Improve dev script for daemon * Ignore `.user` files created by Qt * Add `FORCE_DESKTOP_PROCESS` option * Catch errors related to getting profile dir * Disable IPC entirely if forced desktop * Use in-class init for AppConfig members * Refactor config to use safer memory management * Improve launch config to make OS-specific debugger usage clearer * Re-enable MainWindowTests on Windows, further refactor for memory safety, fixed some include orders * Remove dead singleton code * Swap order of tests * Use HTTPs for URLs * Fixed compile errors for `SYNERGY_ENABLE_LICENSING` compile path * Restore exec function call * Remove extra link in cancel dialog * Fixed broken link on activation cancel UI * Close dialog if activated * Fixed macOS enum ref to kCurrentProcess * Improve wording on cancel activation dialog * WIP - Test timeout (compile error) * Finished timeout logic (with smart pointer) * Include string_view * Switch to thread from jthread (maybe not supported by macOS compiler?) * Improve comment * Disable test on Windows * Add TODO related to jthread on macOS * Refactor settings and paths on Windows * Launch in desktop mode on Windows * Remove arg quote wraps which break desktop mode * Fixed qFatal on Linux * Remove test value * Follow original `AppConfig` accessor convention * Disable service checkbox if not Windows * Simplify TLS control enable logic * Update command and Git ignore * Fixed code style * Fixed include consistency * Fixed includes in validator * Fixed lint errors * Update ChangeLog * Use smart pointer for core process * Remove unneccesary default operators * Don't halt on stderr
2024-07-22 16:48:02 +00:00
2014-01-24 17:53:03 +00:00
#if defined(Q_OS_MAC)
bool checkMacAssistiveDevices();
#endif
const static auto kHeader = QStringLiteral("%1: %2\n").arg(kAppName, kDisplayVersion);
int main(int argc, char *argv[])
{
2024-12-16 15:52:34 +00:00
#if defined(Q_OS_UNIX) && defined(QT_DEBUG)
// Fixes Fedora bug where qDebug() messages aren't printed.
QLoggingCategory::setFilterRules(QStringLiteral("*.debug=true\nqt.*=false"));
#endif
QCoreApplication::setApplicationName(kAppName);
QCoreApplication::setOrganizationName(kAppName);
QCoreApplication::setApplicationVersion(kVersion);
QCoreApplication::setOrganizationDomain(kOrgDomain); // used in prefix, can't be a url
QGuiApplication::setDesktopFileName(QStringLiteral("org.deskflow.deskflow"));
QApplication app(argc, argv);
// Add Command Line Options
auto helpOption = QCommandLineOption({"h", "help"}, "Display Help on the command line");
auto versionOption = QCommandLineOption({"v", "version"}, "Display version information");
auto resetOption = QCommandLineOption("reset", "Reset all settings");
QCommandLineParser parser;
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
parser.addOption(helpOption);
parser.addOption(versionOption);
parser.addOption(resetOption);
parser.parse(QCoreApplication::arguments());
if (!parser.errorText().isEmpty()) {
qCritical().noquote() << parser.errorText() << "\nUse --help for more information.";
return 1;
}
if (parser.isSet(helpOption)) {
QTextStream(stdout) << kHeader << QStringLiteral(" %1\n\n").arg(kAppDescription)
<< parser.helpText().replace(QApplication::applicationFilePath(), kAppId);
return 0;
}
if (parser.isSet(versionOption)) {
QTextStream(stdout) << kHeader << kCopyright << Qt::endl;
return 0;
}
// Create a shared memory segment with a unique key
// This is to prevent a new instance from running if one is already running
QSharedMemory sharedMemory("deskflow-gui");
// Attempt to attach first and detach in order to clean up stale shm chunks
// This can happen if the previous instance was killed or crashed
if (sharedMemory.attach())
sharedMemory.detach();
// If we can create 1 byte of SHM we are the only instance
if (!sharedMemory.create(1)) {
// Ping the running instance to have it show itself
QLocalSocket socket;
socket.connectToServer("deskflow-gui", QLocalSocket::ReadOnly);
if (!socket.waitForConnected()) {
// If we can't connect to the other instance tell the user its running.
// This should never happen but just incase we should show something
QMessageBox::information(nullptr, QObject::tr("Deskflow"), QObject::tr("Deskflow is already running"));
}
socket.disconnectFromServer();
return 0;
}
#if !defined(Q_OS_MAC)
// causes dark mode to be used on some DE's
if (qEnvironmentVariable("XDG_CURRENT_DESKTOP") != QLatin1String("KDE")) {
QApplication::setStyle("fusion");
}
#endif
// Sets the fallback icon path
setIconFallbackPaths();
qInstallMessageHandler(deskflow::gui::messages::messageHandler);
qInfo("%s v%s", kAppName, qPrintable(kVersion));
dotenv();
Refactored core process management and IPC client (#7425) * Also ignore `command_pre` for Fedora itself * Improve warning message * Fixed layout issues on main window * Restore fusion theme for Windows dark mode * Further correct main window layout * Set CWD for launch on Windows to same dir as .env * Use signals for tray icon instead of callback * Reduce complexity for setting tray icon * Further reduce tray icon complexity * Reduce tray retry time * Fixed tray not showing on macOS * Refactor function names * Move tray icon to lib * Decouple server connection class * Move server connection to lib * Move client config to lib * Remove redundant forward declarations * Fixed some namespaces in the new lib * Move core process code to new class * Improve member names on new process class * Remove copy/pasta code * Move OSX helpers to lib * Add .mm to lib config * Fixed copyright * Improve reliability of log line handling * Fixed TLS certificate generate bugs * Remove client list * Refactor core process handling to fix various problems * Fixed process/connection status bugs * Fixed function signature issue on macOS * Fixed override warnings * Fixed string format warning * Save `wasStarted` state and use that instead * Use only filename in dialog * Use lambda for simple slot * Scroll to bottom if at bottome * Set value based on position before text added and set horizontal scroll too * Add 1px tollerance for Linux * Simplify start/stop mutex * Always stop service on restart * Increase scroll bottom threshold to 2 * Log warning instead of critical * Fixed long-standing dir CD-up hack * Remove include * Remove include * Fixed rogue dumbisense includes * Account for optional distro_like * Add QAction include to solve incomplete type * Remove rogue #pragma * Static cast log value * Solve event queue delete warning * Fixed integ test on Windows 10 * Reduce enum verbosity * Use static instance instead of global * Make function const * Use unique_ptr instead of new and delete, and made some functions const * Fixed smart pointer use * Fixed variable shadowing * Fixed wrong use of using * Fixed missing namespace using * Simplify TLS error handling * Improve UX around certificate errors and success * Decouple app config from core process through interface * First iteration of core process test * Mark dtor as override * Rename attach launch entry * Add TODO * Create proxy for process * Move IPC client to deps * Fixed warnings * Reorganize new GUI lib dir structure * Update includes to reflect new paths * Reorg GUI tests * Abstract IPC client * Refactor about screen * Fixed .ui warnings * Remove redundant include * Fixed typo * Fixed typos and add spelling * Fixed misleading function name * Improve comment * Improve code coverage for core process * Remove noisy log line * Make global const * Use default dtor * Use vector instead of new * Make ctor explicit * Make ctor explicit (2) * Use enum class * Fixed bad enum * Stub out core tool * Stub out dir operation * Extract byte functions * Add missing return path * Simplify byte/int functions * Fix truncation * Use ctor member assignment * Fixed segfault in process proxy * Fixed print warning * Make function const * Cleanup header * Fixed missing name * Update ChangeLog * Make more functions const
2024-08-07 14:05:18 +00:00
Logger::instance().loadEnvVars();
2014-01-24 17:53:03 +00:00
#if defined(Q_OS_MAC)
if (app.applicationDirPath().startsWith("/Volumes/")) {
QString msgBody = QStringLiteral(
"Please drag %1 to the Applications folder, "
"and open it from there."
);
QMessageBox::information(nullptr, kAppName, msgBody.arg(kAppName));
return 1;
}
if (!checkMacAssistiveDevices()) {
return 1;
}
2014-01-24 17:53:03 +00:00
#endif
// --no-reset
if (parser.isSet(resetOption)) {
diagnostic::clearSettings(false);
}
MainWindow mainWindow;
mainWindow.open();
return QApplication::exec();
2012-06-10 16:50:54 +00:00
}
2014-01-24 17:53:03 +00:00
#if defined(Q_OS_MAC)
bool checkMacAssistiveDevices()
{
// new in mavericks, applications are trusted individually
// with use of the accessibility api. this call will show a
// prompt which can show the security/privacy/accessibility
// tab, with a list of allowed applications. deskflow should
// show up there automatically, but will be unchecked.
2014-01-24 17:53:03 +00:00
if (AXIsProcessTrusted()) {
return true;
}
const void *keys[] = {kAXTrustedCheckOptionPrompt};
const void *trueValue[] = {kCFBooleanTrue};
CFDictionaryRef options = CFDictionaryCreate(nullptr, keys, trueValue, 1, nullptr, nullptr);
2014-01-24 17:53:03 +00:00
bool result = AXIsProcessTrustedWithOptions(options);
CFRelease(options);
return result;
2014-01-24 17:53:03 +00:00
}
#endif