Show message box explaining why settings are read-only (#7437)
* Swap assert for warning log lines * Flush on IPC write * Flush on cleanup instead of write * Record core started setting * Show server first start message * Show message when active scope is read-only * Show read only message on change * Show read only on window show * Try to improve main window size policy * Revert addition of resizer * Remove redundant file path fiddling * Remove dead code and fixed missing const * Print path and use queued connection * Improve read-only message on Windows * Only show toggle warning when dialog visible * Update ChangeLog * Fixed include
This commit is contained in:
parent
30ea95fb3d
commit
9464aa46b8
25 changed files with 277 additions and 106 deletions
|
|
@ -79,6 +79,7 @@ Enhancements:
|
|||
- #7434 Show dark logo in dark mode and improve .env loader
|
||||
- #7435 Add reset settings menu action and env var
|
||||
- #7436 Introduced new env vars for testing
|
||||
- #7437 Show message box explaining why settings are read-only
|
||||
|
||||
# 1.14.6
|
||||
|
||||
|
|
|
|||
|
|
@ -799,7 +799,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
|||
qDebug("window should hide to tray");
|
||||
}
|
||||
|
||||
void MainWindow::showFirstRunMessage() {
|
||||
void MainWindow::showFirstConnectedMessage() {
|
||||
if (m_AppConfig.startedBefore()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -808,7 +808,7 @@ void MainWindow::showFirstRunMessage() {
|
|||
m_ConfigScopes.save();
|
||||
|
||||
const auto isServer = m_CoreProcess.mode() == CoreMode::Server;
|
||||
messages::showFirstRunMessage(
|
||||
messages::showFirstConnectedMessage(
|
||||
this, m_AppConfig.closeToTray(), m_AppConfig.enableService(), isServer);
|
||||
}
|
||||
|
||||
|
|
@ -887,10 +887,14 @@ void MainWindow::updateStatus() {
|
|||
}
|
||||
|
||||
void MainWindow::onCoreProcessStateChanged(CoreProcessState state) {
|
||||
qDebug("core process state changed: %d", static_cast<int>(state));
|
||||
|
||||
updateStatus();
|
||||
|
||||
if (state == CoreProcessState::Started) {
|
||||
qDebug("recording that core has started");
|
||||
m_AppConfig.setStartedBefore(true);
|
||||
m_ConfigScopes.save();
|
||||
}
|
||||
|
||||
if (state == CoreProcessState::Started ||
|
||||
state == CoreProcessState::Starting) {
|
||||
disconnect(
|
||||
|
|
@ -933,7 +937,7 @@ void MainWindow::onCoreConnectionStateChanged(CoreConnectionState state) {
|
|||
if (state != CoreConnectionState::Connected) {
|
||||
secureSocket(false);
|
||||
} else if (isVisible()) {
|
||||
showFirstRunMessage();
|
||||
showFirstConnectedMessage();
|
||||
showDevThanksMessage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1127,12 +1131,21 @@ void MainWindow::enableServer(bool enable) {
|
|||
m_AppConfig.setServerGroupChecked(enable);
|
||||
m_pRadioGroupServer->setChecked(enable);
|
||||
m_pWidgetServer->setEnabled(enable);
|
||||
m_pWidgetServerInverse->setVisible(m_AppConfig.invertConnection());
|
||||
m_pWidgetServerInput->setVisible(m_AppConfig.invertConnection());
|
||||
|
||||
if (enable) {
|
||||
m_pButtonToggleStart->setEnabled(true);
|
||||
m_pActionStartCore->setEnabled(true);
|
||||
m_CoreProcess.setMode(CoreProcess::Mode::Server);
|
||||
|
||||
// The server can run without any clients configured, and this is actually
|
||||
// what you'll want to do the first time since you'll be prompted when an
|
||||
// unrecognized client tries to connect.
|
||||
if (!m_AppConfig.startedBefore()) {
|
||||
qDebug("auto-starting core server for first time");
|
||||
m_CoreProcess.start();
|
||||
messages::showFirstServerStartMessage(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1140,8 +1153,8 @@ void MainWindow::enableClient(bool enable) {
|
|||
qDebug(enable ? "client enabled" : "client disabled");
|
||||
m_AppConfig.setClientGroupChecked(enable);
|
||||
m_pRadioGroupClient->setChecked(enable);
|
||||
m_pWidgetClient->setEnabled(enable);
|
||||
m_pWidgetClient->setVisible(!m_AppConfig.invertConnection());
|
||||
m_pWidgetClientInput->setEnabled(enable);
|
||||
m_pWidgetClientInput->setVisible(!m_AppConfig.invertConnection());
|
||||
|
||||
if (enable) {
|
||||
m_pButtonToggleStart->setEnabled(true);
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ private:
|
|||
void setupControls();
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void moveEvent(QMoveEvent *event) override;
|
||||
void showFirstRunMessage();
|
||||
void showFirstConnectedMessage();
|
||||
void showDevThanksMessage();
|
||||
QString productName() const;
|
||||
void updateStatus();
|
||||
|
|
|
|||
|
|
@ -110,29 +110,49 @@
|
|||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetServerRadio" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_pRadioGroupServer">
|
||||
<property name="text">
|
||||
<string>Use this computer's keyboard and mouse</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>(make this computer the server)</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_pRadioGroupServer">
|
||||
<property name="text">
|
||||
<string>Use this computer's keyboard and mouse</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>(make this computer the server)</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetServer" native="true">
|
||||
|
|
@ -153,7 +173,7 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_pWidgetServerInverse" native="true">
|
||||
<widget class="QWidget" name="m_pWidgetServerInput" native="true">
|
||||
<layout class="QVBoxLayout" name="m_pLayoutServerInverse">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
|
|
@ -231,7 +251,7 @@
|
|||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
|
|
@ -278,32 +298,52 @@
|
|||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetClientRadio" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_pRadioGroupClient">
|
||||
<property name="text">
|
||||
<string>Use another computer’s mouse and keyboard</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>(make this computer the client)</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_pRadioGroupClient">
|
||||
<property name="text">
|
||||
<string>Use another computer’s mouse and keyboard</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>(make this computer the client)</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetClient" native="true">
|
||||
<widget class="QWidget" name="m_pWidgetClientInput" native="true">
|
||||
<layout class="QVBoxLayout" name="m_pLayoutClient">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
|
|
@ -378,7 +418,7 @@
|
|||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
|
|
|
|||
|
|
@ -50,8 +50,6 @@ public:
|
|||
static void msleep(unsigned long msecs) { QThread::msleep(msecs); }
|
||||
};
|
||||
|
||||
QString getSystemSettingPath();
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
bool checkMacAssistiveDevices();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include <QByteArray>
|
||||
#include <QDataStream>
|
||||
#include <QIODevice>
|
||||
#include <qlogging.h>
|
||||
#include <QtGlobal>
|
||||
|
||||
namespace synergy::gui {
|
||||
|
||||
|
|
|
|||
|
|
@ -394,6 +394,8 @@ void AppConfig::loadScope(ConfigScopes::Scope scope) {
|
|||
|
||||
m_Scopes.setActiveScope(scope);
|
||||
|
||||
qDebug("active scope file path: %s", qPrintable(m_Scopes.activeFilePath()));
|
||||
|
||||
// only signal ready if there is at least one setting in the required scope.
|
||||
// this prevents the current settings from being set back to default.
|
||||
if (m_Scopes.scopeContains(
|
||||
|
|
@ -443,7 +445,7 @@ void AppConfig::persistLogDir() const {
|
|||
// Begin getters
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IConfigScopes &AppConfig::scopes() { return m_Scopes; }
|
||||
IConfigScopes &AppConfig::scopes() const { return m_Scopes; }
|
||||
|
||||
bool AppConfig::activationHasRun() const { return m_ActivationHasRun; }
|
||||
|
||||
|
|
|
|||
|
|
@ -126,7 +126,6 @@ public:
|
|||
IConfigScopes &scopes,
|
||||
std::shared_ptr<Deps> deps = std::make_shared<Deps>());
|
||||
|
||||
IConfigScopes &scopes();
|
||||
void determineScope();
|
||||
|
||||
/**
|
||||
|
|
@ -139,6 +138,7 @@ public:
|
|||
// Getters (overrides)
|
||||
//
|
||||
|
||||
IConfigScopes &scopes() const override;
|
||||
ProcessMode processMode() const override;
|
||||
ElevateMode elevateMode() const override;
|
||||
bool tlsEnabled() const override;
|
||||
|
|
@ -189,6 +189,7 @@ public:
|
|||
//
|
||||
// Setters (overrides)
|
||||
//
|
||||
|
||||
void setScreenName(const QString &s) override;
|
||||
void setPort(int i) override;
|
||||
void setNetworkInterface(const QString &s) override;
|
||||
|
|
@ -211,9 +212,9 @@ public:
|
|||
// Setters (new methods)
|
||||
//
|
||||
|
||||
void setStartedBefore(bool b);
|
||||
void setActivationHasRun(bool value);
|
||||
void setWizardHasRun();
|
||||
void setStartedBefore(bool b);
|
||||
void setSerialKey(const QString &serialKey);
|
||||
void clearSerialKey();
|
||||
void setLicenseNextCheck(unsigned long long);
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public:
|
|||
Scope activeScope() const override;
|
||||
QSettingsProxy &activeSettings() override;
|
||||
const QSettingsProxy &activeSettings() const override;
|
||||
QString activeFilePath() const;
|
||||
QString activeFilePath() const override;
|
||||
|
||||
signals:
|
||||
void ready();
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "ElevateMode.h"
|
||||
|
||||
#include "gui/config/IConfigScopes.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace synergy::gui {
|
||||
|
|
@ -26,13 +28,16 @@ namespace synergy::gui {
|
|||
enum class ProcessMode { kService, kDesktop };
|
||||
|
||||
class IAppConfig {
|
||||
using IConfigScopes = synergy::gui::IConfigScopes;
|
||||
|
||||
public:
|
||||
virtual ~IAppConfig() = default;
|
||||
|
||||
//
|
||||
// Setters
|
||||
// Getters
|
||||
//
|
||||
|
||||
virtual IConfigScopes &scopes() const = 0;
|
||||
virtual QString tlsCertPath() const = 0;
|
||||
virtual int tlsKeyLength() const = 0;
|
||||
virtual bool tlsEnabled() const = 0;
|
||||
|
|
@ -64,7 +69,7 @@ public:
|
|||
virtual bool clientGroupChecked() const = 0;
|
||||
|
||||
//
|
||||
// Getters
|
||||
// Setters
|
||||
//
|
||||
|
||||
virtual void setLoadFromSystemScope(bool loadFromSystemScope) = 0;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public:
|
|||
virtual bool isActiveScopeWritable() const = 0;
|
||||
virtual QSettingsProxy &activeSettings() = 0;
|
||||
virtual const QSettingsProxy &activeSettings() const = 0;
|
||||
virtual QString activeFilePath() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Signals to listeners that the settings that they should read.
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <QRegularExpression>
|
||||
#include <QStandardPaths>
|
||||
#include <QTimer>
|
||||
#include <QtGlobal>
|
||||
|
||||
using namespace synergy::license;
|
||||
using namespace synergy::gui::license;
|
||||
|
|
@ -59,7 +60,25 @@ QString processModeToString(ProcessMode mode) {
|
|||
return "service";
|
||||
default:
|
||||
qFatal("invalid process mode");
|
||||
return "";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
QString processStateToString(CoreProcess::ProcessState state) {
|
||||
using enum CoreProcess::ProcessState;
|
||||
|
||||
switch (state) {
|
||||
case Starting:
|
||||
return "starting";
|
||||
case Started:
|
||||
return "started";
|
||||
case Stopping:
|
||||
return "stopping";
|
||||
case Stopped:
|
||||
return "stopped";
|
||||
default:
|
||||
qFatal("invalid process state");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,8 +158,8 @@ QString CoreProcess::Deps::getProfileRoot() const {
|
|||
//
|
||||
|
||||
CoreProcess::CoreProcess(
|
||||
IAppConfig &appConfig, IServerConfig &serverConfig, const ILicense &license,
|
||||
std::shared_ptr<Deps> deps)
|
||||
const IAppConfig &appConfig, const IServerConfig &serverConfig,
|
||||
const ILicense &license, std::shared_ptr<Deps> deps)
|
||||
: m_appConfig(appConfig),
|
||||
m_serverConfig(serverConfig),
|
||||
m_license(license),
|
||||
|
|
@ -175,7 +194,9 @@ void CoreProcess::onIpcClientServiceReady() {
|
|||
qDebug("service ready, continuing core process stop");
|
||||
stop();
|
||||
} else {
|
||||
qCritical("service ready, but process state is not starting or stopping");
|
||||
// This may happen when the IPC connection fails and then reconnects.
|
||||
qWarning(
|
||||
"ignoring service ready, process state is not starting or stopping");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -644,6 +665,10 @@ void CoreProcess::setProcessState(ProcessState state) {
|
|||
return;
|
||||
}
|
||||
|
||||
qDebug(
|
||||
"core process state changed: %s -> %s", //
|
||||
qPrintable(processStateToString(m_processState)),
|
||||
qPrintable(processStateToString(state)));
|
||||
m_processState = state;
|
||||
emit processStateChanged(state);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public:
|
|||
enum class ConnectionState { Disconnected, Connecting, Connected, Listening };
|
||||
|
||||
explicit CoreProcess(
|
||||
IAppConfig &appConfig, IServerConfig &serverConfig,
|
||||
const IAppConfig &appConfig, const IServerConfig &serverConfig,
|
||||
const ILicense &license,
|
||||
std::shared_ptr<Deps> deps = std::make_shared<Deps>());
|
||||
|
||||
|
|
@ -119,8 +119,8 @@ private:
|
|||
void checkOSXNotification(const QString &line);
|
||||
#endif
|
||||
|
||||
IAppConfig &m_appConfig;
|
||||
IServerConfig &m_serverConfig;
|
||||
const IAppConfig &m_appConfig;
|
||||
const IServerConfig &m_serverConfig;
|
||||
const ILicense &m_license;
|
||||
std::shared_ptr<Deps> m_pDeps;
|
||||
QString m_address;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "UpgradeDialog.h"
|
||||
#include "gui/core/CoreProcess.h"
|
||||
#include "gui/license/license_config.h"
|
||||
#include "gui/messages.h"
|
||||
#include "gui/tls/TlsCertificate.h"
|
||||
#include "gui/tls/TlsUtility.h"
|
||||
#include "gui/validators/ScreenNameValidator.h"
|
||||
|
|
@ -61,6 +62,15 @@ SettingsDialog::SettingsDialog(
|
|||
m_pScreenNameError = new validators::ValidationError(this);
|
||||
m_pLineEditScreenName->setValidator(new validators::ScreenNameValidator(
|
||||
m_pLineEditScreenName, m_pScreenNameError, &serverConfig.screens()));
|
||||
|
||||
connect(
|
||||
this, &SettingsDialog::shown, this,
|
||||
[this] {
|
||||
if (!m_appConfig.isActiveScopeWritable()) {
|
||||
showReadOnlyMessage();
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -107,6 +117,10 @@ void SettingsDialog::on_m_pRadioSystemScope_toggled(bool checked) {
|
|||
m_appConfig.setLoadFromSystemScope(checked);
|
||||
loadFromConfig();
|
||||
updateControls();
|
||||
|
||||
if (isVisible() && !m_appConfig.isActiveScopeWritable()) {
|
||||
showReadOnlyMessage();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::on_m_pPushButtonTlsCertPath_clicked() {
|
||||
|
|
@ -147,6 +161,16 @@ void SettingsDialog::on_m_pCheckBoxServiceEnabled_toggled(bool) {
|
|||
// End of auto-connect slots
|
||||
//
|
||||
|
||||
void SettingsDialog::showEvent(QShowEvent *event) {
|
||||
QDialog::showEvent(event);
|
||||
emit shown();
|
||||
}
|
||||
|
||||
void SettingsDialog::showReadOnlyMessage() {
|
||||
const auto activeScopeFilename = m_appConfig.scopes().activeFilePath();
|
||||
messages::showReadOnlySettings(this, activeScopeFilename);
|
||||
}
|
||||
|
||||
void SettingsDialog::accept() {
|
||||
if (!m_pLineEditScreenName->hasAcceptableInput()) {
|
||||
QMessageBox::warning(
|
||||
|
|
@ -228,6 +252,7 @@ void SettingsDialog::updateTlsControls() {
|
|||
const auto tlsEnabled = m_tlsUtility.isAvailableAndEnabled();
|
||||
const auto writable = m_appConfig.isActiveScopeWritable();
|
||||
|
||||
m_pCheckBoxEnableTls->setEnabled(writable);
|
||||
m_pCheckBoxEnableTls->setChecked(writable && tlsEnabled);
|
||||
m_pLineEditTlsCertPath->setText(m_appConfig.tlsCertPath());
|
||||
|
||||
|
|
|
|||
|
|
@ -39,10 +39,14 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void extracted();
|
||||
SettingsDialog(
|
||||
QWidget *parent, IAppConfig &appConfig, const IServerConfig &serverConfig,
|
||||
const License &license, const CoreProcess &coreProcess);
|
||||
|
||||
signals:
|
||||
void shown();
|
||||
|
||||
private slots:
|
||||
void on_m_pCheckBoxEnableTls_clicked(bool checked);
|
||||
void on_m_pCheckBoxLogToFile_stateChanged(int);
|
||||
|
|
@ -56,6 +60,11 @@ private slots:
|
|||
private:
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
void showEvent(QShowEvent *event) override;
|
||||
bool isClientMode() const;
|
||||
void updateTlsControls();
|
||||
void updateTlsControlsEnabled();
|
||||
void showReadOnlyMessage();
|
||||
|
||||
/// @brief Load all settings.
|
||||
void loadFromConfig();
|
||||
|
|
@ -69,10 +78,6 @@ private:
|
|||
/// @brief Enables controls when they should be.
|
||||
void updateControls();
|
||||
|
||||
bool isClientMode() const;
|
||||
void updateTlsControls();
|
||||
void updateTlsControlsEnabled();
|
||||
|
||||
[[no_unique_address]] CoreTool m_coreTool;
|
||||
validators::ValidationError *m_pScreenNameError;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,8 @@
|
|||
class QDataStreamProxy {
|
||||
public:
|
||||
explicit QDataStreamProxy() = default;
|
||||
explicit QDataStreamProxy(QTcpSocket *socket) {
|
||||
m_Stream = std::make_unique<QDataStream>(socket);
|
||||
}
|
||||
explicit QDataStreamProxy(QTcpSocket *socket)
|
||||
: m_Stream(std::make_unique<QDataStream>(socket)) {}
|
||||
virtual ~QDataStreamProxy() = default;
|
||||
|
||||
virtual qint64 writeRawData(const char *data, int len) {
|
||||
|
|
|
|||
|
|
@ -79,14 +79,17 @@ void QIpcClient::connectToHost() {
|
|||
}
|
||||
|
||||
void QIpcClient::disconnectFromHost() {
|
||||
m_isConnecting = false;
|
||||
qInfo("disconnected from background service");
|
||||
m_pReader->stop();
|
||||
m_pSocket->flush();
|
||||
m_pSocket->close();
|
||||
|
||||
m_isConnecting = false;
|
||||
m_isConnected = false;
|
||||
|
||||
qInfo("disconnected from background service");
|
||||
}
|
||||
|
||||
void QIpcClient::onSocketError(QAbstractSocket::SocketError socketError) const {
|
||||
void QIpcClient::onSocketError(QAbstractSocket::SocketError socketError) {
|
||||
QString text;
|
||||
switch (socketError) {
|
||||
case 0:
|
||||
|
|
@ -101,6 +104,7 @@ void QIpcClient::onSocketError(QAbstractSocket::SocketError socketError) const {
|
|||
}
|
||||
|
||||
qWarning("ipc connection error, %s", qUtf8Printable(text));
|
||||
m_isConnected = false;
|
||||
|
||||
QTimer::singleShot(kRetryInterval, this, &QIpcClient::onRetryConnect);
|
||||
}
|
||||
|
|
@ -154,6 +158,12 @@ void QIpcClient::sendCommand(
|
|||
|
||||
void QIpcClient::onIpcReaderHelloBack() {
|
||||
qDebug("ipc hello back received");
|
||||
|
||||
if (m_isConnected) {
|
||||
qWarning("ipc already connected, ignoring hello back");
|
||||
return;
|
||||
}
|
||||
|
||||
m_isConnected = true;
|
||||
serviceReady();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ private slots:
|
|||
void onRetryConnect();
|
||||
void onSocketConnected() const;
|
||||
void onIpcReaderHelloBack();
|
||||
void onSocketError(QAbstractSocket::SocketError error) const;
|
||||
void onSocketError(QAbstractSocket::SocketError error);
|
||||
void onIpcReaderRead(const QString &text);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -149,7 +149,16 @@ void showCloseReminder(QWidget *parent) {
|
|||
QMessageBox::information(parent, "Notification area icon", message);
|
||||
}
|
||||
|
||||
void showFirstRunMessage(
|
||||
void showFirstServerStartMessage(QWidget *parent) {
|
||||
QMessageBox::information(
|
||||
parent, "Server is running",
|
||||
"<p>Great, the server is now running.</p>"
|
||||
"<p>Now you can connect your other computers to this server. "
|
||||
"You should see a prompt here on the server when a new client tries to "
|
||||
"connect.</p>");
|
||||
}
|
||||
|
||||
void showFirstConnectedMessage(
|
||||
QWidget *parent, bool closeToTray, bool enableService, bool isServer) {
|
||||
|
||||
auto message = QString("<p>Synergy is now connected!</p>");
|
||||
|
|
@ -265,4 +274,13 @@ bool showClearSettings(QWidget *parent) {
|
|||
return message.clickedButton() == clear;
|
||||
}
|
||||
|
||||
void showReadOnlySettings(QWidget *parent, const QString &systemSettingsPath) {
|
||||
QString nativePath = QDir::toNativeSeparators(systemSettingsPath);
|
||||
QMessageBox::information(
|
||||
parent, "Read-only settings",
|
||||
QString("<p>Settings are read-only because you only have read access "
|
||||
"to the file:</p><p>%1</p>")
|
||||
.arg(nativePath));
|
||||
}
|
||||
|
||||
} // namespace synergy::gui::messages
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ void messageHandler(
|
|||
|
||||
void raiseCriticalDialog();
|
||||
|
||||
void showFirstRunMessage(
|
||||
void showFirstServerStartMessage(QWidget *parent);
|
||||
|
||||
void showFirstConnectedMessage(
|
||||
QWidget *parent, bool closeToTray, bool enableService, bool isServer);
|
||||
|
||||
void showCloseReminder(QWidget *parent);
|
||||
|
|
@ -48,4 +50,6 @@ showNewClientPrompt(QWidget *parent, const QString &clientName);
|
|||
|
||||
bool showClearSettings(QWidget *parent);
|
||||
|
||||
void showReadOnlySettings(QWidget *parent, const QString &systemSettingsPath);
|
||||
|
||||
} // namespace synergy::gui::messages
|
||||
|
|
|
|||
|
|
@ -29,26 +29,29 @@
|
|||
namespace synergy::gui::proxy {
|
||||
|
||||
const auto kLegacyOrgDomain = "http-symless-com";
|
||||
|
||||
const auto kSystemConfigFilename = "SystemConfig.ini";
|
||||
const auto kLegacySystemConfigFilename = "SystemConfig.ini";
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
const auto kUnixSystemConfigPath = "/usr/local/etc/symless/";
|
||||
const auto kUnixSystemConfigPath = "/usr/local/etc/";
|
||||
#endif
|
||||
|
||||
//
|
||||
// Free functions
|
||||
//
|
||||
|
||||
QString getSystemSettingPath() {
|
||||
const QString settingFilename(kSystemConfigFilename);
|
||||
/**
|
||||
* @brief The base dir for the system settings file.
|
||||
*
|
||||
* Important: Qt will append the org name as a dir, and the app name as the
|
||||
* settings filename, i.e.: `{base-dir}/Synergy/Synergy.ini`
|
||||
*/
|
||||
QString getSystemSettingsBaseDir() {
|
||||
#if defined(Q_OS_WIN)
|
||||
return QCoreApplication::applicationDirPath() + QDir::separator();
|
||||
#elif defined(Q_OS_MAC)
|
||||
// it would be nice to use /Library dir, but qt has no elevate system.
|
||||
return kUnixSystemConfigPath + settingFilename;
|
||||
#elif defined(Q_OS_LINUX)
|
||||
// qt already adds application and filename to the end of the path on linux.
|
||||
return QCoreApplication::applicationDirPath();
|
||||
#elif defined(Q_OS_UNIX)
|
||||
// Qt already adds application and filename to the end of the path.
|
||||
// On macOS, it would be nice to use /Library dir, but qt has no elevate
|
||||
// system.
|
||||
return kUnixSystemConfigPath;
|
||||
#else
|
||||
#error "unsupported platform"
|
||||
|
|
@ -62,7 +65,8 @@ void migrateLegacySystemSettings(QSettings &settings) {
|
|||
}
|
||||
|
||||
QSettings::setPath(
|
||||
QSettings::IniFormat, QSettings::SystemScope, kSystemConfigFilename);
|
||||
QSettings::IniFormat, QSettings::SystemScope,
|
||||
kLegacySystemConfigFilename);
|
||||
QSettings oldSystemSettings(
|
||||
QSettings::IniFormat, QSettings::SystemScope,
|
||||
QCoreApplication::organizationName(),
|
||||
|
|
@ -75,7 +79,7 @@ void migrateLegacySystemSettings(QSettings &settings) {
|
|||
}
|
||||
|
||||
QSettings::setPath(
|
||||
QSettings::IniFormat, QSettings::SystemScope, getSystemSettingPath());
|
||||
QSettings::IniFormat, QSettings::SystemScope, getSystemSettingsBaseDir());
|
||||
}
|
||||
|
||||
void migrateLegacyUserSettings(QSettings &newSettings) {
|
||||
|
|
@ -151,7 +155,7 @@ void QSettingsProxy::loadSystem() {
|
|||
|
||||
QSettings::setPath(
|
||||
QSettings::Format::IniFormat, QSettings::Scope::SystemScope,
|
||||
getSystemSettingPath());
|
||||
getSystemSettingsBaseDir());
|
||||
|
||||
m_pSettings = std::make_unique<QSettings>(
|
||||
QSettings::Format::IniFormat, QSettings::Scope::SystemScope, orgName,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace synergy::gui::proxy {
|
||||
|
||||
QString getSystemSettingPath();
|
||||
QString getSystemSettingBaseDir();
|
||||
|
||||
class QSettingsProxy {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -57,9 +57,27 @@ Screen::~Screen() {
|
|||
}
|
||||
assert(!m_enabled);
|
||||
|
||||
// TODO: why assert this? it appears to be false when an elevated dialog
|
||||
// appears on windows and the process is killed.
|
||||
assert(m_entered == m_isPrimary);
|
||||
// Originally there was an assert here added before 2009 (history not in
|
||||
// tact). This condition seems to occur on a Windows client when the process
|
||||
// is shut down to make way for a new elevated process (e.g. at login screen).
|
||||
// The reason why this assert was originally added is unclear, and was causing
|
||||
// pain when using debug builds; you lose control of the client when it's at
|
||||
// the login screen. Therefore it has been converted to a warning so that we
|
||||
// can still see when it happens but it won't cause the process to pause. This
|
||||
// also gives us the added benefit of seeing when it happens in production.
|
||||
// Perhaps it indicates that the cursor is still being controlled on the
|
||||
// client while it's shutting down? i.e. the screen is entered and is not the
|
||||
// server, or the screen is not entered and is the server.
|
||||
if (m_entered == m_isPrimary) {
|
||||
LOG(
|
||||
(CLOG_DEBUG "current screen: entered=%s, primary=%s", //
|
||||
m_entered ? "yes" : "no", m_isPrimary ? "yes" : "no"));
|
||||
if (m_isPrimary) {
|
||||
LOG((CLOG_WARN "current primary screen is not entered on shutdown"));
|
||||
} else {
|
||||
LOG((CLOG_WARN "current secondary screen is entered on shutdown"));
|
||||
}
|
||||
}
|
||||
|
||||
delete m_screen;
|
||||
LOG((CLOG_DEBUG "closed display"));
|
||||
|
|
|
|||
|
|
@ -39,9 +39,10 @@ public:
|
|||
}
|
||||
|
||||
//
|
||||
// Setters
|
||||
// Getters
|
||||
//
|
||||
|
||||
MOCK_METHOD(synergy::gui::IConfigScopes &, scopes, (), (const, override));
|
||||
MOCK_METHOD(QString, tlsCertPath, (), (const, override));
|
||||
MOCK_METHOD(int, tlsKeyLength, (), (const, override));
|
||||
MOCK_METHOD(bool, tlsEnabled, (), (const, override));
|
||||
|
|
@ -73,7 +74,7 @@ public:
|
|||
MOCK_METHOD(bool, clientGroupChecked, (), (const, override));
|
||||
|
||||
//
|
||||
// Getters
|
||||
// Setters
|
||||
//
|
||||
|
||||
MOCK_METHOD(
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
MOCK_METHOD(const QSettingsProxy &, activeSettings, (), (const, override));
|
||||
MOCK_METHOD(QSettingsProxy &, activeSettings, (), (override));
|
||||
MOCK_METHOD(void, save, (bool), (override));
|
||||
MOCK_METHOD(QString, activeFilePath, (), (const, override));
|
||||
};
|
||||
|
||||
struct DepsMock : public AppConfig::Deps {
|
||||
|
|
|
|||
Loading…
Reference in a new issue