feat: Option to change server protocol in GUI

This commit is contained in:
Nick Bolton 2024-10-18 16:13:13 +01:00
parent 512faeea28
commit a5cd0fab9e
14 changed files with 623 additions and 448 deletions

View file

@ -72,15 +72,26 @@ bool ServerConfig::save(const QString &fileName) const
bool ServerConfig::operator==(const ServerConfig &sc) const bool ServerConfig::operator==(const ServerConfig &sc) const
{ {
return m_Screens == sc.m_Screens && m_Columns == sc.m_Columns && m_Rows == sc.m_Rows && return m_Screens == sc.m_Screens && //
m_HasHeartbeat == sc.m_HasHeartbeat && m_Heartbeat == sc.m_Heartbeat && m_Columns == sc.m_Columns && //
m_RelativeMouseMoves == sc.m_RelativeMouseMoves && m_Win32KeepForeground == sc.m_Win32KeepForeground && m_Rows == sc.m_Rows && //
m_HasSwitchDelay == sc.m_HasSwitchDelay && m_SwitchDelay == sc.m_SwitchDelay && m_HasHeartbeat == sc.m_HasHeartbeat && //
m_HasSwitchDoubleTap == sc.m_HasSwitchDoubleTap && m_SwitchDoubleTap == sc.m_SwitchDoubleTap && m_Heartbeat == sc.m_Heartbeat && //
m_SwitchCornerSize == sc.m_SwitchCornerSize && m_SwitchCorners == sc.m_SwitchCorners && m_Protocol == sc.m_Protocol && //
m_Hotkeys == sc.m_Hotkeys && m_pAppConfig == sc.m_pAppConfig && m_RelativeMouseMoves == sc.m_RelativeMouseMoves && //
m_EnableDragAndDrop == sc.m_EnableDragAndDrop && m_DisableLockToScreen == sc.m_DisableLockToScreen && m_Win32KeepForeground == sc.m_Win32KeepForeground && //
m_ClipboardSharing == sc.m_ClipboardSharing && m_ClipboardSharingSize == sc.m_ClipboardSharingSize && m_HasSwitchDelay == sc.m_HasSwitchDelay && //
m_SwitchDelay == sc.m_SwitchDelay && //
m_HasSwitchDoubleTap == sc.m_HasSwitchDoubleTap && //
m_SwitchDoubleTap == sc.m_SwitchDoubleTap && //
m_SwitchCornerSize == sc.m_SwitchCornerSize && //
m_SwitchCorners == sc.m_SwitchCorners && //
m_Hotkeys == sc.m_Hotkeys && //
m_pAppConfig == sc.m_pAppConfig && //
m_EnableDragAndDrop == sc.m_EnableDragAndDrop && //
m_DisableLockToScreen == sc.m_DisableLockToScreen && //
m_ClipboardSharing == sc.m_ClipboardSharing && //
m_ClipboardSharingSize == sc.m_ClipboardSharingSize && //
m_pMainWindow == sc.m_pMainWindow; m_pMainWindow == sc.m_pMainWindow;
} }
@ -118,6 +129,7 @@ void ServerConfig::commit()
settings().setValue("hasHeartbeat", hasHeartbeat()); settings().setValue("hasHeartbeat", hasHeartbeat());
settings().setValue("heartbeat", heartbeat()); settings().setValue("heartbeat", heartbeat());
settings().setValue("protocol", static_cast<int>(protocol()));
settings().setValue("relativeMouseMoves", relativeMouseMoves()); settings().setValue("relativeMouseMoves", relativeMouseMoves());
settings().setValue("win32KeepForeground", win32KeepForeground()); settings().setValue("win32KeepForeground", win32KeepForeground());
settings().setValue("hasSwitchDelay", hasSwitchDelay()); settings().setValue("hasSwitchDelay", hasSwitchDelay());
@ -172,6 +184,7 @@ void ServerConfig::recall()
haveHeartbeat(settings().value("hasHeartbeat", false).toBool()); haveHeartbeat(settings().value("hasHeartbeat", false).toBool());
setHeartbeat(settings().value("heartbeat", 5000).toInt()); setHeartbeat(settings().value("heartbeat", 5000).toInt());
setProtocol(static_cast<ServerProtocol>(settings().value("protocol", static_cast<int>(protocol())).toInt()));
setRelativeMouseMoves(settings().value("relativeMouseMoves", false).toBool()); setRelativeMouseMoves(settings().value("relativeMouseMoves", false).toBool());
setWin32KeepForeground(settings().value("win32KeepForeground", false).toBool()); setWin32KeepForeground(settings().value("win32KeepForeground", false).toBool());
haveSwitchDelay(settings().value("hasSwitchDelay", false).toBool()); haveSwitchDelay(settings().value("hasSwitchDelay", false).toBool());
@ -232,6 +245,8 @@ int ServerConfig::adjacentScreenIndex(int idx, int deltaColumn, int deltaRow) co
QTextStream &operator<<(QTextStream &outStream, const ServerConfig &config) QTextStream &operator<<(QTextStream &outStream, const ServerConfig &config)
{ {
using enum synergy::gui::ServerProtocol;
outStream << "section: screens" << Qt::endl; outStream << "section: screens" << Qt::endl;
foreach (const Screen &s, config.screens()) foreach (const Screen &s, config.screens())
@ -266,8 +281,15 @@ QTextStream &operator<<(QTextStream &outStream, const ServerConfig &config)
outStream << "section: options" << Qt::endl; outStream << "section: options" << Qt::endl;
if (config.hasHeartbeat()) if (config.hasHeartbeat())
outStream << "\t" outStream << "\t" << "heartbeat = " << config.heartbeat() << Qt::endl;
<< "heartbeat = " << config.heartbeat() << Qt::endl;
if (config.protocol() == kSynergy) {
outStream << "\t" << "protocol = synergy" << Qt::endl;
} else if (config.protocol() == kBarrier) {
outStream << "\t" << "protocol = barrier" << Qt::endl;
} else {
qFatal("unrecognized protocol when writing config");
}
outStream << "\t" outStream << "\t"
<< "relativeMouseMoves = " << (config.relativeMouseMoves() ? "true" : "false") << Qt::endl; << "relativeMouseMoves = " << (config.relativeMouseMoves() ? "true" : "false") << Qt::endl;

View file

@ -36,9 +36,25 @@ class ServerConfigDialog;
class MainWindow; class MainWindow;
class AppConfig; class AppConfig;
namespace synergy::gui {
enum class ServerProtocol
{
kSynergy,
kBarrier
};
// The default protocol was decided by a community vote.
// TODO: Remove this link when the vote concludes:
// https://github.com/deskflow/deskflow/discussions/7742
const auto kDefaultProtocol = ServerProtocol::kSynergy;
} // namespace synergy::gui
class ServerConfig : public ScreenConfig, public deskflow::gui::IServerConfig class ServerConfig : public ScreenConfig, public deskflow::gui::IServerConfig
{ {
using QSettingsProxy = deskflow::gui::proxy::QSettingsProxy; using QSettingsProxy = deskflow::gui::proxy::QSettingsProxy;
using ServerProtocol = synergy::gui::ServerProtocol;
friend class ServerConfigDialog; friend class ServerConfigDialog;
friend QTextStream &operator<<(QTextStream &outStream, const ServerConfig &config); friend QTextStream &operator<<(QTextStream &outStream, const ServerConfig &config);
@ -80,6 +96,10 @@ public:
{ {
return m_Heartbeat; return m_Heartbeat;
} }
ServerProtocol protocol() const
{
return m_Protocol;
}
bool relativeMouseMoves() const bool relativeMouseMoves() const
{ {
return m_RelativeMouseMoves; return m_RelativeMouseMoves;
@ -188,6 +208,10 @@ private:
{ {
m_Heartbeat = val; m_Heartbeat = val;
} }
void setProtocol(ServerProtocol val)
{
m_Protocol = val;
}
void setRelativeMouseMoves(bool on) void setRelativeMouseMoves(bool on)
{ {
m_RelativeMouseMoves = on; m_RelativeMouseMoves = on;
@ -252,6 +276,7 @@ private:
private: private:
bool m_HasHeartbeat = false; bool m_HasHeartbeat = false;
int m_Heartbeat = 0; int m_Heartbeat = 0;
ServerProtocol m_Protocol = synergy::gui::kDefaultProtocol;
bool m_RelativeMouseMoves = false; bool m_RelativeMouseMoves = false;
bool m_Win32KeepForeground = false; bool m_Win32KeepForeground = false;
bool m_HasSwitchDelay = false; bool m_HasSwitchDelay = false;

View file

@ -30,6 +30,7 @@
#include <QtGui> #include <QtGui>
using enum ScreenConfig::SwitchCorner; using enum ScreenConfig::SwitchCorner;
using ServerProtocol = synergy::gui::ServerProtocol;
ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, AppConfig &appConfig) ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, AppConfig &appConfig)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
@ -51,6 +52,8 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, Ap
ui->m_pEditConfigFile->setText(serverConfig().configFile()); ui->m_pEditConfigFile->setText(serverConfig().configFile());
ui->m_pCheckBoxUseExternalConfig->setChecked(serverConfig().useExternalConfig()); ui->m_pCheckBoxUseExternalConfig->setChecked(serverConfig().useExternalConfig());
ui->m_pCheckBoxHeartbeat->setChecked(serverConfig().hasHeartbeat()); ui->m_pCheckBoxHeartbeat->setChecked(serverConfig().hasHeartbeat());
ui->m_pRadioProtocolSynergy->setChecked(serverConfig().protocol() == ServerProtocol::kSynergy);
ui->m_pRadioProtocolBarrier->setChecked(serverConfig().protocol() == ServerProtocol::kBarrier);
ui->m_pSpinBoxHeartbeat->setValue(serverConfig().heartbeat()); ui->m_pSpinBoxHeartbeat->setValue(serverConfig().heartbeat());
ui->m_pCheckBoxRelativeMouseMoves->setChecked(serverConfig().relativeMouseMoves()); ui->m_pCheckBoxRelativeMouseMoves->setChecked(serverConfig().relativeMouseMoves());
@ -99,6 +102,8 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, Ap
// computers // computers
connect(&m_ScreenSetupModel, &ScreenSetupModel::screensChanged, this, &ServerConfigDialog::onChange); connect(&m_ScreenSetupModel, &ScreenSetupModel::screensChanged, this, &ServerConfigDialog::onChange);
// Above Qt 6.7 the checkbox signal signature has changed from int to Qt::CheckState
#if QT_VERSION <= QT_VERSION_CHECK(6, 7, 0) #if QT_VERSION <= QT_VERSION_CHECK(6, 7, 0)
// advanced // advanced
connect(ui->m_pCheckBoxSwitchDelay, &QCheckBox::stateChanged, this, [this](const int &v) { connect(ui->m_pCheckBoxSwitchDelay, &QCheckBox::stateChanged, this, [this](const int &v) {
@ -237,6 +242,18 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, Ap
onChange(); onChange();
} }
); );
connect(ui->m_pRadioProtocolSynergy, &QRadioButton::toggled, this, [this](const bool &v) {
if (v) {
serverConfig().setProtocol(ServerProtocol::kSynergy);
onChange();
}
});
connect(ui->m_pRadioProtocolBarrier, &QRadioButton::toggled, this, [this](const bool &v) {
if (v) {
serverConfig().setProtocol(ServerProtocol::kBarrier);
onChange();
}
});
connect(ui->m_pEditConfigFile, &QLineEdit::textChanged, this, [this]() { connect(ui->m_pEditConfigFile, &QLineEdit::textChanged, this, [this]() {
serverConfig().setConfigFile(ui->m_pEditConfigFile->text()); serverConfig().setConfigFile(ui->m_pEditConfigFile->text());

View file

@ -29,7 +29,7 @@
</size> </size>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>3</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="m_pTabScreens"> <widget class="QWidget" name="m_pTabScreens">
<attribute name="title"> <attribute name="title">
@ -49,7 +49,7 @@
<number>5</number> <number>5</number>
</property> </property>
<item> <item>
<layout class="QHBoxLayout"> <layout class="QHBoxLayout" name="m_pLayoutScreens">
<property name="spacing"> <property name="spacing">
<number>6</number> <number>6</number>
</property> </property>
@ -130,7 +130,7 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="m_pLayoutAddComputer">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
@ -334,25 +334,376 @@
<attribute name="title"> <attribute name="title">
<string>Advanced</string> <string>Advanced</string>
</attribute> </attribute>
<layout class="QGridLayout"> <layout class="QGridLayout" name="m_pGridCorners">
<property name="leftMargin"> <item row="0" column="1">
<number>9</number> <widget class="QGroupBox" name="m_pGroupCorners">
<property name="font">
<font>
<kerning>true</kerning>
</font>
</property> </property>
<property name="rightMargin"> <property name="title">
<number>9</number> <string>&amp;Dead corners (for this computer)</string>
</property> </property>
<item row="1" column="0"> <property name="checked">
<layout class="QVBoxLayout" name="verticalLayout_21"> <bool>false</bool>
<property name="spacing">
<number>0</number>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>6</number>
</property> </property>
<property name="bottomMargin"> <item>
<layout class="QGridLayout" name="m_pLayoutCorners">
<item row="1" column="0">
<widget class="QCheckBox" name="m_pCheckBoxCornerBottomLeft">
<property name="text">
<string>&amp;Bottom-left</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="m_pCheckBoxCornerTopLeft">
<property name="text">
<string>To&amp;p-left</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="m_pCheckBoxCornerBottomRight">
<property name="text">
<string>Bottom-ri&amp;ght</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="m_pCheckBoxCornerTopRight">
<property name="text">
<string>Top-rig&amp;ht</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="m_pLayoutCornerSize">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Cor&amp;ner size</string>
</property>
<property name="buddy">
<cstring>m_pSpinBoxSwitchCornerSize</cstring>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="m_pSpinBoxSwitchCornerSize">
<property name="maximum">
<number>30000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>px</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_7">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="m_pGroupOptions">
<property name="font">
<font>
<kerning>false</kerning>
</font>
</property>
<property name="title">
<string>&amp;Misc</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QCheckBox" name="m_pCheckBoxDisableLockToScreen">
<property name="text">
<string>Disable lock to screen (scroll lock key)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_pCheckBoxRelativeMouseMoves">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Use &amp;relative mouse movements</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_pCheckBoxWin32KeepForeground">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Don't take &amp;foreground window (Windows only)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="m_pLayoutClipboard">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="m_pCheckBoxEnableClipboard">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable clipboard sharing</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Limit:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_pSpinBoxClipboardSizeLimit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>MB</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="m_pGroupNetwork">
<property name="title">
<string>&amp;Network</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<number>9</number>
</property>
<property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QCheckBox" name="m_pCheckBoxHeartbeat">
<property name="enabled">
<bool>true</bool>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enables the network heartbeat to ping clients every &lt;span style=&quot; font-style:italic;&quot;&gt;n&lt;/span&gt; seconds. This may help to diagnose network problems by retrying the connection if the client becomes unresponsive.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>&amp;Check clients every</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="m_pSpinBoxHeartbeat">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>1000</number>
</property>
<property name="maximum">
<number>30000</number>
</property>
<property name="singleStep">
<number>1000</number>
</property>
<property name="value">
<number>5000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_pLabel_16">
<property name="text">
<string>ms</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="m_pLabelProtocol">
<property name="whatsThis">
<string>&lt;p&gt;Enables compatibility with programs that use either the Synergy or Barrier protocols:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deskflow uses the Synergy protocol.&lt;/li&gt;
&lt;li&gt;Input Leap uses the Barrier protocol.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A Deskflow client will automatically use either the Synergy or Barrier protocol depending on the server protocol.&lt;/p&gt;</string>
</property>
<property name="text">
<string>Network protocol</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="m_pRadioProtocolSynergy">
<property name="text">
<string>&amp;Synergy</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_pRadioProtocolBarrier">
<property name="text">
<string>&amp;Barrier</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="m_pGroupSwitch"> <widget class="QGroupBox" name="m_pGroupSwitch">
<property name="font"> <property name="font">
<font> <font>
@ -360,7 +711,7 @@
</font> </font>
</property> </property>
<property name="title"> <property name="title">
<string>&amp;Switch computer</string> <string>&amp;Switching</string>
</property> </property>
<layout class="QVBoxLayout"> <layout class="QVBoxLayout">
<property name="spacing"> <property name="spacing">
@ -478,104 +829,15 @@
</item> </item>
</layout> </layout>
</item> </item>
</layout>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer_41"> <spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="font">
<font>
<kerning>true</kerning>
</font>
</property>
<property name="title">
<string>Clipboard sharing</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="topMargin">
<number>6</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="m_pCheckBoxEnableClipboard">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable clipboard sharing</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="m_pSpinBoxClipboardSizeLimit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>mb</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>60</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@ -583,10 +845,8 @@
</layout> </layout>
</widget> </widget>
</item> </item>
</layout> <item row="2" column="0">
</item> <spacer name="verticalSpacer_2">
<item row="5" column="0">
<spacer>
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -598,237 +858,6 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="4" column="0" colspan="3">
<widget class="QGroupBox" name="m_pGroupSwitchCorners">
<property name="font">
<font>
<kerning>true</kerning>
</font>
</property>
<property name="title">
<string>&amp;Dead corners for this computer</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QGridLayout">
<property name="topMargin">
<number>6</number>
</property>
<item row="1" column="0" colspan="3">
<widget class="QCheckBox" name="m_pCheckBoxCornerTopLeft">
<property name="text">
<string>To&amp;p-left</string>
</property>
</widget>
</item>
<item row="1" column="3" colspan="2">
<widget class="QCheckBox" name="m_pCheckBoxCornerTopRight">
<property name="text">
<string>Top-rig&amp;ht</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QCheckBox" name="m_pCheckBoxCornerBottomLeft">
<property name="text">
<string>&amp;Bottom-left</string>
</property>
</widget>
</item>
<item row="2" column="3" colspan="2">
<widget class="QCheckBox" name="m_pCheckBoxCornerBottomRight">
<property name="text">
<string>Bottom-ri&amp;ght</string>
</property>
</widget>
</item>
<item row="1" column="5">
<layout class="QHBoxLayout" name="horizontalLayout_21">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Cor&amp;ner Size:</string>
</property>
<property name="buddy">
<cstring>m_pSpinBoxSwitchCornerSize</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_pSpinBoxSwitchCornerSize">
<property name="maximum">
<number>30000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>px</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="2">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="m_pGroupOptions">
<property name="font">
<font>
<kerning>false</kerning>
</font>
</property>
<property name="title">
<string>&amp;Options</string>
</property>
<layout class="QGridLayout">
<property name="verticalSpacing">
<number>12</number>
</property>
<item row="11" column="0">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="m_pCheckBoxRelativeMouseMoves">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Use &amp;relative mouse moves</string>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>9</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="m_pCheckBoxHeartbeat">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Check clients every</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="m_pSpinBoxHeartbeat">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>1000</number>
</property>
<property name="maximum">
<number>30000</number>
</property>
<property name="singleStep">
<number>1000</number>
</property>
<property name="value">
<number>5000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_pLabel_16">
<property name="text">
<string>ms</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="m_pCheckBoxIgnoreAutoConfigClient">
<property name="text">
<string>Ignore auto config clients</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="m_pCheckBoxDisableLockToScreen">
<property name="text">
<string>Disable lock to screen</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="m_pCheckBoxWin32KeepForeground">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Don't take &amp;foreground window on Windows servers</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="m_pTabAdvancedConfig"> <widget class="QWidget" name="m_pTabAdvancedConfig">
@ -905,7 +934,7 @@ Enabling this setting will disable the server config GUI.</string>
</spacer> </spacer>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="m_pLayoutConfigCheckbox">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -966,7 +995,7 @@ Enabling this setting will disable the server config GUI.</string>
</layout> </layout>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="m_pLayoutConfigPath">
<property name="leftMargin"> <property name="leftMargin">
<number>40</number> <number>40</number>
</property> </property>
@ -1165,18 +1194,12 @@ Enabling this setting will disable the server config GUI.</string>
<tabstop>m_pCheckBoxHeartbeat</tabstop> <tabstop>m_pCheckBoxHeartbeat</tabstop>
<tabstop>m_pSpinBoxHeartbeat</tabstop> <tabstop>m_pSpinBoxHeartbeat</tabstop>
<tabstop>m_pCheckBoxRelativeMouseMoves</tabstop> <tabstop>m_pCheckBoxRelativeMouseMoves</tabstop>
<tabstop>m_pCheckBoxWin32KeepForeground</tabstop>
<tabstop>m_pCheckBoxIgnoreAutoConfigClient</tabstop>
<tabstop>m_pCheckBoxDisableLockToScreen</tabstop>
<tabstop>m_pCheckBoxCornerTopLeft</tabstop>
<tabstop>m_pCheckBoxCornerBottomLeft</tabstop>
<tabstop>m_pCheckBoxCornerTopRight</tabstop>
<tabstop>m_pCheckBoxCornerBottomRight</tabstop>
<tabstop>m_pSpinBoxSwitchCornerSize</tabstop> <tabstop>m_pSpinBoxSwitchCornerSize</tabstop>
<tabstop>m_pCheckBoxUseExternalConfig</tabstop> <tabstop>m_pCheckBoxUseExternalConfig</tabstop>
<tabstop>m_pEditConfigFile</tabstop> <tabstop>m_pEditConfigFile</tabstop>
<tabstop>m_pTabWidget</tabstop> <tabstop>m_pTabWidget</tabstop>
</tabstops> </tabstops>
<resources/>
<connections> <connections>
<connection> <connection>
<sender>m_pButtonBox</sender> <sender>m_pButtonBox</sender>

View file

@ -52,7 +52,7 @@ void HelloBack::handleHello(deskflow::IStream *stream, const std::string &client
} }
// check versions // check versions
LOG_DEBUG("got hello version %s, %d.%d", protocolName.c_str(), serverMajor, serverMinor); LOG_DEBUG("got hello from %s, protocol v%d.%d", protocolName.c_str(), serverMajor, serverMinor);
const auto helloBackMajor = m_majorVersion; const auto helloBackMajor = m_majorVersion;
auto helloBackMinor = m_minorVersion; auto helloBackMinor = m_minorVersion;

View file

@ -28,6 +28,15 @@ String XBadClient::getWhat() const throw()
return "XBadClient"; return "XBadClient";
} }
//
// XInvalidProtocol
//
String XInvalidProtocol::getWhat() const throw()
{
return "XInvalidProtocol";
}
// //
// XIncompatibleClient // XIncompatibleClient
// //

View file

@ -35,6 +35,12 @@ Thrown when the client fails to follow the protocol.
*/ */
XBASE_SUBCLASS_WHAT(XBadClient, XDeskflow); XBASE_SUBCLASS_WHAT(XBadClient, XDeskflow);
//! Server protocol error
/*!
Thrown when the server protocol is unrecognized.
*/
XBASE_SUBCLASS_WHAT(XInvalidProtocol, XDeskflow);
//! Incompatible client exception //! Incompatible client exception
/*! /*!
Thrown when a client attempting to connect has an incompatible version. Thrown when a client attempting to connect has an incompatible version.

View file

@ -55,6 +55,7 @@ static const OptionID kOptionModifierMapForAltGr = OPTION_CODE("MMFG");
static const OptionID kOptionModifierMapForMeta = OPTION_CODE("MMFM"); static const OptionID kOptionModifierMapForMeta = OPTION_CODE("MMFM");
static const OptionID kOptionModifierMapForSuper = OPTION_CODE("MMFR"); static const OptionID kOptionModifierMapForSuper = OPTION_CODE("MMFR");
static const OptionID kOptionHeartbeat = OPTION_CODE("HART"); static const OptionID kOptionHeartbeat = OPTION_CODE("HART");
static const OptionID kOptionProtocol = OPTION_CODE("PROT");
static const OptionID kOptionScreenSwitchCorners = OPTION_CODE("SSCM"); static const OptionID kOptionScreenSwitchCorners = OPTION_CODE("SSCM");
static const OptionID kOptionScreenSwitchCornerSize = OPTION_CODE("SSCS"); static const OptionID kOptionScreenSwitchCornerSize = OPTION_CODE("SSCS");
static const OptionID kOptionScreenSwitchDelay = OPTION_CODE("SSWT"); static const OptionID kOptionScreenSwitchDelay = OPTION_CODE("SSWT");
@ -98,4 +99,13 @@ enum EScreenSwitchCornerMasks
}; };
//@} //@}
//! @name Network protocol
//@{
enum class ENetworkProtocol
{
kSynergy,
kBarrier
};
//@}
#undef OPTION_CODE #undef OPTION_CODE

View file

@ -60,9 +60,10 @@ ClientProxyUnknown::ClientProxyUnknown(deskflow::IStream *stream, double timeout
m_timer = m_events->newOneShotTimer(timeout, this); m_timer = m_events->newOneShotTimer(timeout, this);
addStreamHandlers(); addStreamHandlers();
std::string helloMessage = std::string(kSynergyProtocolName).append(kMsgHelloArgs); const auto protocol = m_server->protocolString();
const auto helloMessage = protocol + kMsgHelloArgs;
LOG((CLOG_DEBUG1 "saying hello")); LOG_DEBUG("saying hello as %s, protocol v%d.%d", protocol.c_str(), kProtocolMajorVersion, kProtocolMinorVersion);
ProtocolUtil::writef(m_stream, helloMessage.c_str(), kProtocolMajorVersion, kProtocolMinorVersion); ProtocolUtil::writef(m_stream, helloMessage.c_str(), kProtocolMajorVersion, kProtocolMinorVersion);
} }

View file

@ -21,6 +21,7 @@
#include "base/Event.h" #include "base/Event.h"
#include "base/EventTypes.h" #include "base/EventTypes.h"
#include "base/String.h" #include "base/String.h"
#include "deskflow/option_types.h"
class ClientProxy; class ClientProxy;
class EventQueueTimer; class EventQueueTimer;

View file

@ -22,7 +22,9 @@
#include "common/stdistream.h" #include "common/stdistream.h"
#include "common/stdostream.h" #include "common/stdostream.h"
#include "deskflow/KeyMap.h" #include "deskflow/KeyMap.h"
#include "deskflow/XDeskflow.h"
#include "deskflow/key_types.h" #include "deskflow/key_types.h"
#include "deskflow/option_types.h"
#include "net/XSocket.h" #include "net/XSocket.h"
#include "server/Server.h" #include "server/Server.h"
@ -32,6 +34,9 @@ using namespace deskflow::string;
namespace deskflow::server { namespace deskflow::server {
const auto kSynergyProtocolOption = "synergy";
const auto kBarrierProtocolOption = "barrier";
// //
// Config // Config
// //
@ -675,6 +680,8 @@ void Config::readSectionOptions(ConfigReadContext &s)
} }
} else if (name == "heartbeat") { } else if (name == "heartbeat") {
addOption("", kOptionHeartbeat, s.parseInt(value)); addOption("", kOptionHeartbeat, s.parseInt(value));
} else if (name == "protocol") {
addOption("", kOptionProtocol, s.parseProtocol(value));
} else if (name == "switchCorners") { } else if (name == "switchCorners") {
addOption("", kOptionScreenSwitchCorners, s.parseCorners(value)); addOption("", kOptionScreenSwitchCorners, s.parseCorners(value));
} else if (name == "switchCornerSize") { } else if (name == "switchCornerSize") {
@ -1325,6 +1332,17 @@ String Config::getOptionValue(OptionID id, OptionValue value)
} }
return result; return result;
} }
if (id == kOptionProtocol) {
using enum ENetworkProtocol;
const auto enumValue = static_cast<ENetworkProtocol>(value);
if (enumValue == kSynergy) {
return kSynergyProtocolOption;
} else if (enumValue == kBarrier) {
return kBarrierProtocolOption;
} else {
throw XInvalidProtocol();
}
}
return ""; return "";
} }
@ -1822,6 +1840,16 @@ OptionValue ConfigReadContext::parseCorner(const String &arg) const
throw XConfigRead(*this, "invalid argument \"%{1}\"", arg); throw XConfigRead(*this, "invalid argument \"%{1}\"", arg);
} }
OptionValue ConfigReadContext::parseProtocol(const String &args) const
{
if (CaselessCmp::equal(args, kSynergyProtocolOption)) {
return static_cast<OptionValue>(ENetworkProtocol::kSynergy);
} else if (CaselessCmp::equal(args, kBarrierProtocolOption)) {
return static_cast<OptionValue>(ENetworkProtocol::kBarrier);
}
throw XConfigRead(*this, "invalid protocol argument \"%{1}\"", args);
}
OptionValue ConfigReadContext::parseCorners(const String &args) const OptionValue ConfigReadContext::parseCorners(const String &args) const
{ {
// find first token // find first token

View file

@ -537,6 +537,7 @@ public:
OptionValue parseModifierKey(const String &) const; OptionValue parseModifierKey(const String &) const;
OptionValue parseCorner(const String &) const; OptionValue parseCorner(const String &) const;
OptionValue parseCorners(const String &) const; OptionValue parseCorners(const String &) const;
OptionValue parseProtocol(const String &) const;
Config::Interval parseInterval(const ArgList &args) const; Config::Interval parseInterval(const ArgList &args) const;
void parseNameWithArgs( void parseNameWithArgs(
const String &type, const String &line, const String &delim, String::size_type &index, String &name, ArgList &args const String &type, const String &line, const String &delim, String::size_type &index, String &name, ArgList &args

View file

@ -31,6 +31,7 @@
#include "deskflow/PacketStreamFilter.h" #include "deskflow/PacketStreamFilter.h"
#include "deskflow/Screen.h" #include "deskflow/Screen.h"
#include "deskflow/StreamChunker.h" #include "deskflow/StreamChunker.h"
#include "deskflow/XDeskflow.h"
#include "deskflow/option_types.h" #include "deskflow/option_types.h"
#include "deskflow/protocol_types.h" #include "deskflow/protocol_types.h"
#include "mt/Thread.h" #include "mt/Thread.h"
@ -341,6 +342,17 @@ void Server::disconnect()
} }
} }
std::string Server::protocolString() const
{
using enum ENetworkProtocol;
if (m_protocol == kSynergy) {
return kSynergyProtocolName;
} else if (m_protocol == kBarrier) {
return kBarrierProtocolName;
}
throw XInvalidProtocol();
}
UInt32 Server::getNumClients() const UInt32 Server::getNumClients() const
{ {
return (SInt32)m_clients.size(); return (SInt32)m_clients.size();
@ -1100,7 +1112,17 @@ void Server::processOptions()
for (Config::ScreenOptions::const_iterator index = options->begin(); index != options->end(); ++index) { for (Config::ScreenOptions::const_iterator index = options->begin(); index != options->end(); ++index) {
const OptionID id = index->first; const OptionID id = index->first;
const OptionValue value = index->second; const OptionValue value = index->second;
if (id == kOptionScreenSwitchDelay) { if (id == kOptionProtocol) {
using enum ENetworkProtocol;
const auto enumValue = static_cast<ENetworkProtocol>(value);
if (enumValue == kSynergy) {
m_protocol = kSynergy;
} else if (enumValue == kBarrier) {
m_protocol = kBarrier;
} else {
throw XInvalidProtocol();
}
} else if (id == kOptionScreenSwitchDelay) {
m_switchWaitDelay = 1.0e-3 * static_cast<double>(value); m_switchWaitDelay = 1.0e-3 * static_cast<double>(value);
if (m_switchWaitDelay < 0.0) { if (m_switchWaitDelay < 0.0) {
m_switchWaitDelay = 0.0; m_switchWaitDelay = 0.0;

View file

@ -31,6 +31,7 @@
#include "deskflow/clipboard_types.h" #include "deskflow/clipboard_types.h"
#include "deskflow/key_types.h" #include "deskflow/key_types.h"
#include "deskflow/mouse_types.h" #include "deskflow/mouse_types.h"
#include "deskflow/option_types.h"
#include "server/Config.h" #include "server/Config.h"
#include <memory> #include <memory>
@ -192,6 +193,12 @@ public:
//! @name accessors //! @name accessors
//@{ //@{
//! Get the network protocol
/*!
Returns the network protocol used by the server.
*/
std::string protocolString() const;
//! Get number of connected clients //! Get number of connected clients
/*! /*!
Returns the number of connected clients, including the server itself. Returns the number of connected clients, including the server itself.
@ -422,6 +429,9 @@ private:
UInt32 m_clipboardSeqNum; UInt32 m_clipboardSeqNum;
}; };
// used in hello message sent to the client
ENetworkProtocol m_protocol;
// the primary screen client // the primary screen client
PrimaryClient *m_primaryClient; PrimaryClient *m_primaryClient;