diff --git a/ChangeLog b/ChangeLog
index ec6c108c..873fd434 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+v1.7.4-stable
+=============
+Bug #4721 - High CPU usage for Windows service on client
+Bug #4712 - Unable to send clipboard with size above 1KB when using SSL
+Bug #4584 - Drag and drop with SSL causes crash
+Bug #3774 - Missing MinGW dependencies after install on Windows
+Bug #4749 - Clipboard thread race condition causes assertion failure
+Bug #4723 - Waiting for active desktop result freezes Windows service
+Bug #4690 - Log line 'activeDesktop' does not use logging system
+Bug #4720 - Plugin download shows 'Could not get Linux package type' error
+Bug #4737 - Using error log level does not show SSL fingerprint dialog
+Enhancement #4696 - Include 'ns' plugin in installers instead of wizard download
+Enhancement #4796 - Improve secure socket intensive try operations
+Enhancement #4327 - GUI setting to disable drag and drop feature
+Enhancement #4745 - Tray icon notification for clipboard data transfer progress
+Enhancement #4793 - Additional logging to output OpenSSL version
+
v1.7.3-stable
=============
Bug #4565 - Incorrect plugin downloads on Debian and Mint
diff --git a/src/gui/res/ServerConfigDialogBase.ui b/src/gui/res/ServerConfigDialogBase.ui
index 6d257ba2..cc44f66e 100644
--- a/src/gui/res/ServerConfigDialogBase.ui
+++ b/src/gui/res/ServerConfigDialogBase.ui
@@ -491,7 +491,21 @@ Double click on a screen to edit its settings.
+ -
+
+
+ Ignore auto config clients
+
+
+
-
+
+
+ Enable drag and drop file transfers
+
+
+
+ -
Qt::Vertical
@@ -504,13 +518,6 @@ Double click on a screen to edit its settings.
- -
-
-
- Ignore auto config clients
-
-
-
diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp
index 4db1a65f..1ecfde01 100644
--- a/src/gui/src/MainWindow.cpp
+++ b/src/gui/src/MainWindow.cpp
@@ -467,24 +467,26 @@ void MainWindow::checkFingerprint(const QString& line)
void MainWindow::checkTransmission(const QString& line)
{
- if (line.contains("Transmission")) {
- if (line.contains("Started")) {
- setSynergyState(synergyTransfering);
- }
- else if (line.contains("Failed") ||
- line.contains("Complete") ||
- line.contains("Interrupted")) {
- setSynergyState(synergyConnected);
- }
+ if (appConfig().logLevel() >= 2) {
+ if (line.contains("Transmission")) {
+ if (line.contains("Started")) {
+ setSynergyState(synergyTransfering);
+ }
+ else if (line.contains("Failed") ||
+ line.contains("Complete") ||
+ line.contains("Interrupted")) {
+ setSynergyState(synergyConnected);
+ }
- // NOTIFY: Title: Detail
- int p1 = line.indexOf(':');
- if (p1 > 0) {
- int p2 = line.indexOf(':', p1 + 1);
- if (p2 > 0) {
- QString title = line.mid(p1 + 2, p2 - p1 - 2);
- QString detail = line.mid(p2 + 2);
- m_pTrayIcon->showMessage(title, detail);
+ // NOTIFY: Title: Detail
+ int p1 = line.indexOf(':');
+ if (p1 > 0) {
+ int p2 = line.indexOf(':', p1 + 1);
+ if (p2 > 0) {
+ QString title = line.mid(p1 + 2, p2 - p1 - 2);
+ QString detail = line.mid(p2 + 2);
+ m_pTrayIcon->showMessage(title, detail);
+ }
}
}
}
@@ -546,7 +548,9 @@ void MainWindow::startSynergy()
#ifndef Q_OS_LINUX
- args << "--enable-drag-drop";
+ if (m_ServerConfig.enableDragAndDrop()) {
+ args << "--enable-drag-drop";
+ }
#endif
diff --git a/src/gui/src/ServerConfig.cpp b/src/gui/src/ServerConfig.cpp
index 70f5d46e..d84f91f0 100644
--- a/src/gui/src/ServerConfig.cpp
+++ b/src/gui/src/ServerConfig.cpp
@@ -50,6 +50,7 @@ ServerConfig::ServerConfig(QSettings* settings, int numColumns, int numRows ,
m_NumRows(numRows),
m_ServerName(serverName),
m_IgnoreAutoConfigClient(false),
+ m_EnableDragAndDrop(false),
m_pMainWindow(mainWindow)
{
Q_ASSERT(m_pSettings);
@@ -114,6 +115,7 @@ void ServerConfig::saveSettings()
settings().setValue("switchDoubleTap", switchDoubleTap());
settings().setValue("switchCornerSize", switchCornerSize());
settings().setValue("ignoreAutoConfigClient", ignoreAutoConfigClient());
+ settings().setValue("enableDragAndDrop", enableDragAndDrop());
writeSettings(settings(), switchCorners(), "switchCorner");
@@ -157,6 +159,7 @@ void ServerConfig::loadSettings()
setSwitchDoubleTap(settings().value("switchDoubleTap", 250).toInt());
setSwitchCornerSize(settings().value("switchCornerSize").toInt());
setIgnoreAutoConfigClient(settings().value("ignoreAutoConfigClient").toBool());
+ setEnableDragAndDrop(settings().value("enableDragAndDrop", true).toBool());
readSettings(settings(), switchCorners(), "switchCorner", false, NumSwitchCorners);
diff --git a/src/gui/src/ServerConfig.h b/src/gui/src/ServerConfig.h
index 9600b35d..15214a7e 100644
--- a/src/gui/src/ServerConfig.h
+++ b/src/gui/src/ServerConfig.h
@@ -61,6 +61,7 @@ class ServerConfig : public BaseConfig
const QList& switchCorners() const { return m_SwitchCorners; }
const HotkeyList& hotkeys() const { return m_Hotkeys; }
bool ignoreAutoConfigClient() const { return m_IgnoreAutoConfigClient; }
+ bool enableDragAndDrop() const { return m_EnableDragAndDrop; }
void saveSettings();
void loadSettings();
@@ -88,6 +89,7 @@ class ServerConfig : public BaseConfig
void setSwitchCorner(int c, bool on) { m_SwitchCorners[c] = on; }
void setSwitchCornerSize(int val) { m_SwitchCornerSize = val; }
void setIgnoreAutoConfigClient(bool on) { m_IgnoreAutoConfigClient = on; }
+ void setEnableDragAndDrop(bool on) { m_EnableDragAndDrop = on; }
QList& switchCorners() { return m_SwitchCorners; }
HotkeyList& hotkeys() { return m_Hotkeys; }
@@ -119,6 +121,7 @@ class ServerConfig : public BaseConfig
HotkeyList m_Hotkeys;
QString m_ServerName;
bool m_IgnoreAutoConfigClient;
+ bool m_EnableDragAndDrop;
MainWindow* m_pMainWindow;
};
diff --git a/src/gui/src/ServerConfigDialog.cpp b/src/gui/src/ServerConfigDialog.cpp
index 3fc04fab..501c758c 100644
--- a/src/gui/src/ServerConfigDialog.cpp
+++ b/src/gui/src/ServerConfigDialog.cpp
@@ -56,6 +56,8 @@ ServerConfigDialog::ServerConfigDialog(QWidget* parent, ServerConfig& config, co
m_pCheckBoxIgnoreAutoConfigClient->setChecked(serverConfig().ignoreAutoConfigClient());
+ m_pCheckBoxEnableDragAndDrop->setChecked(serverConfig().enableDragAndDrop());
+
foreach(const Hotkey& hotkey, serverConfig().hotkeys())
m_pListHotkeys->addItem(hotkey.text());
@@ -97,6 +99,7 @@ void ServerConfigDialog::accept()
serverConfig().setSwitchCorner(BaseConfig::BottomRight, m_pCheckBoxCornerBottomRight->isChecked());
serverConfig().setSwitchCornerSize(m_pSpinBoxSwitchCornerSize->value());
serverConfig().setIgnoreAutoConfigClient(m_pCheckBoxIgnoreAutoConfigClient->isChecked());
+ serverConfig().setEnableDragAndDrop(m_pCheckBoxEnableDragAndDrop->isChecked());
// now that the dialog has been accepted, copy the new server config to the original one,
// which is a reference to the one in MainWindow.
diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp
index 52258d69..ad586809 100644
--- a/src/lib/client/Client.cpp
+++ b/src/lib/client/Client.cpp
@@ -273,6 +273,7 @@ Client::leave()
if (m_sendClipboardThread != NULL) {
StreamChunker::interruptClipboard();
+ m_sendClipboardThread->wait();
m_sendClipboardThread = NULL;
}
diff --git a/src/lib/net/TCPSocket.cpp b/src/lib/net/TCPSocket.cpp
index 91655ae3..ab8d189b 100644
--- a/src/lib/net/TCPSocket.cpp
+++ b/src/lib/net/TCPSocket.cpp
@@ -469,34 +469,47 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job,
}
bool needNewJob = false;
- static UInt32 s_retryOutputBufferSize = 0;
+
+ static bool s_retry = false;
+ static int s_retrySize = 0;
+ static void* s_staticBuffer = NULL;
if (write) {
try {
// write data
- int buffSize = m_outputBuffer.getSize();
+ int bufferSize = 0;
int bytesWrote = 0;
int status = 0;
- if (s_retryOutputBufferSize > 0) {
- buffSize = s_retryOutputBufferSize;
+ if (s_retry) {
+ bufferSize = s_retrySize;
}
+ else {
+ bufferSize = m_outputBuffer.getSize();
+ s_staticBuffer = malloc(bufferSize);
+ memcpy(s_staticBuffer, m_outputBuffer.peek(bufferSize), bufferSize);
+ }
- const void* buffer = m_outputBuffer.peek(buffSize);
+ if (bufferSize == 0) {
+ return job;
+ }
if (isSecure()) {
if (isSecureReady()) {
- status = secureWrite(buffer, buffSize, bytesWrote);
+ status = secureWrite(s_staticBuffer, bufferSize, bytesWrote);
if (status > 0) {
- s_retryOutputBufferSize = 0;
-
+ s_retry = false;
+ bufferSize = 0;
+ free(s_staticBuffer);
+ s_staticBuffer = NULL;
}
else if (status < 0) {
return NULL;
}
else if (status == 0) {
- s_retryOutputBufferSize = buffSize;
- return job;
+ s_retry = true;
+ s_retrySize = bufferSize;
+ return newJob();
}
}
else {
@@ -504,7 +517,10 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job,
}
}
else {
- bytesWrote = (UInt32)ARCH->writeSocket(m_socket, buffer, buffSize);
+ bytesWrote = (UInt32)ARCH->writeSocket(m_socket, s_staticBuffer, bufferSize);
+ bufferSize = 0;
+ free(s_staticBuffer);
+ s_staticBuffer = NULL;
}
// discard written data
@@ -559,7 +575,7 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job,
return NULL;
}
else if (status == 0) {
- return job;
+ return newJob();
}
}
else {
diff --git a/src/lib/net/TCPSocket.h b/src/lib/net/TCPSocket.h
index c30a2d7e..b4c833ba 100644
--- a/src/lib/net/TCPSocket.h
+++ b/src/lib/net/TCPSocket.h
@@ -96,6 +96,10 @@ private:
serviceConnected(ISocketMultiplexerJob*,
bool, bool, bool);
+protected:
+ bool m_readable;
+ bool m_writable;
+
private:
Mutex m_mutex;
ArchSocket m_socket;
@@ -103,8 +107,6 @@ private:
StreamBuffer m_outputBuffer;
CondVar m_flushed;
bool m_connected;
- bool m_readable;
- bool m_writable;
IEventQueue* m_events;
SocketMultiplexer* m_socketMultiplexer;
};
diff --git a/src/lib/plugin/ns/SecureSocket.cpp b/src/lib/plugin/ns/SecureSocket.cpp
index 639220ed..b753188a 100644
--- a/src/lib/plugin/ns/SecureSocket.cpp
+++ b/src/lib/plugin/ns/SecureSocket.cpp
@@ -417,14 +417,21 @@ SecureSocket::checkResult(int status, int& retry)
break;
case SSL_ERROR_WANT_READ:
+ m_readable = true;
+ retry++;
+ LOG((CLOG_DEBUG2 "want to read, error=%d, attempt=%d", errorCode, retry));
+ break;
+
case SSL_ERROR_WANT_WRITE:
+ m_writable = true;
+ retry++;
+ LOG((CLOG_DEBUG2 "want to write, error=%d, attempt=%d", errorCode, retry));
+ break;
+
case SSL_ERROR_WANT_CONNECT:
case SSL_ERROR_WANT_ACCEPT:
- // it seems like these sort of errors are part of openssl's normal behavior,
- // so we should expect a very high amount of these. sleeping doesn't seem to
- // help... maybe you just have to swallow the errors (yuck).
retry++;
- LOG((CLOG_DEBUG2 "passive ssl error, error=%d, attempt=%d", errorCode, retry));
+ LOG((CLOG_DEBUG2 "want to connect, error=%d, attempt=%d", errorCode, retry));
break;
case SSL_ERROR_SYSCALL:
diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp
index 4420b2dd..1f04489c 100644
--- a/src/lib/server/Server.cpp
+++ b/src/lib/server/Server.cpp
@@ -509,6 +509,8 @@ Server::switchScreen(BaseClientProxy* dst,
// clipboard data could be corrupted on the other side
if (m_sendClipboardThread != NULL) {
StreamChunker::interruptClipboard();
+ m_sendClipboardThread->wait();
+ m_sendClipboardThread = NULL;
}
// send the clipboard data to new active screen
diff --git a/src/setup/win32/Product.wxs b/src/setup/win32/Product.wxs
index 6cdac1b2..c47aa063 100644
--- a/src/setup/win32/Product.wxs
+++ b/src/setup/win32/Product.wxs
@@ -112,13 +112,13 @@
-
-
-
-
-
+
+
+
+
+
-
+