#4323 Implement Elevate tristrate in GUI

This commit is contained in:
Andrew Nelless 2016-06-07 17:20:22 +01:00
parent 3cd58f7c7d
commit 9c26c7ea94
7 changed files with 57 additions and 38 deletions

View File

@ -55,7 +55,7 @@ AppConfig::AppConfig(QSettings* settings) :
m_WizardLastRun(0), m_WizardLastRun(0),
m_ProcessMode(DEFAULT_PROCESS_MODE), m_ProcessMode(DEFAULT_PROCESS_MODE),
m_AutoConfig(true), m_AutoConfig(true),
m_ElevateMode(false), m_ElevateMode(defaultElevateMode),
m_AutoConfigPrompted(false), m_AutoConfigPrompted(false),
m_CryptoEnabled(false), m_CryptoEnabled(false),
m_AutoHide(false), m_AutoHide(false),
@ -126,7 +126,12 @@ void AppConfig::loadSettings()
m_Language = settings().value("language", QLocale::system().name()).toString(); m_Language = settings().value("language", QLocale::system().name()).toString();
m_StartedBefore = settings().value("startedBefore", false).toBool(); m_StartedBefore = settings().value("startedBefore", false).toBool();
m_AutoConfig = settings().value("autoConfig", true).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<int>(defaultElevateMode)));
}
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool(); m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool();
m_Edition = settings().value("edition", Unknown).toInt(); m_Edition = settings().value("edition", Unknown).toInt();
m_ActivateEmail = settings().value("activateEmail", "").toString(); m_ActivateEmail = settings().value("activateEmail", "").toString();
@ -148,7 +153,10 @@ void AppConfig::saveSettings()
settings().setValue("language", m_Language); settings().setValue("language", m_Language);
settings().setValue("startedBefore", m_StartedBefore); settings().setValue("startedBefore", m_StartedBefore);
settings().setValue("autoConfig", m_AutoConfig); 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<int>(m_ElevateMode));
settings().setValue("autoConfigPrompted", m_AutoConfigPrompted); settings().setValue("autoConfigPrompted", m_AutoConfigPrompted);
settings().setValue("edition", m_Edition); settings().setValue("edition", m_Edition);
settings().setValue("activateEmail", m_ActivateEmail); settings().setValue("activateEmail", m_ActivateEmail);
@ -168,7 +176,7 @@ void AppConfig::setAutoConfigPrompted(bool prompted)
m_AutoConfigPrompted = prompted; m_AutoConfigPrompted = prompted;
} }
bool AppConfig::elevateMode() ElevateMode AppConfig::elevateMode()
{ {
return m_ElevateMode; return m_ElevateMode;
} }

View File

@ -46,6 +46,29 @@ enum ProcessMode {
Desktop 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 class AppConfig
{ {
friend class SettingsDialog; friend class SettingsDialog;
@ -89,7 +112,7 @@ class AppConfig
bool detectPath(const QString& name, QString& path); bool detectPath(const QString& name, QString& path);
void persistLogDir(); void persistLogDir();
bool elevateMode(); ElevateMode elevateMode();
void setCryptoEnabled(bool e) { m_CryptoEnabled = e; } void setCryptoEnabled(bool e) { m_CryptoEnabled = e; }
bool getCryptoEnabled() { return m_CryptoEnabled; } bool getCryptoEnabled() { return m_CryptoEnabled; }
@ -109,7 +132,7 @@ class AppConfig
void setWizardHasRun() { m_WizardLastRun = kWizardVersion; } void setWizardHasRun() { m_WizardLastRun = kWizardVersion; }
void setLanguage(const QString language) { m_Language = language; } void setLanguage(const QString language) { m_Language = language; }
void setStartedBefore(bool b) { m_StartedBefore = b; } void setStartedBefore(bool b) { m_StartedBefore = b; }
void setElevateMode(bool b) { m_ElevateMode = b; } void setElevateMode(ElevateMode em) { m_ElevateMode = em; }
void loadSettings(); void loadSettings();
@ -126,7 +149,7 @@ class AppConfig
QString m_Language; QString m_Language;
bool m_StartedBefore; bool m_StartedBefore;
bool m_AutoConfig; bool m_AutoConfig;
bool m_ElevateMode; ElevateMode m_ElevateMode;
bool m_AutoConfigPrompted; bool m_AutoConfigPrompted;
int m_Edition; int m_Edition;
QString m_ActivateEmail; QString m_ActivateEmail;

View File

@ -98,7 +98,7 @@ void IpcClient::sendHello()
stream.writeRawData(typeBuf, 1); 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); QDataStream stream(m_Socket);
@ -114,7 +114,8 @@ void IpcClient::sendCommand(const QString& command, bool elevate)
stream.writeRawData(charCommand, length); stream.writeRawData(charCommand, length);
char elevateBuf[1]; 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); stream.writeRawData(elevateBuf, 1);
} }

View File

@ -21,6 +21,8 @@
#include <QObject> #include <QObject>
#include <QAbstractSocket> #include <QAbstractSocket>
#include "AppConfig.h"
class QTcpSocket; class QTcpSocket;
class IpcReader; class IpcReader;
@ -33,7 +35,7 @@ public:
virtual ~IpcClient(); virtual ~IpcClient();
void sendHello(); void sendHello();
void sendCommand(const QString& command, bool elevate); void sendCommand(const QString& command, ElevateMode elevate);
void connectToHost(); void connectToHost();
void disconnectFromHost(); void disconnectFromHost();

View File

@ -536,7 +536,14 @@ void MainWindow::startSynergy()
// is switched; this is because we may need to elevate or not // is switched; this is because we may need to elevate or not
// based on which desk the user is in (login always needs // based on which desk the user is in (login always needs
// elevation, where as default desk does not). // elevation, where as default desk does not).
// 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"; args << "--stop-on-desk-switch";
}
#endif #endif
} }

View File

@ -36,8 +36,7 @@ static const char networkSecurity[] = "ns";
SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
Ui::SettingsDialogBase(), Ui::SettingsDialogBase(),
m_AppConfig(config), m_AppConfig(config)
m_SuppressElevateWarning(false)
{ {
setupUi(this); setupUi(this);
@ -53,14 +52,13 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
m_pCheckBoxAutoHide->setChecked(appConfig().getAutoHide()); m_pCheckBoxAutoHide->setChecked(appConfig().getAutoHide());
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
m_SuppressElevateWarning = true; m_pComboElevate->setCurrentIndex(static_cast<int>(appConfig().elevateMode()));
m_pCheckBoxElevateMode->setChecked(appConfig().elevateMode());
m_SuppressElevateWarning = false;
m_pCheckBoxAutoHide->hide(); m_pCheckBoxAutoHide->hide();
#else #else
// elevate checkbox is only useful on ms windows. // elevate checkbox is only useful on ms windows.
m_pCheckBoxElevateMode->hide(); m_pLabelElevate->hide();
m_pComboElevate->hide();
#endif #endif
if (!PluginManager::exist(networkSecurity)) { if (!PluginManager::exist(networkSecurity)) {
@ -81,7 +79,7 @@ void SettingsDialog::accept()
appConfig().setLogToFile(m_pCheckBoxLogToFile->isChecked()); appConfig().setLogToFile(m_pCheckBoxLogToFile->isChecked());
appConfig().setLogFilename(m_pLineEditLogFilename->text()); appConfig().setLogFilename(m_pLineEditLogFilename->text());
appConfig().setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString()); appConfig().setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString());
appConfig().setElevateMode(m_pCheckBoxElevateMode->isChecked()); appConfig().setElevateMode(static_cast<ElevateMode>(m_pComboElevate->currentIndex()));
appConfig().setAutoHide(m_pCheckBoxAutoHide->isChecked()); appConfig().setAutoHide(m_pCheckBoxAutoHide->isChecked());
appConfig().saveSettings(); appConfig().saveSettings();
QDialog::accept(); QDialog::accept();
@ -147,24 +145,6 @@ void SettingsDialog::on_m_pComboLanguage_currentIndexChanged(int index)
QSynergyApplication::getInstance()->switchTranslator(ietfCode); 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) void SettingsDialog::on_m_pCheckBoxEnableCrypto_toggled(bool checked)
{ {
m_AppConfig.setCryptoEnabled(checked); m_AppConfig.setCryptoEnabled(checked);

View File

@ -46,11 +46,9 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
AppConfig& m_AppConfig; AppConfig& m_AppConfig;
SynergyLocale m_Locale; SynergyLocale m_Locale;
CoreInterface m_CoreInterface; CoreInterface m_CoreInterface;
bool m_SuppressElevateWarning;
private slots: private slots:
void on_m_pCheckBoxEnableCrypto_toggled(bool checked); void on_m_pCheckBoxEnableCrypto_toggled(bool checked);
void on_m_pCheckBoxElevateMode_toggled(bool checked);
void on_m_pComboLanguage_currentIndexChanged(int index); void on_m_pComboLanguage_currentIndexChanged(int index);
void on_m_pCheckBoxLogToFile_stateChanged(int ); void on_m_pCheckBoxLogToFile_stateChanged(int );
void on_m_pButtonBrowseLog_clicked(); void on_m_pButtonBrowseLog_clicked();