diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index 69142d1d..9f659738 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -55,7 +55,7 @@ AppConfig::AppConfig(QSettings* settings) : m_WizardLastRun(0), m_ProcessMode(DEFAULT_PROCESS_MODE), m_AutoConfig(true), - m_ElevateMode(false), + m_ElevateMode(defaultElevateMode), m_AutoConfigPrompted(false), m_CryptoEnabled(false), m_AutoHide(false), @@ -126,7 +126,12 @@ void AppConfig::loadSettings() m_Language = settings().value("language", QLocale::system().name()).toString(); m_StartedBefore = settings().value("startedBefore", false).toBool(); m_AutoConfig = settings().value("autoConfig", true).toBool(); - m_ElevateMode = settings().value("elevateMode", false).toBool(); + QVariant elevateMode = settings().value("elevateModeEnum"); + if (!elevateMode.isValid()) { + elevateMode = settings().value ("elevateMode", + QVariant(static_cast(defaultElevateMode))); + } + m_ElevateMode = static_cast(elevateMode.toInt()); m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool(); m_Edition = settings().value("edition", Unknown).toInt(); m_ActivateEmail = settings().value("activateEmail", "").toString(); @@ -148,7 +153,10 @@ void AppConfig::saveSettings() settings().setValue("language", m_Language); settings().setValue("startedBefore", m_StartedBefore); settings().setValue("autoConfig", m_AutoConfig); - settings().setValue("elevateMode", m_ElevateMode); + // Refer to enum ElevateMode declaration for insight in to why this + // flag is mapped this way + settings().setValue("elevateMode", m_ElevateMode == ElevateAlways); + settings().setValue("elevateModeEnum", static_cast(m_ElevateMode)); settings().setValue("autoConfigPrompted", m_AutoConfigPrompted); settings().setValue("edition", m_Edition); settings().setValue("activateEmail", m_ActivateEmail); @@ -168,7 +176,7 @@ void AppConfig::setAutoConfigPrompted(bool prompted) m_AutoConfigPrompted = prompted; } -bool AppConfig::elevateMode() +ElevateMode AppConfig::elevateMode() { return m_ElevateMode; } diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h index dfcb477a..dcd5a482 100644 --- a/src/gui/src/AppConfig.h +++ b/src/gui/src/AppConfig.h @@ -46,6 +46,29 @@ enum ProcessMode { Desktop }; +// The elevate mode tristate determines two behaviours on Windows. +// The first, switch-on-desk-switch (SodS), passed through synergyd as a +// command line argument to synergy core, determines if the server restarts +// when switching Windows desktops (e.g. when Windows UAC dialog pops up). +// The second, passed as a boolean flag to Synergyd over the IPC inside +// kIpcCommandMessage, determines whether Synergy should be started with +// elevated privileges. +// +// The matrix for these two behaviours is as follows: +// SodS Elevate +// ___________________________ +// ElevateAsNeeded | true | false +// ElevateAlways | false | true +// ElevateNever | false | false +// +enum ElevateMode { + ElevateAsNeeded = 0, + ElevateAlways = 1, + ElevateNever = 2 +}; + +static const ElevateMode defaultElevateMode = ElevateAsNeeded; + class AppConfig { friend class SettingsDialog; @@ -89,7 +112,7 @@ class AppConfig bool detectPath(const QString& name, QString& path); void persistLogDir(); - bool elevateMode(); + ElevateMode elevateMode(); void setCryptoEnabled(bool e) { m_CryptoEnabled = e; } bool getCryptoEnabled() { return m_CryptoEnabled; } @@ -109,7 +132,7 @@ class AppConfig void setWizardHasRun() { m_WizardLastRun = kWizardVersion; } void setLanguage(const QString language) { m_Language = language; } void setStartedBefore(bool b) { m_StartedBefore = b; } - void setElevateMode(bool b) { m_ElevateMode = b; } + void setElevateMode(ElevateMode em) { m_ElevateMode = em; } void loadSettings(); @@ -126,7 +149,7 @@ class AppConfig QString m_Language; bool m_StartedBefore; bool m_AutoConfig; - bool m_ElevateMode; + ElevateMode m_ElevateMode; bool m_AutoConfigPrompted; int m_Edition; QString m_ActivateEmail; diff --git a/src/gui/src/IpcClient.cpp b/src/gui/src/IpcClient.cpp index 397ebdc5..728a800c 100644 --- a/src/gui/src/IpcClient.cpp +++ b/src/gui/src/IpcClient.cpp @@ -98,7 +98,7 @@ void IpcClient::sendHello() stream.writeRawData(typeBuf, 1); } -void IpcClient::sendCommand(const QString& command, bool elevate) +void IpcClient::sendCommand(const QString& command, ElevateMode const elevate) { QDataStream stream(m_Socket); @@ -114,7 +114,8 @@ void IpcClient::sendCommand(const QString& command, bool elevate) stream.writeRawData(charCommand, length); char elevateBuf[1]; - elevateBuf[0] = elevate ? 1 : 0; + // Refer to enum ElevateMode documentation for why this flag is mapped this way + elevateBuf[0] = (elevate == ElevateAlways) ? 1 : 0; stream.writeRawData(elevateBuf, 1); } diff --git a/src/gui/src/IpcClient.h b/src/gui/src/IpcClient.h index b1cd224e..439211bd 100644 --- a/src/gui/src/IpcClient.h +++ b/src/gui/src/IpcClient.h @@ -21,6 +21,8 @@ #include #include +#include "AppConfig.h" + class QTcpSocket; class IpcReader; @@ -33,7 +35,7 @@ public: virtual ~IpcClient(); void sendHello(); - void sendCommand(const QString& command, bool elevate); + void sendCommand(const QString& command, ElevateMode elevate); void connectToHost(); void disconnectFromHost(); diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 727f2dfb..b28a46ed 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -536,7 +536,14 @@ void MainWindow::startSynergy() // is switched; this is because we may need to elevate or not // based on which desk the user is in (login always needs // elevation, where as default desk does not). - args << "--stop-on-desk-switch"; + // Note that this is only enabled when synergy is set to elevate + // 'as needed' (e.g. on a UAC dialog popup) in order to prevent + // unnecessary restarts when synergy was started elevated or + // when it is not allowed to elevate. In these cases restarting + // the server is fruitless. + if (appConfig().elevateMode() == ElevateAsNeeded) { + args << "--stop-on-desk-switch"; + } #endif } diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp index fbe81f2a..f3deebba 100644 --- a/src/gui/src/SettingsDialog.cpp +++ b/src/gui/src/SettingsDialog.cpp @@ -36,8 +36,7 @@ static const char networkSecurity[] = "ns"; SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), Ui::SettingsDialogBase(), - m_AppConfig(config), - m_SuppressElevateWarning(false) + m_AppConfig(config) { setupUi(this); @@ -53,14 +52,13 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : m_pCheckBoxAutoHide->setChecked(appConfig().getAutoHide()); #if defined(Q_OS_WIN) - m_SuppressElevateWarning = true; - m_pCheckBoxElevateMode->setChecked(appConfig().elevateMode()); - m_SuppressElevateWarning = false; + m_pComboElevate->setCurrentIndex(static_cast(appConfig().elevateMode())); m_pCheckBoxAutoHide->hide(); #else // elevate checkbox is only useful on ms windows. - m_pCheckBoxElevateMode->hide(); + m_pLabelElevate->hide(); + m_pComboElevate->hide(); #endif if (!PluginManager::exist(networkSecurity)) { @@ -81,7 +79,7 @@ void SettingsDialog::accept() appConfig().setLogToFile(m_pCheckBoxLogToFile->isChecked()); appConfig().setLogFilename(m_pLineEditLogFilename->text()); appConfig().setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString()); - appConfig().setElevateMode(m_pCheckBoxElevateMode->isChecked()); + appConfig().setElevateMode(static_cast(m_pComboElevate->currentIndex())); appConfig().setAutoHide(m_pCheckBoxAutoHide->isChecked()); appConfig().saveSettings(); QDialog::accept(); @@ -147,24 +145,6 @@ void SettingsDialog::on_m_pComboLanguage_currentIndexChanged(int index) QSynergyApplication::getInstance()->switchTranslator(ietfCode); } -void SettingsDialog::on_m_pCheckBoxElevateMode_toggled(bool checked) -{ - if (checked && !m_SuppressElevateWarning) { - int r = QMessageBox::warning( - this, tr("Elevate Synergy"), - tr("Are you sure you want to elevate Synergy?\n\n" - "This allows Synergy to interact with elevated processes " - "and the UAC dialog, but can cause problems with non-elevated " - "processes. Elevate Synergy only if you really need to."), - QMessageBox::Yes | QMessageBox::No); - - if (r != QMessageBox::Yes) { - m_pCheckBoxElevateMode->setChecked(false); - return; - } - } -} - void SettingsDialog::on_m_pCheckBoxEnableCrypto_toggled(bool checked) { m_AppConfig.setCryptoEnabled(checked); diff --git a/src/gui/src/SettingsDialog.h b/src/gui/src/SettingsDialog.h index 8ab2e1e0..ea30ac32 100644 --- a/src/gui/src/SettingsDialog.h +++ b/src/gui/src/SettingsDialog.h @@ -46,11 +46,9 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase AppConfig& m_AppConfig; SynergyLocale m_Locale; CoreInterface m_CoreInterface; - bool m_SuppressElevateWarning; private slots: void on_m_pCheckBoxEnableCrypto_toggled(bool checked); - void on_m_pCheckBoxElevateMode_toggled(bool checked); void on_m_pComboLanguage_currentIndexChanged(int index); void on_m_pCheckBoxLogToFile_stateChanged(int ); void on_m_pButtonBrowseLog_clicked();