diff --git a/ChangeLog b/ChangeLog
index 7855debe6..61473aa5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,7 +15,7 @@ Enhancements:
- #7026 Update the way we package OpenSSL for Windows build
- #7035 Add Fedora 34 build
- #7037 Add Ubuntu 21.04 build
-- #7030 | #7041 Add user nofication for secure input on Mac
+- #7030 | #7041 | #7043 Add user notification for secure input on Mac
===========
v1.14.0-stable
diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp
index a3bcff046..0ca688cf7 100644
--- a/src/lib/client/Client.cpp
+++ b/src/lib/client/Client.cpp
@@ -730,7 +730,14 @@ Client::handleHello(const Event&, void*)
// check versions
LOG((CLOG_DEBUG1 "got hello version %d.%d", major, minor));
- if (major < kProtocolMajorVersion ||
+ SInt16 helloBackMajor = kProtocolMajorVersion;
+ SInt16 helloBackMinor = kProtocolMinorVersion;
+ if (major == kProtocolMajorVersion && minor == 6 && kProtocolMinorVersion == 7) {
+ //because 1.6 and 1.7 is comptable - downgrading protocol for server
+ LOG((CLOG_NOTE "Downgrading protocol version for server"));
+ helloBackMinor = minor;
+ }
+ else if (major < kProtocolMajorVersion ||
(major == kProtocolMajorVersion && minor < kProtocolMinorVersion)) {
sendConnectionFailedEvent(XIncompatibleClient(major, minor).what());
cleanupTimer();
@@ -739,10 +746,10 @@ Client::handleHello(const Event&, void*)
}
// say hello back
- LOG((CLOG_DEBUG1 "say hello version %d.%d", kProtocolMajorVersion, kProtocolMinorVersion));
+ LOG((CLOG_DEBUG1 "say hello version %d.%d", helloBackMajor, helloBackMinor));
ProtocolUtil::writef(m_stream, kMsgHelloBack,
- kProtocolMajorVersion,
- kProtocolMinorVersion, &m_name);
+ helloBackMajor,
+ helloBackMinor, & m_name);
// now connected but waiting to complete handshake
setupScreen();
diff --git a/src/lib/client/ServerProxy.cpp b/src/lib/client/ServerProxy.cpp
index 177baa6d5..3d431055b 100644
--- a/src/lib/client/ServerProxy.cpp
+++ b/src/lib/client/ServerProxy.cpp
@@ -26,6 +26,7 @@
#include "synergy/ProtocolUtil.h"
#include "synergy/option_types.h"
#include "synergy/protocol_types.h"
+#include "synergy/AppUtil.h"
#include "io/IStream.h"
#include "base/Log.h"
#include "base/IEventQueue.h"
@@ -129,8 +130,10 @@ ServerProxy::handleData(const Event&, void*)
case kUnknown:
LOG((CLOG_ERR "invalid message from server: %c%c%c%c", code[0], code[1], code[2], code[3]));
- m_client->disconnect("invalid message from server");
- return;
+ // not possible to determine message boundaries
+ // read the whole stream to discard unkonwn data
+ while (m_stream->read(nullptr, 4));
+ break;
case kDisconnect:
return;
@@ -303,6 +306,9 @@ ServerProxy::parseMessage(const UInt8* code)
else if (memcmp(code, kMsgDDragInfo, 4) == 0) {
dragInfoReceived();
}
+ else if (memcmp(code, kMsgDSecureInputNotification, 4) == 0) {
+ secureInputNotification();
+ }
else if (memcmp(code, kMsgCClose, 4) == 0) {
// server wants us to hangup
@@ -906,3 +912,19 @@ ServerProxy::sendDragInfo(UInt32 fileCount, const char* info, size_t size)
String data(info, size);
ProtocolUtil::writef(m_stream, kMsgDDragInfo, fileCount, &data);
}
+
+void
+ServerProxy::secureInputNotification()
+{
+ String app;
+ ProtocolUtil::readf(m_stream, kMsgDSecureInputNotification + 4, &app);
+
+ String secureInputNotificationBody =
+ "'Secure input' enabled by " + app + " on the server. " \
+ "To fix the keyboard, " + app + " must be closed.";
+
+ // display this notification on the client
+ AppUtil::instance().showNotification(
+ "The keyboard may stop working.",
+ secureInputNotificationBody);
+}
diff --git a/src/lib/client/ServerProxy.h b/src/lib/client/ServerProxy.h
index 463bab790..e9bdae8bb 100644
--- a/src/lib/client/ServerProxy.h
+++ b/src/lib/client/ServerProxy.h
@@ -112,6 +112,7 @@ private:
void fileChunkReceived();
void dragInfoReceived();
void handleClipboardSendingEvent(const Event&, void*);
+ void secureInputNotification();
private:
typedef EResult (ServerProxy::*MessageParser)(const UInt8*);
diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp
index acfc53494..73d1ecd9a 100644
--- a/src/lib/platform/MSWindowsScreen.cpp
+++ b/src/lib/platform/MSWindowsScreen.cpp
@@ -1988,10 +1988,11 @@ MSWindowsScreen::getDropTarget() const
return m_desktopPath;
}
-void
-MSWindowsScreen::createNotification(const String& title, const String& content) const
+String
+MSWindowsScreen::getSecureInputApp() const
{
- // TODO: implement notification
+ // ignore on Windows
+ return "";
}
bool
diff --git a/src/lib/platform/MSWindowsScreen.h b/src/lib/platform/MSWindowsScreen.h
index 8f2447c90..b8a6e2536 100644
--- a/src/lib/platform/MSWindowsScreen.h
+++ b/src/lib/platform/MSWindowsScreen.h
@@ -139,7 +139,7 @@ public:
virtual String& getDraggingFilename();
virtual const String&
getDropTarget() const;
- void createNotification(const String& title, const String& content) const override;
+ String getSecureInputApp() const override;
protected:
// IPlatformScreen overrides
diff --git a/src/lib/platform/OSXScreen.h b/src/lib/platform/OSXScreen.h
index 1360b96a1..397f61c0b 100644
--- a/src/lib/platform/OSXScreen.h
+++ b/src/lib/platform/OSXScreen.h
@@ -59,55 +59,55 @@ public:
IEventQueue* getEvents() const { return m_events; }
// IScreen overrides
- virtual void* getEventTarget() const;
- virtual bool getClipboard(ClipboardID id, IClipboard*) const;
- virtual void getShape(SInt32& x, SInt32& y,
- SInt32& width, SInt32& height) const;
- virtual void getCursorPos(SInt32& x, SInt32& y) const;
+ void* getEventTarget() const override;
+ bool getClipboard(ClipboardID id, IClipboard*) const override;
+ void getShape(SInt32& x, SInt32& y,
+ SInt32& width, SInt32& height) const override;
+ void getCursorPos(SInt32& x, SInt32& y) const override;
// IPrimaryScreen overrides
- virtual void reconfigure(UInt32 activeSides);
- virtual void warpCursor(SInt32 x, SInt32 y);
- virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask);
- virtual void unregisterHotKey(UInt32 id);
- virtual void fakeInputBegin();
- virtual void fakeInputEnd();
- virtual SInt32 getJumpZoneSize() const;
- virtual bool isAnyMouseButtonDown(UInt32& buttonID) const;
- virtual void getCursorCenter(SInt32& x, SInt32& y) const;
+ void reconfigure(UInt32 activeSides) override;
+ void warpCursor(SInt32 x, SInt32 y) override;
+ UInt32 registerHotKey(KeyID key, KeyModifierMask mask) override;
+ void unregisterHotKey(UInt32 id) override;
+ void fakeInputBegin() override;
+ void fakeInputEnd() override;
+ SInt32 getJumpZoneSize() const override;
+ bool isAnyMouseButtonDown(UInt32& buttonID) const override;
+ void getCursorCenter(SInt32& x, SInt32& y) const override;
// ISecondaryScreen overrides
- virtual void fakeMouseButton(ButtonID id, bool press);
- virtual void fakeMouseMove(SInt32 x, SInt32 y);
- virtual void fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const;
- virtual void fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const;
+ void fakeMouseButton(ButtonID id, bool press) override;
+ void fakeMouseMove(SInt32 x, SInt32 y) override;
+ void fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const override;
+ void fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const override;
// IPlatformScreen overrides
- virtual void enable();
- virtual void disable();
- virtual void enter();
- virtual bool leave();
- virtual bool setClipboard(ClipboardID, const IClipboard*);
- virtual void checkClipboards();
- virtual void openScreensaver(bool notify);
- virtual void closeScreensaver();
- virtual void screensaver(bool activate);
- virtual void resetOptions();
- virtual void setOptions(const OptionsList& options);
- virtual void setSequenceNumber(UInt32);
- virtual bool isPrimary() const;
- virtual void fakeDraggingFiles(DragFileList fileList);
- virtual String& getDraggingFilename();
+ void enable() override;
+ void disable() override;
+ void enter() override;
+ bool leave() override;
+ bool setClipboard(ClipboardID, const IClipboard*) override;
+ void checkClipboards() override;
+ void openScreensaver(bool notify) override;
+ void closeScreensaver() override;
+ void screensaver(bool activate) override;
+ void resetOptions() override;
+ void setOptions(const OptionsList& options) override;
+ void setSequenceNumber(UInt32) override;
+ bool isPrimary() const override;
+ void fakeDraggingFiles(DragFileList fileList) override;
+ String& getDraggingFilename() override;
+ String getSecureInputApp() const override;
- const String& getDropTarget() const { return m_dropTarget; }
- void waitForCarbonLoop() const;
- void createNotification(const String& title, const String& content) const override;
+ const String& getDropTarget() const override { return m_dropTarget; }
+ void waitForCarbonLoop() const;
protected:
// IPlatformScreen overrides
- virtual void handleSystemEvent(const Event&, void*);
- virtual void updateButtons();
- virtual IKeyState* getKeyState() const;
+ void handleSystemEvent(const Event&, void*) override;
+ void updateButtons() override;
+ IKeyState* getKeyState() const override;
private:
bool updateScreenShape();
@@ -203,8 +203,6 @@ private:
static char* CFStringRefToUTF8String(CFStringRef aString);
void getDropTargetThread(void*);
-
- void createSecureInputNotification();
private:
struct HotKeyItem {
diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm
old mode 100755
new mode 100644
index f82ede88c..a81e54cf1
--- a/src/lib/platform/OSXScreen.mm
+++ b/src/lib/platform/OSXScreen.mm
@@ -59,6 +59,7 @@ enum {
kCarbonLoopWaitTimeout = 10
};
+void createSecureInputNotification();
int getSecureInputEventPID();
String getProcessName(int pid);
@@ -2158,26 +2159,31 @@ OSXScreen::waitForCarbonLoop() const
}
-void
-OSXScreen::createNotification(const String& title, const String& content) const
+String
+OSXScreen::getSecureInputApp() const
{
- LOG((CLOG_INFO "OSX Notification: %s|%s", title.c_str(), content.c_str()));
+ if(IsSecureEventInputEnabled()) {
+ int secureInputProcessPID = getSecureInputEventPID();
+ if(secureInputProcessPID == 0) return "unknown";
+ return getProcessName(secureInputProcessPID);
+ }
+ return "";
}
void
-OSXScreen::createSecureInputNotification()
+createSecureInputNotification()
{
- std::string secureInputNotificationBody =
- "Secure input was enabled in your system. " \
- "Synergy may not be able to send keyboard strokes. ";
-
int secureInputProcessPID = getSecureInputEventPID();
- std::string infringingProcessName = getProcessName(secureInputProcessPID);
- if(secureInputProcessPID == 0) infringingProcessName = "unknown";
- secureInputNotificationBody += "Infringing process is " + infringingProcessName;
+ String app = getProcessName(secureInputProcessPID);
+ if(secureInputProcessPID == 0) app = "unknown";
- createNotification(
- "Keyboard may not work correctly",
+ String secureInputNotificationBody =
+ "'Secure input' enabled by " + app + ". " \
+ "Close " + app + " to continue using keyboards on the clients.";
+
+ // display this notification on the server
+ AppUtil::instance().showNotification(
+ "The client keyboards may stop working.",
secureInputNotificationBody);
}
diff --git a/src/lib/platform/XWindowsScreen.cpp b/src/lib/platform/XWindowsScreen.cpp
index 8bbde462e..560d3c7ac 100644
--- a/src/lib/platform/XWindowsScreen.cpp
+++ b/src/lib/platform/XWindowsScreen.cpp
@@ -475,10 +475,11 @@ XWindowsScreen::isPrimary() const
return m_isPrimary;
}
-void
-XWindowsScreen::createNotification(const String& title, const String& content) const
+String
+XWindowsScreen::getSecureInputApp() const
{
- // TODO: implement notification
+ // ignore on Linux
+ return "";
}
void*
diff --git a/src/lib/platform/XWindowsScreen.h b/src/lib/platform/XWindowsScreen.h
index a0d401a0a..19689a2fc 100644
--- a/src/lib/platform/XWindowsScreen.h
+++ b/src/lib/platform/XWindowsScreen.h
@@ -84,7 +84,7 @@ public:
virtual void setOptions(const OptionsList& options);
virtual void setSequenceNumber(UInt32);
virtual bool isPrimary() const;
- void createNotification(const String& title, const String& content) const override;
+ String getSecureInputApp() const override;
protected:
// IPlatformScreen overrides
diff --git a/src/lib/server/BaseClientProxy.h b/src/lib/server/BaseClientProxy.h
index 22076c7cb..0e6556b71 100644
--- a/src/lib/server/BaseClientProxy.h
+++ b/src/lib/server/BaseClientProxy.h
@@ -89,6 +89,8 @@ public:
virtual void sendDragInfo(UInt32 fileCount, const char* info,
size_t size) = 0;
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0;
+ virtual String getSecureInputApp() const = 0;
+ virtual void secureInputNotification(const String& app) const = 0;
virtual String getName() const;
virtual synergy::IStream*
getStream() const = 0;
diff --git a/src/lib/server/ClientProxy.h b/src/lib/server/ClientProxy.h
index f978783e3..283f70be7 100644
--- a/src/lib/server/ClientProxy.h
+++ b/src/lib/server/ClientProxy.h
@@ -56,40 +56,41 @@ public:
/*!
Returns the original stream passed to the c'tor.
*/
- synergy::IStream* getStream() const;
+ synergy::IStream* getStream() const override;
//@}
// IScreen
- virtual void* getEventTarget() const;
- virtual bool getClipboard(ClipboardID id, IClipboard*) const = 0;
- virtual void getShape(SInt32& x, SInt32& y,
- SInt32& width, SInt32& height) const = 0;
- virtual void getCursorPos(SInt32& x, SInt32& y) const = 0;
+ void* getEventTarget() const override;
+ bool getClipboard(ClipboardID id, IClipboard*) const override = 0;
+ void getShape(SInt32& x, SInt32& y,
+ SInt32& width, SInt32& height) const override = 0;
+ void getCursorPos(SInt32& x, SInt32& y) const override = 0;
// IClient overrides
- virtual void enter(SInt32 xAbs, SInt32 yAbs,
+ void enter(SInt32 xAbs, SInt32 yAbs,
UInt32 seqNum, KeyModifierMask mask,
- bool forScreensaver) = 0;
- virtual bool leave() = 0;
- virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
- virtual void grabClipboard(ClipboardID) = 0;
- virtual void setClipboardDirty(ClipboardID, bool) = 0;
- virtual void keyDown(KeyID, KeyModifierMask, KeyButton) = 0;
- virtual void keyRepeat(KeyID, KeyModifierMask,
- SInt32 count, KeyButton) = 0;
- virtual void keyUp(KeyID, KeyModifierMask, KeyButton) = 0;
- virtual void mouseDown(ButtonID) = 0;
- virtual void mouseUp(ButtonID) = 0;
- virtual void mouseMove(SInt32 xAbs, SInt32 yAbs) = 0;
- virtual void mouseRelativeMove(SInt32 xRel, SInt32 yRel) = 0;
- virtual void mouseWheel(SInt32 xDelta, SInt32 yDelta) = 0;
- virtual void screensaver(bool activate) = 0;
- virtual void resetOptions() = 0;
- virtual void setOptions(const OptionsList& options) = 0;
- virtual void sendDragInfo(UInt32 fileCount, const char* info,
- size_t size) = 0;
- virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0;
+ bool forScreensaver) override = 0;
+ bool leave() override = 0;
+ void setClipboard(ClipboardID, const IClipboard*) override = 0;
+ void grabClipboard(ClipboardID) override = 0;
+ void setClipboardDirty(ClipboardID, bool) override = 0;
+ void keyDown(KeyID, KeyModifierMask, KeyButton) override = 0;
+ void keyRepeat(KeyID, KeyModifierMask,
+ SInt32 count, KeyButton) override = 0;
+ void keyUp(KeyID, KeyModifierMask, KeyButton) override = 0;
+ void mouseDown(ButtonID) override = 0;
+ void mouseUp(ButtonID) override = 0;
+ void mouseMove(SInt32 xAbs, SInt32 yAbs) override = 0;
+ void mouseRelativeMove(SInt32 xRel, SInt32 yRel) override = 0;
+ void mouseWheel(SInt32 xDelta, SInt32 yDelta) override = 0;
+ void screensaver(bool activate) override = 0;
+ void resetOptions() override = 0;
+ void setOptions(const OptionsList& options) override = 0;
+ void sendDragInfo(UInt32 fileCount, const char* info,
+ size_t size) override = 0;
+ void fileChunkSending(UInt8 mark, char* data, size_t dataSize) override = 0;
+ void secureInputNotification(const String& app) const override = 0;
private:
synergy::IStream* m_stream;
diff --git a/src/lib/server/ClientProxy1_0.cpp b/src/lib/server/ClientProxy1_0.cpp
index 429973f18..5aee1278f 100644
--- a/src/lib/server/ClientProxy1_0.cpp
+++ b/src/lib/server/ClientProxy1_0.cpp
@@ -150,8 +150,9 @@ ClientProxy1_0::handleData(const Event&, void*)
LOG((CLOG_DEBUG2 "msg from \"%s\": %c%c%c%c", getName().c_str(), code[0], code[1], code[2], code[3]));
if (!(this->*m_parser)(code)) {
LOG((CLOG_ERR "invalid message from client \"%s\": %c%c%c%c", getName().c_str(), code[0], code[1], code[2], code[3]));
- disconnect();
- return;
+ // not possible to determine message boundaries
+ // read the whole stream to discard unkonwn data
+ while (getStream()->read(nullptr, 4));
}
// next message
@@ -365,6 +366,21 @@ ClientProxy1_0::fileChunkSending(UInt8 mark, char* data, size_t dataSize)
LOG((CLOG_DEBUG "fileChunkSending not supported"));
}
+String
+ClientProxy1_0::getSecureInputApp() const
+{
+ // ignore -- not supported on clients
+ LOG((CLOG_DEBUG "getSecureInputApp not supported"));
+ return "";
+}
+
+void
+ClientProxy1_0::secureInputNotification(const String& app) const
+{
+ // ignore -- not supported in protocol 1.0
+ LOG((CLOG_DEBUG "secureInputNotification not supported"));
+}
+
void
ClientProxy1_0::screensaver(bool on)
{
diff --git a/src/lib/server/ClientProxy1_0.h b/src/lib/server/ClientProxy1_0.h
index edd3ec6f4..ce122332b 100644
--- a/src/lib/server/ClientProxy1_0.h
+++ b/src/lib/server/ClientProxy1_0.h
@@ -38,33 +38,35 @@ public:
ClientProxy1_0& operator=(ClientProxy1_0 &&) =delete;
// IScreen
- virtual bool getClipboard(ClipboardID id, IClipboard*) const;
- virtual void getShape(SInt32& x, SInt32& y,
- SInt32& width, SInt32& height) const;
- virtual void getCursorPos(SInt32& x, SInt32& y) const;
+ bool getClipboard(ClipboardID id, IClipboard*) const override;
+ void getShape(SInt32& x, SInt32& y,
+ SInt32& width, SInt32& height) const override;
+ void getCursorPos(SInt32& x, SInt32& y) const override;
// IClient overrides
- virtual void enter(SInt32 xAbs, SInt32 yAbs,
+ void enter(SInt32 xAbs, SInt32 yAbs,
UInt32 seqNum, KeyModifierMask mask,
- bool forScreensaver);
- virtual bool leave();
- virtual void setClipboard(ClipboardID, const IClipboard*);
- virtual void grabClipboard(ClipboardID);
- virtual void setClipboardDirty(ClipboardID, bool);
- virtual void keyDown(KeyID, KeyModifierMask, KeyButton);
- virtual void keyRepeat(KeyID, KeyModifierMask,
- SInt32 count, KeyButton);
- virtual void keyUp(KeyID, KeyModifierMask, KeyButton);
- virtual void mouseDown(ButtonID);
- virtual void mouseUp(ButtonID);
- virtual void mouseMove(SInt32 xAbs, SInt32 yAbs);
- virtual void mouseRelativeMove(SInt32 xRel, SInt32 yRel);
- virtual void mouseWheel(SInt32 xDelta, SInt32 yDelta);
- virtual void screensaver(bool activate);
- virtual void resetOptions();
- virtual void setOptions(const OptionsList& options);
- virtual void sendDragInfo(UInt32 fileCount, const char* info, size_t size);
- virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize);
+ bool forScreensaver) override;
+ bool leave() override;
+ void setClipboard(ClipboardID, const IClipboard*) override;
+ void grabClipboard(ClipboardID) override;
+ void setClipboardDirty(ClipboardID, bool) override;
+ void keyDown(KeyID, KeyModifierMask, KeyButton) override;
+ void keyRepeat(KeyID, KeyModifierMask,
+ SInt32 count, KeyButton) override;
+ void keyUp(KeyID, KeyModifierMask, KeyButton) override;
+ void mouseDown(ButtonID) override;
+ void mouseUp(ButtonID) override;
+ void mouseMove(SInt32 xAbs, SInt32 yAbs) override;
+ void mouseRelativeMove(SInt32 xRel, SInt32 yRel) override;
+ void mouseWheel(SInt32 xDelta, SInt32 yDelta) override;
+ void screensaver(bool activate) override;
+ void resetOptions() override;
+ void setOptions(const OptionsList& options) override;
+ void sendDragInfo(UInt32 fileCount, const char* info, size_t size) override;
+ void fileChunkSending(UInt8 mark, char* data, size_t dataSize) override;
+ String getSecureInputApp() const override;
+ void secureInputNotification(const String& app) const override;
protected:
virtual bool parseHandshakeMessage(const UInt8* code);
diff --git a/src/lib/server/ClientProxy1_7.cpp b/src/lib/server/ClientProxy1_7.cpp
new file mode 100644
index 000000000..bd51778e8
--- /dev/null
+++ b/src/lib/server/ClientProxy1_7.cpp
@@ -0,0 +1,41 @@
+/*
+ * synergy -- mouse and keyboard sharing utility
+ * Copyright (C) 2015-2016 Symless Ltd.
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file LICENSE that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "server/ClientProxy1_7.h"
+#include "server/Server.h"
+#include "synergy/AppUtil.h"
+#include "synergy/ProtocolUtil.h"
+#include "base/TMethodEventJob.h"
+#include "base/Log.h"
+
+//
+// ClientProxy1_7
+//
+
+ClientProxy1_7::ClientProxy1_7(const String& name, synergy::IStream* stream, Server* server, IEventQueue* events) :
+ ClientProxy1_6(name, stream, server, events),
+ m_events(events)
+{
+
+}
+
+void
+ClientProxy1_7::secureInputNotification(const String& app) const
+{
+ LOG((CLOG_DEBUG2 "send secure input notification to \"%s\" %s", getName().c_str(), app.c_str()));
+ ProtocolUtil::writef(getStream(), kMsgDSecureInputNotification, &app);
+}
diff --git a/src/lib/server/ClientProxy1_7.h b/src/lib/server/ClientProxy1_7.h
new file mode 100644
index 000000000..04343edb7
--- /dev/null
+++ b/src/lib/server/ClientProxy1_7.h
@@ -0,0 +1,33 @@
+/*
+ * synergy -- mouse and keyboard sharing utility
+ * Copyright (C) 2015-2016 Symless Ltd.
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file LICENSE that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#include "server/ClientProxy1_6.h"
+
+//! Proxy for client implementing protocol version 1.7
+class ClientProxy1_7 : public ClientProxy1_6 {
+public:
+ ClientProxy1_7(const String& name, synergy::IStream* adoptedStream, Server* server, IEventQueue* events);
+ ~ClientProxy1_7() override = default;
+
+ void secureInputNotification(const String& app) const override;
+
+private:
+
+ IEventQueue* m_events;
+};
diff --git a/src/lib/server/ClientProxyUnknown.cpp b/src/lib/server/ClientProxyUnknown.cpp
index 7df67c0f1..3b7bfc802 100644
--- a/src/lib/server/ClientProxyUnknown.cpp
+++ b/src/lib/server/ClientProxyUnknown.cpp
@@ -26,6 +26,7 @@
#include "server/ClientProxy1_4.h"
#include "server/ClientProxy1_5.h"
#include "server/ClientProxy1_6.h"
+#include "server/ClientProxy1_7.h"
#include "synergy/protocol_types.h"
#include "synergy/ProtocolUtil.h"
#include "synergy/XSynergy.h"
@@ -232,6 +233,10 @@ ClientProxyUnknown::handleData(const Event&, void*)
case 6:
m_proxy = new ClientProxy1_6(name, m_stream, m_server, m_events);
break;
+
+ case 7:
+ m_proxy = new ClientProxy1_7(name, m_stream, m_server, m_events);
+ break;
}
}
diff --git a/src/lib/server/PrimaryClient.cpp b/src/lib/server/PrimaryClient.cpp
index 76731228e..63d40fe15 100644
--- a/src/lib/server/PrimaryClient.cpp
+++ b/src/lib/server/PrimaryClient.cpp
@@ -261,6 +261,18 @@ PrimaryClient::fileChunkSending(UInt8 mark, char* data, size_t dataSize)
// ignore
}
+String
+PrimaryClient::getSecureInputApp() const
+{
+ return m_screen->getSecureInputApp();
+}
+
+void
+PrimaryClient::secureInputNotification(const String& app) const
+{
+ // ignore
+}
+
void
PrimaryClient::resetOptions()
{
diff --git a/src/lib/server/PrimaryClient.h b/src/lib/server/PrimaryClient.h
index f63bbf5cf..a4d6fcc97 100644
--- a/src/lib/server/PrimaryClient.h
+++ b/src/lib/server/PrimaryClient.h
@@ -117,38 +117,40 @@ public:
virtual void disable();
// IScreen overrides
- virtual void* getEventTarget() const;
- virtual bool getClipboard(ClipboardID id, IClipboard*) const;
- virtual void getShape(SInt32& x, SInt32& y,
- SInt32& width, SInt32& height) const;
- virtual void getCursorPos(SInt32& x, SInt32& y) const;
+ void* getEventTarget() const override;
+ bool getClipboard(ClipboardID id, IClipboard*) const override;
+ void getShape(SInt32& x, SInt32& y,
+ SInt32& width, SInt32& height) const override;
+ void getCursorPos(SInt32& x, SInt32& y) const override;
// IClient overrides
- virtual void enter(SInt32 xAbs, SInt32 yAbs,
+ void enter(SInt32 xAbs, SInt32 yAbs,
UInt32 seqNum, KeyModifierMask mask,
- bool forScreensaver);
- virtual bool leave();
- virtual void setClipboard(ClipboardID, const IClipboard*);
- virtual void grabClipboard(ClipboardID);
- virtual void setClipboardDirty(ClipboardID, bool);
- virtual void keyDown(KeyID, KeyModifierMask, KeyButton);
- virtual void keyRepeat(KeyID, KeyModifierMask,
- SInt32 count, KeyButton);
- virtual void keyUp(KeyID, KeyModifierMask, KeyButton);
- virtual void mouseDown(ButtonID);
- virtual void mouseUp(ButtonID);
- virtual void mouseMove(SInt32 xAbs, SInt32 yAbs);
- virtual void mouseRelativeMove(SInt32 xRel, SInt32 yRel);
- virtual void mouseWheel(SInt32 xDelta, SInt32 yDelta);
- virtual void screensaver(bool activate);
- virtual void resetOptions();
- virtual void setOptions(const OptionsList& options);
- virtual void sendDragInfo(UInt32 fileCount, const char* info, size_t size);
- virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize);
+ bool forScreensaver) override;
+ bool leave() override;
+ void setClipboard(ClipboardID, const IClipboard*) override;
+ void grabClipboard(ClipboardID) override;
+ void setClipboardDirty(ClipboardID, bool) override;
+ void keyDown(KeyID, KeyModifierMask, KeyButton) override;
+ void keyRepeat(KeyID, KeyModifierMask,
+ SInt32 count, KeyButton) override;
+ void keyUp(KeyID, KeyModifierMask, KeyButton) override;
+ void mouseDown(ButtonID) override;
+ void mouseUp(ButtonID) override;
+ void mouseMove(SInt32 xAbs, SInt32 yAbs) override;
+ void mouseRelativeMove(SInt32 xRel, SInt32 yRel) override;
+ void mouseWheel(SInt32 xDelta, SInt32 yDelta) override;
+ void screensaver(bool activate) override;
+ void resetOptions() override;
+ void setOptions(const OptionsList& options) override;
+ void sendDragInfo(UInt32 fileCount, const char* info, size_t size) override;
+ void fileChunkSending(UInt8 mark, char* data, size_t dataSize) override;
+ String getSecureInputApp() const override;
+ void secureInputNotification(const String& app) const override;
- virtual synergy::IStream*
- getStream() const { return NULL; }
- bool isPrimary() const { return true; }
+ synergy::IStream*
+ getStream() const override { return nullptr; }
+ bool isPrimary() const override { return true; }
private:
synergy::Screen* m_screen;
bool m_clipboardDirty[kClipboardEnd];
diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp
index b620e401c..e56b83253 100644
--- a/src/lib/server/Server.cpp
+++ b/src/lib/server/Server.cpp
@@ -511,6 +511,14 @@ Server::switchScreen(BaseClientProxy* dst,
}
}
+
+#if defined(__APPLE__)
+ String secureInputApplication = m_active->getSecureInputApp();
+ if (m_active == m_primaryClient && secureInputApplication != "") {
+ dst->secureInputNotification(secureInputApplication);
+ }
+#endif
+
// cut over
m_active = dst;
diff --git a/src/lib/synergy/IAppUtil.h b/src/lib/synergy/IAppUtil.h
index 5f94e82d6..657bbfc82 100644
--- a/src/lib/synergy/IAppUtil.h
+++ b/src/lib/synergy/IAppUtil.h
@@ -20,6 +20,7 @@
#include "common/IInterface.h"
#include "synergy/IApp.h"
+#include "base/String.h"
class IAppUtil : public IInterface {
public:
@@ -28,4 +29,5 @@ public:
virtual int run(int argc, char** argv) = 0;
virtual void beforeAppExit() = 0;
virtual void startNode() = 0;
+ virtual void showNotification(const String& title, const String& text) const = 0;
};
diff --git a/src/lib/synergy/IPlatformScreen.h b/src/lib/synergy/IPlatformScreen.h
index ccb325f75..6a24019fa 100644
--- a/src/lib/synergy/IPlatformScreen.h
+++ b/src/lib/synergy/IPlatformScreen.h
@@ -133,11 +133,11 @@ public:
//! Change dragging status
virtual void setDraggingStarted(bool started) = 0;
- //! Send desktop user notification
+ //! Determine the name of the app causing a secure input state
/*!
- Creates a platform dependant user notificaiton using native APIs
+ On MacOS check which app causes a secure input state to be enabled. No alternative on other platforms
*/
- virtual void createNotification(const String& title, const String& content) const = 0;
+ virtual String getSecureInputApp() const = 0;
//@}
//! @name accessors
diff --git a/src/lib/synergy/Screen.cpp b/src/lib/synergy/Screen.cpp
index 15ab824f4..18245b840 100644
--- a/src/lib/synergy/Screen.cpp
+++ b/src/lib/synergy/Screen.cpp
@@ -522,10 +522,10 @@ Screen::leaveSecondary()
m_screen->fakeAllKeysUp();
}
-void
-Screen::createNotification(const String& title, const String& content) const
+String
+Screen::getSecureInputApp() const
{
- m_screen->createNotification(title, content);
+ return m_screen->getSecureInputApp();
}
}
diff --git a/src/lib/synergy/Screen.h b/src/lib/synergy/Screen.h
index 15bf2f096..34d5efa89 100644
--- a/src/lib/synergy/Screen.h
+++ b/src/lib/synergy/Screen.h
@@ -234,11 +234,11 @@ public:
void setEnableDragDrop(bool enabled);
- //! Send desktop user notification
+ //! Determine the name of the app causing a secure input state
/*!
- Creates a platform dependant user notificaiton using native APIs
+ On MacOS check which app causes a secure input state to be enabled. No alternative on other platforms
*/
- virtual void createNotification(const String& title, const String& content) const;
+ String getSecureInputApp() const;
//@}
//! @name accessors
diff --git a/src/lib/synergy/protocol_types.cpp b/src/lib/synergy/protocol_types.cpp
index e4834fce0..80f2fe4ec 100644
--- a/src/lib/synergy/protocol_types.cpp
+++ b/src/lib/synergy/protocol_types.cpp
@@ -18,36 +18,37 @@
#include "synergy/protocol_types.h"
-const char* kMsgHello = "Synergy%2i%2i";
-const char* kMsgHelloBack = "Synergy%2i%2i%s";
-const char* kMsgCNoop = "CNOP";
-const char* kMsgCClose = "CBYE";
-const char* kMsgCEnter = "CINN%2i%2i%4i%2i";
-const char* kMsgCLeave = "COUT";
-const char* kMsgCClipboard = "CCLP%1i%4i";
-const char* kMsgCScreenSaver = "CSEC%1i";
-const char* kMsgCResetOptions = "CROP";
-const char* kMsgCInfoAck = "CIAK";
-const char* kMsgCKeepAlive = "CALV";
-const char* kMsgDKeyDown = "DKDN%2i%2i%2i";
-const char* kMsgDKeyDown1_0 = "DKDN%2i%2i";
-const char* kMsgDKeyRepeat = "DKRP%2i%2i%2i%2i";
-const char* kMsgDKeyRepeat1_0 = "DKRP%2i%2i%2i";
-const char* kMsgDKeyUp = "DKUP%2i%2i%2i";
-const char* kMsgDKeyUp1_0 = "DKUP%2i%2i";
-const char* kMsgDMouseDown = "DMDN%1i";
-const char* kMsgDMouseUp = "DMUP%1i";
-const char* kMsgDMouseMove = "DMMV%2i%2i";
-const char* kMsgDMouseRelMove = "DMRM%2i%2i";
-const char* kMsgDMouseWheel = "DMWM%2i%2i";
-const char* kMsgDMouseWheel1_0 = "DMWM%2i";
-const char* kMsgDClipboard = "DCLP%1i%4i%1i%s";
-const char* kMsgDInfo = "DINF%2i%2i%2i%2i%2i%2i%2i";
-const char* kMsgDSetOptions = "DSOP%4I";
-const char* kMsgDFileTransfer = "DFTR%1i%s";
-const char* kMsgDDragInfo = "DDRG%2i%s";
-const char* kMsgQInfo = "QINF";
-const char* kMsgEIncompatible = "EICV%2i%2i";
-const char* kMsgEBusy = "EBSY";
-const char* kMsgEUnknown = "EUNK";
-const char* kMsgEBad = "EBAD";
+const char* const kMsgHello = "Synergy%2i%2i";
+const char* const kMsgHelloBack = "Synergy%2i%2i%s";
+const char* const kMsgCNoop = "CNOP";
+const char* const kMsgCClose = "CBYE";
+const char* const kMsgCEnter = "CINN%2i%2i%4i%2i";
+const char* const kMsgCLeave = "COUT";
+const char* const kMsgCClipboard = "CCLP%1i%4i";
+const char* const kMsgCScreenSaver = "CSEC%1i";
+const char* const kMsgCResetOptions = "CROP";
+const char* const kMsgCInfoAck = "CIAK";
+const char* const kMsgCKeepAlive = "CALV";
+const char* const kMsgDKeyDown = "DKDN%2i%2i%2i";
+const char* const kMsgDKeyDown1_0 = "DKDN%2i%2i";
+const char* const kMsgDKeyRepeat = "DKRP%2i%2i%2i%2i";
+const char* const kMsgDKeyRepeat1_0 = "DKRP%2i%2i%2i";
+const char* const kMsgDKeyUp = "DKUP%2i%2i%2i";
+const char* const kMsgDKeyUp1_0 = "DKUP%2i%2i";
+const char* const kMsgDMouseDown = "DMDN%1i";
+const char* const kMsgDMouseUp = "DMUP%1i";
+const char* const kMsgDMouseMove = "DMMV%2i%2i";
+const char* const kMsgDMouseRelMove = "DMRM%2i%2i";
+const char* const kMsgDMouseWheel = "DMWM%2i%2i";
+const char* const kMsgDMouseWheel1_0 = "DMWM%2i";
+const char* const kMsgDClipboard = "DCLP%1i%4i%1i%s";
+const char* const kMsgDInfo = "DINF%2i%2i%2i%2i%2i%2i%2i";
+const char* const kMsgDSetOptions = "DSOP%4I";
+const char* const kMsgDFileTransfer = "DFTR%1i%s";
+const char* const kMsgDDragInfo = "DDRG%2i%s";
+const char* const kMsgDSecureInputNotification = "SECN%s";
+const char* const kMsgQInfo = "QINF";
+const char* const kMsgEIncompatible = "EICV%2i%2i";
+const char* const kMsgEBusy = "EBSY";
+const char* const kMsgEUnknown = "EUNK";
+const char* const kMsgEBad = "EBAD";
diff --git a/src/lib/synergy/protocol_types.h b/src/lib/synergy/protocol_types.h
index e3f7f42c1..4fec0ac37 100644
--- a/src/lib/synergy/protocol_types.h
+++ b/src/lib/synergy/protocol_types.h
@@ -31,7 +31,7 @@
// 1.6: adds clipboard streaming
// NOTE: with new version, synergy minor version should increment
static const SInt16 kProtocolMajorVersion = 1;
-static const SInt16 kProtocolMinorVersion = 6;
+static const SInt16 kProtocolMinorVersion = 7;
// default contact port number
static const UInt16 kDefaultPort = 24800;
@@ -103,13 +103,13 @@ enum EDataReceived {
// say hello to client; primary -> secondary
// $1 = protocol major version number supported by server. $2 =
// protocol minor version number supported by server.
-extern const char* kMsgHello;
+extern const char* const kMsgHello;
// respond to hello from server; secondary -> primary
// $1 = protocol major version number supported by client. $2 =
// protocol minor version number supported by client. $3 = client
// name.
-extern const char* kMsgHelloBack;
+extern const char* const kMsgHelloBack;
//
@@ -117,10 +117,10 @@ extern const char* kMsgHelloBack;
//
// no operation; secondary -> primary
-extern const char* kMsgCNoop;
+extern const char* const kMsgCNoop;
// close connection; primary -> secondary
-extern const char* kMsgCClose;
+extern const char* const kMsgCClose;
// enter screen: primary -> secondary
// entering screen at screen position $1 = x, $2 = y. x,y are
@@ -130,7 +130,7 @@ extern const char* kMsgCClose;
// mask. this will have bits set for each toggle modifier key
// that is activated on entry to the screen. the secondary screen
// should adjust its toggle modifiers to reflect that state.
-extern const char* kMsgCEnter;
+extern const char* const kMsgCEnter;
// leave screen: primary -> secondary
// leaving screen. the secondary screen should send clipboard
@@ -139,28 +139,28 @@ extern const char* kMsgCEnter;
// not received a kMsgCClipboard for with a greater sequence
// number) and that were grabbed or have changed since the
// last leave.
-extern const char* kMsgCLeave;
+extern const char* const kMsgCLeave;
// grab clipboard: primary <-> secondary
// sent by screen when some other app on that screen grabs a
// clipboard. $1 = the clipboard identifier, $2 = sequence number.
// secondary screens must use the sequence number passed in the
// most recent kMsgCEnter. the primary always sends 0.
-extern const char* kMsgCClipboard;
+extern const char* const kMsgCClipboard;
// screensaver change: primary -> secondary
// screensaver on primary has started ($1 == 1) or closed ($1 == 0)
-extern const char* kMsgCScreenSaver;
+extern const char* const kMsgCScreenSaver;
// reset options: primary -> secondary
// client should reset all of its options to their defaults.
-extern const char* kMsgCResetOptions;
+extern const char* const kMsgCResetOptions;
// resolution change acknowledgment: primary -> secondary
// sent by primary in response to a secondary screen's kMsgDInfo.
// this is sent for every kMsgDInfo, whether or not the primary
// had sent a kMsgQInfo.
-extern const char* kMsgCInfoAck;
+extern const char* const kMsgCInfoAck;
// keep connection alive: primary <-> secondary
// sent by the server periodically to verify that connections are still
@@ -170,7 +170,7 @@ extern const char* kMsgCInfoAck;
// client doesn't receive these (or any message) periodically then it
// should disconnect from the server. the appropriate interval is
// defined by an option.
-extern const char* kMsgCKeepAlive;
+extern const char* const kMsgCKeepAlive;
//
// data codes
@@ -187,57 +187,57 @@ extern const char* kMsgCKeepAlive;
// the press. this can happen with combining (dead) keys or if
// the keyboard layouts are not identical and the user releases
// a modifier key before releasing the modified key.
-extern const char* kMsgDKeyDown;
+extern const char* const kMsgDKeyDown;
// key pressed 1.0: same as above but without KeyButton
-extern const char* kMsgDKeyDown1_0;
+extern const char* const kMsgDKeyDown1_0;
// key auto-repeat: primary -> secondary
// $1 = KeyID, $2 = KeyModifierMask, $3 = number of repeats, $4 = KeyButton
-extern const char* kMsgDKeyRepeat;
+extern const char* const kMsgDKeyRepeat;
// key auto-repeat 1.0: same as above but without KeyButton
-extern const char* kMsgDKeyRepeat1_0;
+extern const char* const kMsgDKeyRepeat1_0;
// key released: primary -> secondary
// $1 = KeyID, $2 = KeyModifierMask, $3 = KeyButton
-extern const char* kMsgDKeyUp;
+extern const char* const kMsgDKeyUp;
// key released 1.0: same as above but without KeyButton
-extern const char* kMsgDKeyUp1_0;
+extern const char* const kMsgDKeyUp1_0;
// mouse button pressed: primary -> secondary
// $1 = ButtonID
-extern const char* kMsgDMouseDown;
+extern const char* const kMsgDMouseDown;
// mouse button released: primary -> secondary
// $1 = ButtonID
-extern const char* kMsgDMouseUp;
+extern const char* const kMsgDMouseUp;
// mouse moved: primary -> secondary
// $1 = x, $2 = y. x,y are absolute screen coordinates.
-extern const char* kMsgDMouseMove;
+extern const char* const kMsgDMouseMove;
// relative mouse move: primary -> secondary
// $1 = dx, $2 = dy. dx,dy are motion deltas.
-extern const char* kMsgDMouseRelMove;
+extern const char* const kMsgDMouseRelMove;
// mouse scroll: primary -> secondary
// $1 = xDelta, $2 = yDelta. the delta should be +120 for one tick forward
// (away from the user) or right and -120 for one tick backward (toward
// the user) or left.
-extern const char* kMsgDMouseWheel;
+extern const char* const kMsgDMouseWheel;
// mouse vertical scroll: primary -> secondary
// like as kMsgDMouseWheel except only sends $1 = yDelta.
-extern const char* kMsgDMouseWheel1_0;
+extern const char* const kMsgDMouseWheel1_0;
// clipboard data: primary <-> secondary
// $2 = sequence number, $3 = mark $4 = clipboard data. the sequence number
// is 0 when sent by the primary. secondary screens should use the
// sequence number from the most recent kMsgCEnter. $1 = clipboard
// identifier.
-extern const char* kMsgDClipboard;
+extern const char* const kMsgDClipboard;
// client data: secondary -> primary
// $1 = coordinate of leftmost pixel on secondary screen,
@@ -253,25 +253,30 @@ extern const char* kMsgDClipboard;
// should ignore any kMsgDMouseMove messages until it receives a
// kMsgCInfoAck in order to prevent attempts to move the mouse off
// the new screen area.
-extern const char* kMsgDInfo;
+extern const char* const kMsgDInfo;
// set options: primary -> secondary
// client should set the given option/value pairs. $1 = option/value
// pairs.
-extern const char* kMsgDSetOptions;
+extern const char* const kMsgDSetOptions;
// file data: primary <-> secondary
// transfer file data. A mark is used in the first byte.
// 0 means the content followed is the file size.
// 1 means the content followed is the chunk data.
// 2 means the file transfer is finished.
-extern const char* kMsgDFileTransfer;
+extern const char* const kMsgDFileTransfer;
// drag infomation: primary <-> secondary
// transfer drag infomation. The first 2 bytes are used for storing
// the number of dragging objects. Then the following string consists
// of each object's directory.
-extern const char* kMsgDDragInfo;
+extern const char* const kMsgDDragInfo;
+
+// secure input notification: primary -> secondary
+// $1 = app. app only obtainable on MacOS since that's the only
+// platform facing secure input problems
+extern const char* const kMsgDSecureInputNotification;
//
// query codes
@@ -279,7 +284,7 @@ extern const char* kMsgDDragInfo;
// query screen info: primary -> secondary
// client should reply with a kMsgDInfo.
-extern const char* kMsgQInfo;
+extern const char* const kMsgQInfo;
//
@@ -288,19 +293,19 @@ extern const char* kMsgQInfo;
// incompatible versions: primary -> secondary
// $1 = major version of primary, $2 = minor version of primary.
-extern const char* kMsgEIncompatible;
+extern const char* const kMsgEIncompatible;
// name provided when connecting is already in use: primary -> secondary
-extern const char* kMsgEBusy;
+extern const char* const kMsgEBusy;
// unknown client: primary -> secondary
// name provided when connecting is not in primary's screen
// configuration map.
-extern const char* kMsgEUnknown;
+extern const char* const kMsgEUnknown;
// protocol violation: primary -> secondary
// primary should disconnect after sending this message.
-extern const char* kMsgEBad;
+extern const char* const kMsgEBad;
//
diff --git a/src/lib/synergy/unix/AppUtilUnix.cpp b/src/lib/synergy/unix/AppUtilUnix.cpp
index a052bfd92..7c2adec4d 100644
--- a/src/lib/synergy/unix/AppUtilUnix.cpp
+++ b/src/lib/synergy/unix/AppUtilUnix.cpp
@@ -18,6 +18,8 @@
#include "synergy/unix/AppUtilUnix.h"
#include "synergy/ArgsBase.h"
+#include "base/Log.h"
+#include "base/log_outputters.h"
AppUtilUnix::AppUtilUnix(IEventQueue* events)
{
@@ -44,3 +46,16 @@ AppUtilUnix::startNode()
{
app().startNode();
}
+
+void
+AppUtilUnix::showNotification(const String & title, const String & text) const
+{
+ LOG((CLOG_DEBUG "Showing notification. Title: \"%s\". Text: \"%s\"", title.c_str(), text.c_str()));
+#if WINAPI_XWINDOWS
+
+#elif WINAPI_CARBON
+ // synergys and synergyc are not allowed to send native notifications on MacOS
+ // instead ask main synergy process to show them instead
+ LOG((CLOG_INFO "OSX Notification: %s|%s", title.c_str(), text.c_str()));
+#endif
+}
diff --git a/src/lib/synergy/unix/AppUtilUnix.h b/src/lib/synergy/unix/AppUtilUnix.h
index ba235dcc6..63f5007c0 100644
--- a/src/lib/synergy/unix/AppUtilUnix.h
+++ b/src/lib/synergy/unix/AppUtilUnix.h
@@ -31,4 +31,5 @@ public:
int run(int argc, char** argv);
void startNode();
+ void showNotification(const String& title, const String& text) const override;
};
diff --git a/src/lib/synergy/win32/AppUtilWindows.cpp b/src/lib/synergy/win32/AppUtilWindows.cpp
index 7641c94c1..d1c64a467 100644
--- a/src/lib/synergy/win32/AppUtilWindows.cpp
+++ b/src/lib/synergy/win32/AppUtilWindows.cpp
@@ -180,3 +180,9 @@ AppUtilWindows::startNode()
{
app().startNode();
}
+
+void
+AppUtilWindows::showNotification(const String & title, const String & text) const
+{
+ LOG((CLOG_DEBUG "Showing notification. Title: \"%s\". Text: \"%s\"", title.c_str(), text.c_str()));
+}
diff --git a/src/lib/synergy/win32/AppUtilWindows.h b/src/lib/synergy/win32/AppUtilWindows.h
index 04b6d4242..007249bcd 100644
--- a/src/lib/synergy/win32/AppUtilWindows.h
+++ b/src/lib/synergy/win32/AppUtilWindows.h
@@ -54,6 +54,8 @@ public:
void startNode();
+ void showNotification(const String& title, const String& text) const override;
+
private:
AppExitMode m_exitMode;
IEventQueue* m_events;