diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 00000000..09408928 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,62 @@ +gcp_credentials: ENCRYPTED[d3110e2399b82e1d2adb6f9294917064a448a4d102c42c5023815723841db4ff7aa1d0df64a44281ed25b3adbeb08eff] + +windows_task: + gce_instance: + image_project: buildcluster-237411 + image_name: windows2019-vs2017-ramdisk + platform: windows + zone: us-central1-a + type: n1-highcpu-16 + disk: 32 + use_ssd: true + + env: + BONJOUR_SDK_HOME: C:\Program Files\Bonjour SDK\ + CMAKE_PREFIX_PATH: C:\Qt\5.9.5\msvc2017_64 + CIRRUS_WORKING_DIR: D:\ + + build_script: + - .\CI\Windows\build.bat + +ubuntu1604_task: + use_compute_credits: true + container: + dockerfile: CI/ubuntu1604.Dockerfile + build_script: + - pwd; ls -la + - chmod +x ./CI/build.sh + - ./CI/build.sh + +ubuntu1804_task: + use_compute_credits: true + container: + dockerfile: CI/ubuntu1804.Dockerfile + build_script: + - pwd; ls -la + - chmod +x ./CI/build.sh + - ./CI/build.sh + +ubuntu1904_task: + use_compute_credits: true + container: + dockerfile: CI/ubuntu1904.Dockerfile + build_script: + - pwd; ls -la + - chmod +x ./CI/build.sh + - ./CI/build.sh + +macos_task: + use_compute_credits: true + osx_instance: + image: mojave-xcode-10.2 + + env: + PATH: /usr/local/opt/qt/bin:$PATH + + install_script: + - brew install qt + build_script: + - mkdir build + - cd build + - cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.10 -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -DCMAKE_CONFIGURATION_TYPES=$CMAKE_BUILD_TYPE .. + - make diff --git a/CI/MacOS/qtifwsilent.qs b/CI/MacOS/qtifwsilent.qs new file mode 100644 index 00000000..d4069ef3 --- /dev/null +++ b/CI/MacOS/qtifwsilent.qs @@ -0,0 +1,56 @@ +function Controller() { + installer.autoRejectMessageBoxes(); + installer.installationFinished.connect(function() { + gui.clickButton(buttons.NextButton); + }) +} + +Controller.prototype.WelcomePageCallback = function() { + gui.clickButton(buttons.NextButton, 3000); +} + +Controller.prototype.CredentialsPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.IntroductionPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.TargetDirectoryPageCallback = function() +{ + gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.value("HomeDir") + "/Qt"); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ComponentSelectionPageCallback = function() { + var widget = gui.currentPageWidget(); + + widget.deselectAll(); + + widget.selectComponent("qt.595.clang_64") + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.LicenseAgreementPageCallback = function() { + gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.StartMenuDirectoryPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ReadyForInstallationPageCallback = function() +{ + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.FinishedPageCallback = function() { +var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm +if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) { + checkBoxForm.launchQtCreatorCheckBox.checked = false; +} + gui.clickButton(buttons.FinishButton); +} \ No newline at end of file diff --git a/CI/Windows/build.bat b/CI/Windows/build.bat new file mode 100644 index 00000000..61973076 --- /dev/null +++ b/CI/Windows/build.bat @@ -0,0 +1,6 @@ +SET VS_INSTALL_PATH=C:\"Program Files (x86)"\"Microsoft Visual Studio"\2019\Community\ +call %VS_INSTALL_PATH%Common7\Tools\VsDevCmd.bat +mkdir build +cd build +cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Debug .. +msbuild synergy-core.sln /p:Platform="x64" /p:Configuration=Debug /m \ No newline at end of file diff --git a/CI/Windows/qtifwsilent.qs b/CI/Windows/qtifwsilent.qs new file mode 100644 index 00000000..c980892a --- /dev/null +++ b/CI/Windows/qtifwsilent.qs @@ -0,0 +1,54 @@ +function Controller() { + installer.autoRejectMessageBoxes(); + installer.installationFinished.connect(function() { + gui.clickButton(buttons.NextButton); + }) +} + +Controller.prototype.WelcomePageCallback = function() { + gui.clickButton(buttons.NextButton, 3000); +} + +Controller.prototype.CredentialsPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.IntroductionPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.TargetDirectoryPageCallback = function() { + gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.environmentVariable("QT_INSTALL_DIR")); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ComponentSelectionPageCallback = function() { + var widget = gui.currentPageWidget(); + widget.deselectAll(); + widget.selectComponent("qt.595.win32_msvc2015"); + widget.selectComponent("qt.595.win64_msvc2015_64"); + widget.selectComponent("qt.595.qtscript"); + widget.selectComponent("qt.tools.vcredist_msvc2015_x86"); + widget.selectComponent("qt.tools.vcredist_msvc2015_x64"); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.LicenseAgreementPageCallback = function() { + gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.StartMenuDirectoryPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ReadyForInstallationPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.FinishedPageCallback = function() { + var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm; + if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) + checkBoxForm.launchQtCreatorCheckBox.checked = false; + gui.clickButton(buttons.FinishButton); +} \ No newline at end of file diff --git a/CI/build.sh b/CI/build.sh new file mode 100644 index 00000000..d940c135 --- /dev/null +++ b/CI/build.sh @@ -0,0 +1,6 @@ +pwd +ls -la +mkdir build +cd build +cmake .. +make \ No newline at end of file diff --git a/CI/package.sh b/CI/package.sh new file mode 100644 index 00000000..e5a3fa59 --- /dev/null +++ b/CI/package.sh @@ -0,0 +1,12 @@ +cd ${CIRRUS_WORKING_DIR} + +source ./build/version + +SYNERGY_VERSION="$SYNERGY_VERSION_MAJOR.$SYNERGY_VERSION_MINOR.$SYNERGY_VERSION_PATCH" +SYNERGY_REVISION=`git rev-parse --short=8 HEAD` +SYNERGY_DEB_VERSION="${SYNERGY_VERSION}.${SYNERGY_VERSION_STAGE}~b${BUILD_NUMBER}+${SYNERGY_REVISION}" + +dch --create --package "synergy" --controlmaint --distribution unstable --newversion $SYNERGY_DEB_VERSION "Initial release" + +export DEB_BUILD_OPTIONS="parallel=4" +debuild --preserve-envvar SYNERGY_* --preserve-envvar GIT_COMMIT --preserve-envvar BUILD_NUMBER \ No newline at end of file diff --git a/CI/ubuntu1604.Dockerfile b/CI/ubuntu1604.Dockerfile new file mode 100644 index 00000000..de1b1c64 --- /dev/null +++ b/CI/ubuntu1604.Dockerfile @@ -0,0 +1,24 @@ +# +# Ubuntu Dockerfile +# +# https://github.com/dockerfile/ubuntu +# + +# Pull base image. +FROM ubuntu:16.04 + +# Install. +RUN \ + sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \ + apt-get update && \ + apt-get install -y git cmake qtbase5-dev build-essential libx11-dev libxtst-dev libgl1-mesa-dev libssl-dev libavahi-compat-libdnssd-dev && \ + apt-get install -y debhelper devscripts + +# Set environment variables. +ENV HOME /root + +# Define working directory. +WORKDIR /root + +# Define default command. +CMD ["bash"] \ No newline at end of file diff --git a/CI/ubuntu1804.Dockerfile b/CI/ubuntu1804.Dockerfile new file mode 100644 index 00000000..733cbbd7 --- /dev/null +++ b/CI/ubuntu1804.Dockerfile @@ -0,0 +1,24 @@ +# +# Ubuntu Dockerfile +# +# https://github.com/dockerfile/ubuntu +# + +# Pull base image. +FROM ubuntu:18.04 + +# Install. +RUN \ + sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \ + apt-get update && \ + apt-get install -y git cmake qtbase5-dev build-essential libx11-dev libxtst-dev libgl1-mesa-dev libssl-dev libavahi-compat-libdnssd-dev && \ + apt-get install -y debhelper devscripts + +# Set environment variables. +ENV HOME /root + +# Define working directory. +WORKDIR /root + +# Define default command. +CMD ["bash"] \ No newline at end of file diff --git a/CI/ubuntu1904.Dockerfile b/CI/ubuntu1904.Dockerfile new file mode 100644 index 00000000..2e48cf4f --- /dev/null +++ b/CI/ubuntu1904.Dockerfile @@ -0,0 +1,24 @@ +# +# Ubuntu Dockerfile +# +# https://github.com/dockerfile/ubuntu +# + +# Pull base image. +FROM ubuntu:19.04 + +# Install. +RUN \ + sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \ + apt-get update && \ + apt-get install -y git cmake qtbase5-dev build-essential libx11-dev libxtst-dev libgl1-mesa-dev libssl-dev libavahi-compat-libdnssd-dev && \ + apt-get install -y debhelper devscripts + +# Set environment variables. +ENV HOME /root + +# Define working directory. +WORKDIR /root + +# Define default command. +CMD ["bash"] \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 35bbfabb..bf9eecbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -336,6 +336,23 @@ macro (configure_files srcDir destDir) endforeach (templateFile) endmacro (configure_files) +macro(generate_versionfile) + if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR ${CMAKE_SYSTEM_NAME} MATCHES "Linux") + FILE(WRITE ${CMAKE_BINARY_DIR}/version + "export SYNERGY_VERSION_MAJOR=\"${SYNERGY_VERSION_MAJOR}\"\n" + "export SYNERGY_VERSION_MINOR=\"${SYNERGY_VERSION_MINOR}\"\n" + "export SYNERGY_VERSION_PATCH=\"${SYNERGY_VERSION_PATCH}\"\n" + "export SYNERGY_VERSION_STAGE=\"${SYNERGY_VERSION_STAGE}\"\n") + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + FILE(WRITE ${CMAKE_BINARY_DIR}/version + "$env:SYNERGY_VERSION_MAJOR=\"${SYNERGY_VERSION_MAJOR}\"\n" + "$env:SYNERGY_VERSION_MINOR=\"${SYNERGY_VERSION_MINOR}\"\n" + "$env:SYNERGY_VERSION_PATCH=\"${SYNERGY_VERSION_PATCH}\"\n" + "$env:SYNERGY_VERSION_STAGE=\"${SYNERGY_VERSION_STAGE}\"\n") + endif() +endmacro(generate_versionfile) + + if (${SYNERGY_BUILD_LEGACY_INSTALLER}) # # macOS app Bundle @@ -346,7 +363,8 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set (SYNERGY_BUNDLE_DIR ${CMAKE_BINARY_DIR}/bundle) set (SYNERGY_BUNDLE_APP_DIR ${SYNERGY_BUNDLE_DIR}/Synergy.app) set (SYNERGY_BUNDLE_BINARY_DIR ${SYNERGY_BUNDLE_APP_DIR}/Contents/MacOS) - + + generate_versionfile() configure_files (${SYNERGY_BUNDLE_SOURCE_DIR} ${SYNERGY_BUNDLE_DIR}) endif() @@ -356,6 +374,7 @@ endif() if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") message (STATUS "Configuring the v1 installer") configure_files (${CMAKE_CURRENT_SOURCE_DIR}/dist/wix ${CMAKE_BINARY_DIR}/installer) + generate_versionfile() endif() # @@ -369,6 +388,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") else() install(FILES res/synergy.desktop DESTINATION share/applications) endif() + generate_versionfile() endif() else() diff --git a/ChangeLog b/ChangeLog index c9ec3b89..6e2853b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +v1.10.2-rc2 +============== + +Bug fixes: +- #6495 Event queue memory leak in server cleanup +- #6471 Unable to stop core retry loop in config app +- #6460 TLS memory leak on Linux server when using client +- #6407 Enterprise config app shows auto-config elements +- #6403 Mouse cursor movement drifts over time +- #6392 Hostname alert shows unnecessarily on every open +- #6373 Compile fails on BSD Unix with dl error + +Enhancements: +- #6485 Readme for master branch with download help +- #6475 Change master branch to current version +- #6470 CI solution with on-demand containers +- #6397 Remember last server used in Auto Config +- #6375 Support for Qt 5.11 framework on Windows + v1.10.1-stable ============== diff --git a/cmake/Version.cmake b/cmake/Version.cmake index 623445f6..546a5109 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -7,7 +7,7 @@ cmake_minimum_required (VERSION 3.4) set (SYNERGY_VERSION_MAJOR 1) set (SYNERGY_VERSION_MINOR 10) set (SYNERGY_VERSION_PATCH 2) -set (SYNERGY_VERSION_STAGE "snapshot") +set (SYNERGY_VERSION_STAGE "rc2") # # Version from CI diff --git a/src/gui/src/ActionDialog.cpp b/src/gui/src/ActionDialog.cpp index 94950338..7518015e 100644 --- a/src/gui/src/ActionDialog.cpp +++ b/src/gui/src/ActionDialog.cpp @@ -25,6 +25,7 @@ #include #include +#include ActionDialog::ActionDialog(QWidget* parent, ServerConfig& config, Hotkey& hotkey, Action& action) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index 547d0866..2d6fd1b3 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -56,7 +56,8 @@ AppConfig::AppConfig(QSettings* settings) : m_ElevateMode(defaultElevateMode), m_CryptoEnabled(false), m_AutoHide(false), - m_LastExpiringWarningTime(0) + m_LastExpiringWarningTime(0), + m_AutoConfigServer() { Q_ASSERT(m_pSettings); @@ -126,7 +127,16 @@ const QString &AppConfig::language() const { return m_Language; } bool AppConfig::startedBefore() const { return m_StartedBefore; } -bool AppConfig::autoConfig() const { return m_AutoConfig; } +bool AppConfig::autoConfig() const { +#ifndef SYNERGY_ENTERPRISE + return m_AutoConfig; +#else + // always disable auto config for enterprise edition. + return false; +#endif +} + +QString AppConfig::autoConfigServer() const { return m_AutoConfigServer; } void AppConfig::loadSettings() { @@ -140,6 +150,7 @@ void AppConfig::loadSettings() m_Language = settings().value("language", QLocale::system().name()).toString(); m_StartedBefore = settings().value("startedBefore", false).toBool(); m_AutoConfig = settings().value("autoConfig", false).toBool(); + m_AutoConfigServer = settings().value("autoConfigServer", "").toString(); QVariant elevateMode = settings().value("elevateModeEnum"); if (!elevateMode.isValid()) { elevateMode = settings().value ("elevateMode", @@ -168,6 +179,7 @@ void AppConfig::saveSettings() settings().setValue("language", m_Language); settings().setValue("startedBefore", m_StartedBefore); settings().setValue("autoConfig", m_AutoConfig); + settings().setValue("autoConfigServer", m_AutoConfigServer); // Refer to enum ElevateMode declaration for insight in to why this // flag is mapped this way settings().setValue("elevateMode", m_ElevateMode == ElevateAlways); @@ -231,6 +243,11 @@ void AppConfig::setAutoConfig(bool autoConfig) m_AutoConfig = autoConfig; } +void AppConfig::setAutoConfigServer(QString autoConfigServer) +{ + m_AutoConfigServer = autoConfigServer; +} + #ifndef SYNERGY_ENTERPRISE void AppConfig::setEdition(Edition e) { m_Edition = e; diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h index 756492a6..654cc3dc 100644 --- a/src/gui/src/AppConfig.h +++ b/src/gui/src/AppConfig.h @@ -77,6 +77,8 @@ class AppConfig: public QObject bool startedBefore() const; bool autoConfig() const; void setAutoConfig(bool autoConfig); + QString autoConfigServer() const; + void setAutoConfigServer(QString autoConfigServer); #ifndef SYNERGY_ENTERPRISE void setEdition(Edition); Edition edition() const; @@ -138,6 +140,7 @@ protected: QString m_Language; bool m_StartedBefore; bool m_AutoConfig; + QString m_AutoConfigServer; ElevateMode m_ElevateMode; Edition m_Edition; QString m_ActivateEmail; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 624d71ba..facff7e0 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -66,10 +66,11 @@ static const int debugLogLevel = 1; static const char* synergyIconFiles[] = { - ":/res/icons/16x16/synergy-disconnected.png", - ":/res/icons/16x16/synergy-disconnected.png", - ":/res/icons/16x16/synergy-connected.png", - ":/res/icons/16x16/synergy-transfering.png" + ":/res/icons/16x16/synergy-disconnected.png", //synergyDisconnected + ":/res/icons/16x16/synergy-disconnected.png", //synergyConnecting + ":/res/icons/16x16/synergy-connected.png", //synergyConnected + ":/res/icons/16x16/synergy-transfering.png", //synergyListening + ":/res/icons/16x16/synergy-disconnected.png" //synergyPendingRetry }; #ifdef SYNERGY_ENTERPRISE @@ -179,8 +180,11 @@ MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig, #ifndef SYNERGY_ENTERPRISE updateZeroconfService(); - updateAutoConfigWidgets(); + + addZeroconfServer(m_AppConfig->autoConfigServer()); #endif + + updateAutoConfigWidgets(); } MainWindow::~MainWindow() @@ -439,7 +443,7 @@ void MainWindow::appendLogRaw(const QString& text) void MainWindow::updateFromLogLine(const QString &line) { - // TODO: this code makes Andrew cry + // TODO: This shouldn't be updating from log needs a better way of doing this checkConnected(line); checkFingerprint(line); checkSecureSocket(line); @@ -709,6 +713,16 @@ void MainWindow::startSynergy() } } +void MainWindow::retryStart() +{ + //This function is only called after a failed start + //Only start synergy if the current state is pending retry + if (m_SynergyState == synergyPendingRetry) + { + startSynergy(); + } +} + void MainWindow::sslToggled (bool enabled) { @@ -751,17 +765,37 @@ bool MainWindow::clientArgs(QStringList& args, QString& app) args << serverIp + ":" + QString::number(appConfig().port()); return true; } + else { + show(); + QMessageBox::warning( + this, tr("No server selected"), + tr("No auto config server was selected, try manual mode instead.")); + return false; + } } #endif - if (m_pLineEditHostname->text().isEmpty()) { - show(); - QMessageBox::warning( - this, tr("Hostname is empty"), - tr("Please fill in a hostname for the synergy client to connect to.")); - return false; - } + if (m_pLineEditHostname->text().isEmpty()) + { +#ifndef SYNERGY_ENTERPRISE + //check if autoconfig mode is enabled + if (!appConfig().autoConfig()) + { +#endif + show(); + QMessageBox::warning( + this, tr("Hostname is empty"), + tr("Please fill in a hostname for the synergy client to connect to.")); + return false; +#ifndef SYNERGY_ENTERPRISE + } + else + { + return false; + } +#endif + } args << m_pLineEditHostname->text() + ":" + QString::number(appConfig().port()); return true; } @@ -912,7 +946,9 @@ void MainWindow::synergyFinished(int exitCode, QProcess::ExitStatus) } if (m_ExpectedRunningState == kStarted) { - QTimer::singleShot(1000, this, SLOT(startSynergy())); + + setSynergyState(synergyPendingRetry); + QTimer::singleShot(1000, this, SLOT(retryStart())); appendLogInfo(QString("detected process not running, auto restarting")); } else { @@ -932,7 +968,7 @@ void MainWindow::setSynergyState(qSynergyState state) if (synergyState() == state) return; - if ((state == synergyConnected) || (state == synergyConnecting) || (state == synergyListening)) + if ((state == synergyConnected) || (state == synergyConnecting) || (state == synergyListening) || (state == synergyPendingRetry)) { disconnect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStartSynergy, SLOT(trigger())); connect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStopSynergy, SLOT(trigger())); @@ -976,6 +1012,9 @@ void MainWindow::setSynergyState(qSynergyState state) case synergyConnecting: setStatus(tr("Synergy is starting...")); break; + case synergyPendingRetry: + setStatus(tr("There was an error, retrying...")); + break; case synergyDisconnected: setStatus(tr("Synergy is not running")); break; @@ -1071,13 +1110,8 @@ void MainWindow::changeEvent(QEvent* event) } } -void MainWindow::zeroconfServerDetected(const QString name) +void MainWindow::addZeroconfServer(const QString name) { - // don't add to the server combo box if not in client mode. - if (synergyType() != synergyClient) { - return; - } - // don't add yourself to the server list. if (getIPAddresses().contains(name)) { return; @@ -1086,10 +1120,6 @@ void MainWindow::zeroconfServerDetected(const QString name) if (m_pComboServerList->findText(name) == -1) { m_pComboServerList->addItem(name); } - - if (m_pComboServerList->count() > 1) { - m_pComboServerList->show(); - } } void MainWindow::setEdition(Edition edition) @@ -1262,7 +1292,11 @@ void MainWindow::updateAutoConfigWidgets() m_pLabelAutoDetected->hide(); m_pComboServerList->hide(); +#ifndef SYNERGY_ENTERPRISE m_pWidgetAutoConfig->show(); +#else + m_pWidgetAutoConfig->hide(); +#endif } } @@ -1410,3 +1444,9 @@ void MainWindow::on_m_pLabelAutoConfig_linkActivated(const QString &) { m_pActionSettings->trigger(); } + +void MainWindow::on_m_pComboServerList_currentIndexChanged(const QString &server) +{ + appConfig().setAutoConfigServer(server); + appConfig().saveSettings(); +} diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index e267ccf2..f4df8f4b 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -73,7 +73,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase synergyDisconnected, synergyConnecting, synergyConnected, - synergyListening + synergyListening, + synergyPendingRetry }; enum qSynergyType @@ -117,7 +118,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase void showConfigureServer(const QString& message); void showConfigureServer() { showConfigureServer(""); } void autoAddScreen(const QString name); - void zeroconfServerDetected(const QString name); + void addZeroconfServer(const QString name); void updateLocalFingerprint(); Zeroconf& zeroconf() { return *m_pZeroconf; } #ifndef SYNERGY_ENTERPRISE @@ -138,6 +139,7 @@ public slots: void appendLogDebug(const QString& text); void appendLogError(const QString& text); void startSynergy(); + void retryStart(); // If the connection failed this will retry a startSynergy protected slots: void sslToggled(bool enabled); @@ -239,6 +241,8 @@ private slots: void on_m_pLabelAutoConfig_linkActivated(const QString &link); + void on_m_pComboServerList_currentIndexChanged(const QString &arg1); + signals: void windowShown(); }; diff --git a/src/gui/src/ScreenSetupView.cpp b/src/gui/src/ScreenSetupView.cpp index f26d9700..0580cf2d 100644 --- a/src/gui/src/ScreenSetupView.cpp +++ b/src/gui/src/ScreenSetupView.cpp @@ -22,6 +22,7 @@ #include #include +#include ScreenSetupView::ScreenSetupView(QWidget* parent) : QTableView(parent) diff --git a/src/gui/src/ZeroconfService.cpp b/src/gui/src/ZeroconfService.cpp index e8a124f2..eff56aef 100644 --- a/src/gui/src/ZeroconfService.cpp +++ b/src/gui/src/ZeroconfService.cpp @@ -81,7 +81,7 @@ void ZeroconfService::serverDetected(const QList& list) registerService(false); m_pMainWindow->appendLogInfo(tr("zeroconf server detected: %1").arg( record.serviceName)); - m_pMainWindow->zeroconfServerDetected(record.serviceName); + m_pMainWindow->addZeroconfServer(record.serviceName); } } diff --git a/src/lib/arch/CMakeLists.txt b/src/lib/arch/CMakeLists.txt index e7b755be..3bc0ccc2 100644 --- a/src/lib/arch/CMakeLists.txt +++ b/src/lib/arch/CMakeLists.txt @@ -40,5 +40,5 @@ endif() add_library(arch STATIC ${sources}) if (UNIX) - target_link_libraries(arch dl ${libs}) + target_link_libraries(arch ${CMAKE_DL_LIBS} ${libs}) endif() diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 43b45e2a..21d9bbdf 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -199,6 +199,7 @@ SecureSocket::doWrite() { static bool s_retry = false; static int s_retrySize = 0; + static int s_staticBufferSize = 0; static void* s_staticBuffer = NULL; // write data @@ -211,8 +212,13 @@ SecureSocket::doWrite() } else { bufferSize = m_outputBuffer.getSize(); - s_staticBuffer = malloc(bufferSize); - memcpy(s_staticBuffer, m_outputBuffer.peek(bufferSize), bufferSize); + if (bufferSize != 0) { + if (bufferSize > s_staticBufferSize) { + s_staticBuffer = realloc(s_staticBuffer, bufferSize); + s_staticBufferSize = bufferSize; + } + memcpy(s_staticBuffer, m_outputBuffer.peek(bufferSize), bufferSize); + } } if (bufferSize == 0) { @@ -224,8 +230,6 @@ SecureSocket::doWrite() if (status > 0) { s_retry = false; bufferSize = 0; - free(s_staticBuffer); - s_staticBuffer = NULL; } else if (status < 0) { return kBreak; diff --git a/src/lib/platform/OSXScreen.h b/src/lib/platform/OSXScreen.h index 25531e0e..6b1e8211 100644 --- a/src/lib/platform/OSXScreen.h +++ b/src/lib/platform/OSXScreen.h @@ -118,7 +118,7 @@ private: void sendClipboardEvent(Event::Type type, ClipboardID id) const; // message handlers - bool onMouseMove(SInt32 mx, SInt32 my); + bool onMouseMove(CGFloat mx, CGFloat my); // mouse button handler. pressed is true if this is a mousedown // event, false if it is a mouseup event. macButton is the index // of the button pressed using the mac button mapping. diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm index 93bec0e9..ba2814ef 100644 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -1080,20 +1080,20 @@ OSXScreen::handleSystemEvent(const Event& event, void*) } bool -OSXScreen::onMouseMove(SInt32 mx, SInt32 my) +OSXScreen::onMouseMove(CGFloat mx, CGFloat my) { - LOG((CLOG_DEBUG2 "mouse move %+d,%+d", mx, my)); + LOG((CLOG_DEBUG2 "mouse move %+f,%+f", mx, my)); - SInt32 x = mx - m_xCursor; - SInt32 y = my - m_yCursor; + CGFloat x = mx - m_xCursor; + CGFloat y = my - m_yCursor; if ((x == 0 && y == 0) || (mx == m_xCenter && mx == m_yCenter)) { return true; } // save position to compute delta of next motion - m_xCursor = mx; - m_yCursor = my; + m_xCursor = (SInt32)mx; + m_yCursor = (SInt32)my; if (m_isOnScreen) { // motion on primary screen @@ -1122,7 +1122,21 @@ OSXScreen::onMouseMove(SInt32 mx, SInt32 my) } else { // send motion - sendEvent(m_events->forIPrimaryScreen().motionOnSecondary(), MotionInfo::alloc(x, y)); + // Accumulate together the move into the running total + static CGFloat m_xFractionalMove = 0; + static CGFloat m_yFractionalMove = 0; + + m_xFractionalMove += x; + m_yFractionalMove += y; + + // Return the integer part + SInt32 intX = (SInt32)m_xFractionalMove; + SInt32 intY = (SInt32)m_yFractionalMove; + + // And keep only the fractional part + m_xFractionalMove -= intX; + m_yFractionalMove -= intY; + sendEvent(m_events->forIPrimaryScreen().motionOnSecondary(), MotionInfo::alloc(intX, intY)); } } diff --git a/src/lib/synergy/ServerApp.cpp b/src/lib/synergy/ServerApp.cpp index 5d49239a..726e05ab 100644 --- a/src/lib/synergy/ServerApp.cpp +++ b/src/lib/synergy/ServerApp.cpp @@ -304,11 +304,11 @@ ServerApp::closeServer(Server* server) void ServerApp::stopRetryTimer() { - if (m_timer != NULL) { - m_events->deleteTimer(m_timer); - m_events->removeHandler(Event::kTimer, NULL); - m_timer = NULL; - } + if (m_timer != NULL) { + m_events->removeHandler(Event::kTimer, m_timer); + m_events->deleteTimer(m_timer); + m_timer = NULL; + } } void