Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar. Second, windows key processing was fixed. Previously pressing and release the key would only send a press event, locking the user onto the client window; also, the win32 server treated as a Meta modifier instead of a Super modifier, which broke any use of it as any kind of modifier key. Third, added hacks to support several key combinations on windows 95/98/me that are treated specially by windows, including Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any combination using the windows key like Win+E and Win+F but not Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which only happened when using a synergy server on windows) has been fixed; unfortunately the solution causes a lot of screen redraws for some reason. Finally, there's been a fix to clipboard handling that may or may not fix a problem where the clipboard would stop transferring between systems after a little while. I can't be sure if it fixes the problem because I can't reproduce the problem.
This commit is contained in:
parent
ef59307c16
commit
4521fe4990
|
@ -21,6 +21,8 @@
|
||||||
// CMSWindowsClipboard
|
// CMSWindowsClipboard
|
||||||
//
|
//
|
||||||
|
|
||||||
|
UINT CMSWindowsClipboard::s_ownershipFormat = 0;
|
||||||
|
|
||||||
CMSWindowsClipboard::CMSWindowsClipboard(HWND window) :
|
CMSWindowsClipboard::CMSWindowsClipboard(HWND window) :
|
||||||
m_window(window),
|
m_window(window),
|
||||||
m_time(0)
|
m_time(0)
|
||||||
|
@ -40,11 +42,16 @@ CMSWindowsClipboard::empty()
|
||||||
{
|
{
|
||||||
LOG((CLOG_DEBUG "empty clipboard"));
|
LOG((CLOG_DEBUG "empty clipboard"));
|
||||||
|
|
||||||
|
// empty the clipboard (and take ownership)
|
||||||
if (!EmptyClipboard()) {
|
if (!EmptyClipboard()) {
|
||||||
LOG((CLOG_DEBUG "failed to grab clipboard"));
|
LOG((CLOG_DEBUG "failed to grab clipboard"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mark clipboard as being owned by synergy
|
||||||
|
HGLOBAL data = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, 1);
|
||||||
|
SetClipboardData(getOwnershipFormat(), data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,3 +166,25 @@ CMSWindowsClipboard::clearConverters()
|
||||||
}
|
}
|
||||||
m_converters.clear();
|
m_converters.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CMSWindowsClipboard::isOwnedBySynergy()
|
||||||
|
{
|
||||||
|
// create ownership format if we haven't yet
|
||||||
|
if (s_ownershipFormat == 0) {
|
||||||
|
s_ownershipFormat = RegisterClipboardFormat(TEXT("SynergyOwnership"));
|
||||||
|
}
|
||||||
|
return (IsClipboardFormatAvailable(getOwnershipFormat()) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT
|
||||||
|
CMSWindowsClipboard::getOwnershipFormat()
|
||||||
|
{
|
||||||
|
// create ownership format if we haven't yet
|
||||||
|
if (s_ownershipFormat == 0) {
|
||||||
|
s_ownershipFormat = RegisterClipboardFormat(TEXT("SynergyOwnership"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the format
|
||||||
|
return s_ownershipFormat;
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@ public:
|
||||||
CMSWindowsClipboard(HWND window);
|
CMSWindowsClipboard(HWND window);
|
||||||
virtual ~CMSWindowsClipboard();
|
virtual ~CMSWindowsClipboard();
|
||||||
|
|
||||||
|
//! Test if clipboard is owned by synergy
|
||||||
|
static bool isOwnedBySynergy();
|
||||||
|
|
||||||
// IClipboard overrides
|
// IClipboard overrides
|
||||||
virtual bool empty();
|
virtual bool empty();
|
||||||
virtual void add(EFormat, const CString& data);
|
virtual void add(EFormat, const CString& data);
|
||||||
|
@ -44,12 +47,15 @@ private:
|
||||||
HANDLE convertTextToWin32(const CString& data) const;
|
HANDLE convertTextToWin32(const CString& data) const;
|
||||||
CString convertTextFromWin32(HANDLE) const;
|
CString convertTextFromWin32(HANDLE) const;
|
||||||
|
|
||||||
|
static UINT getOwnershipFormat();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::vector<IMSWindowsClipboardConverter*> ConverterList;
|
typedef std::vector<IMSWindowsClipboardConverter*> ConverterList;
|
||||||
|
|
||||||
HWND m_window;
|
HWND m_window;
|
||||||
mutable Time m_time;
|
mutable Time m_time;
|
||||||
ConverterList m_converters;
|
ConverterList m_converters;
|
||||||
|
static UINT s_ownershipFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Clipboard format converter interface
|
//! Clipboard format converter interface
|
||||||
|
|
|
@ -385,12 +385,45 @@ KeyModifierMask
|
||||||
CMSWindowsPrimaryScreen::getToggleMask() const
|
CMSWindowsPrimaryScreen::getToggleMask() const
|
||||||
{
|
{
|
||||||
KeyModifierMask mask = 0;
|
KeyModifierMask mask = 0;
|
||||||
|
if (isActive()) {
|
||||||
|
// get key state
|
||||||
|
if ((m_keys[VK_CAPITAL] & 0x01) != 0)
|
||||||
|
mask |= KeyModifierCapsLock;
|
||||||
|
if ((m_keys[VK_NUMLOCK] & 0x01) != 0)
|
||||||
|
mask |= KeyModifierNumLock;
|
||||||
|
if ((m_keys[VK_SCROLL] & 0x01) != 0)
|
||||||
|
mask |= KeyModifierScrollLock;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// show the window, but make it very small. we must do this
|
||||||
|
// because GetKeyState() reports the key state according to
|
||||||
|
// processed messages and until the window is visible the
|
||||||
|
// system won't update the state of the toggle keys reported
|
||||||
|
// by that function. unfortunately, this slows this method
|
||||||
|
// down significantly and, for some reason i don't understand,
|
||||||
|
// causes everything on the screen to redraw.
|
||||||
|
if (m_window != NULL) {
|
||||||
|
MoveWindow(m_window, 1, 1, 1, 1, FALSE);
|
||||||
|
const_cast<CMSWindowsPrimaryScreen*>(this)->showWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get key state
|
||||||
if ((GetKeyState(VK_CAPITAL) & 0x01) != 0)
|
if ((GetKeyState(VK_CAPITAL) & 0x01) != 0)
|
||||||
mask |= KeyModifierCapsLock;
|
mask |= KeyModifierCapsLock;
|
||||||
if ((GetKeyState(VK_NUMLOCK) & 0x01) != 0)
|
if ((GetKeyState(VK_NUMLOCK) & 0x01) != 0)
|
||||||
mask |= KeyModifierNumLock;
|
mask |= KeyModifierNumLock;
|
||||||
if ((GetKeyState(VK_SCROLL) & 0x01) != 0)
|
if ((GetKeyState(VK_SCROLL) & 0x01) != 0)
|
||||||
mask |= KeyModifierScrollLock;
|
mask |= KeyModifierScrollLock;
|
||||||
|
|
||||||
|
// make the window hidden again and restore its size
|
||||||
|
if (m_window != NULL) {
|
||||||
|
const_cast<CMSWindowsPrimaryScreen*>(this)->hideWindow();
|
||||||
|
SInt32 x, y, w, h;
|
||||||
|
m_screen->getShape(x, y, w, h);
|
||||||
|
MoveWindow(m_window, x, y, w, h, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,6 +492,57 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
||||||
{
|
{
|
||||||
assert(event != NULL);
|
assert(event != NULL);
|
||||||
|
|
||||||
|
const MSG* msg = &event->m_msg;
|
||||||
|
|
||||||
|
// check if windows key is up but we think it's down. if so then
|
||||||
|
// synthesize a key release for it. we have to do this because
|
||||||
|
// if the user presses and releases a windows key without pressing
|
||||||
|
// any other key when its down then windows will eat the key
|
||||||
|
// release. if we don't detect that an synthesize the release
|
||||||
|
// then the user will be locked to the screen and the client won't
|
||||||
|
// take the usual windows key release action (which on windows is
|
||||||
|
// to show the start menu).
|
||||||
|
//
|
||||||
|
// we can use GetKeyState() to check the state of the windows keys
|
||||||
|
// because, event though the key release is not reported to us,
|
||||||
|
// the event is processed and the keyboard state updated by the
|
||||||
|
// system. since the key could go up at any time we'll check the
|
||||||
|
// state on every event. only check on windows 95 family since
|
||||||
|
// NT family reports the key release as usual. obviously we skip
|
||||||
|
// this if the event is for the windows key itself.
|
||||||
|
if (m_is95Family) {
|
||||||
|
if ((m_keys[VK_LWIN] & 0x80) != 0 &&
|
||||||
|
(GetAsyncKeyState(VK_LWIN) & 0x8000) == 0 &&
|
||||||
|
!(msg->message == SYNERGY_MSG_KEY && msg->wParam == VK_LWIN)) {
|
||||||
|
// compute appropriate parameters for fake event
|
||||||
|
WPARAM wParam = VK_LWIN;
|
||||||
|
LPARAM lParam = 0xc1000000;
|
||||||
|
lParam |= (0x00ff0000 & (MapVirtualKey(wParam, 0) << 24));
|
||||||
|
|
||||||
|
// process as if it were a key up
|
||||||
|
KeyModifierMask mask;
|
||||||
|
const KeyID key = mapKey(wParam, lParam, &mask);
|
||||||
|
LOG((CLOG_DEBUG1 "event: fake key release key=%d mask=0x%04x", key, mask));
|
||||||
|
m_receiver->onKeyUp(key, mask);
|
||||||
|
updateKey(wParam, false);
|
||||||
|
}
|
||||||
|
if ((m_keys[VK_RWIN] & 0x80) != 0 &&
|
||||||
|
(GetAsyncKeyState(VK_RWIN) & 0x8000) == 0 &&
|
||||||
|
!(msg->message == SYNERGY_MSG_KEY && msg->wParam == VK_RWIN)) {
|
||||||
|
// compute appropriate parameters for fake event
|
||||||
|
WPARAM wParam = VK_RWIN;
|
||||||
|
LPARAM lParam = 0xc1000000;
|
||||||
|
lParam |= (0x00ff0000 & (MapVirtualKey(wParam, 0) << 24));
|
||||||
|
|
||||||
|
// process as if it were a key up
|
||||||
|
KeyModifierMask mask;
|
||||||
|
const KeyID key = mapKey(wParam, lParam, &mask);
|
||||||
|
LOG((CLOG_DEBUG1 "event: fake key release key=%d mask=0x%04x", key, mask));
|
||||||
|
m_receiver->onKeyUp(key, mask);
|
||||||
|
updateKey(wParam, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// handle event
|
// handle event
|
||||||
const MSG* msg = &event->m_msg;
|
const MSG* msg = &event->m_msg;
|
||||||
switch (msg->message) {
|
switch (msg->message) {
|
||||||
|
@ -474,8 +558,9 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
||||||
if (key != kKeyNone) {
|
if (key != kKeyNone) {
|
||||||
if ((msg->lParam & 0x80000000) == 0) {
|
if ((msg->lParam & 0x80000000) == 0) {
|
||||||
// key press
|
// key press
|
||||||
|
const bool wasDown = ((msg->lParam & 0x40000000) != 0);
|
||||||
const SInt32 repeat = (SInt32)(msg->lParam & 0xffff);
|
const SInt32 repeat = (SInt32)(msg->lParam & 0xffff);
|
||||||
if (repeat >= 2) {
|
if (repeat >= 2 || wasDown) {
|
||||||
LOG((CLOG_DEBUG1 "event: key repeat key=%d mask=0x%04x count=%d", key, mask, repeat));
|
LOG((CLOG_DEBUG1 "event: key repeat key=%d mask=0x%04x count=%d", key, mask, repeat));
|
||||||
m_receiver->onKeyRepeat(key, mask, repeat);
|
m_receiver->onKeyRepeat(key, mask, repeat);
|
||||||
}
|
}
|
||||||
|
@ -488,7 +573,20 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
||||||
updateKey(msg->wParam, true);
|
updateKey(msg->wParam, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// key release
|
// key release. if the key isn't down according to
|
||||||
|
// our table then we never got the key press event
|
||||||
|
// for it. if it's not a modifier key then we'll
|
||||||
|
// synthesize the press first. only do this on
|
||||||
|
// the windows 95 family, which eats certain special
|
||||||
|
// keys like alt+tab, ctrl+esc, etc.
|
||||||
|
if (m_is95Family && !isModifier(msg->wParam) &&
|
||||||
|
(m_keys[msg->wParam] & 0x80) == 0) {
|
||||||
|
LOG((CLOG_DEBUG1 "event: fake key press key=%d mask=0x%04x", key, mask));
|
||||||
|
m_receiver->onKeyDown(key, mask);
|
||||||
|
updateKey(msg->wParam, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do key up
|
||||||
LOG((CLOG_DEBUG1 "event: key release key=%d mask=0x%04x", key, mask));
|
LOG((CLOG_DEBUG1 "event: key release key=%d mask=0x%04x", key, mask));
|
||||||
m_receiver->onKeyUp(key, mask);
|
m_receiver->onKeyUp(key, mask);
|
||||||
|
|
||||||
|
@ -583,8 +681,10 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
||||||
|
|
||||||
if (!isActive()) {
|
if (!isActive()) {
|
||||||
// motion on primary screen
|
// motion on primary screen
|
||||||
|
if (x != 0 || y != 0) {
|
||||||
m_receiver->onMouseMovePrimary(m_x, m_y);
|
m_receiver->onMouseMovePrimary(m_x, m_y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// motion on secondary screen. warp mouse back to
|
// motion on secondary screen. warp mouse back to
|
||||||
// center.
|
// center.
|
||||||
|
@ -1271,7 +1371,7 @@ CMSWindowsPrimaryScreen::mapKey(
|
||||||
}
|
}
|
||||||
if (((m_keys[VK_LWIN] |
|
if (((m_keys[VK_LWIN] |
|
||||||
m_keys[VK_RWIN]) & 0x80) != 0) {
|
m_keys[VK_RWIN]) & 0x80) != 0) {
|
||||||
mask |= KeyModifierMeta;
|
mask |= KeyModifierSuper;
|
||||||
}
|
}
|
||||||
if ((m_keys[VK_CAPITAL] & 0x01) != 0) {
|
if ((m_keys[VK_CAPITAL] & 0x01) != 0) {
|
||||||
mask |= KeyModifierCapsLock;
|
mask |= KeyModifierCapsLock;
|
||||||
|
@ -1523,3 +1623,29 @@ CMSWindowsPrimaryScreen::updateKey(UINT vkCode, bool press)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CMSWindowsPrimaryScreen::isModifier(UINT vkCode) const
|
||||||
|
|
||||||
|
{
|
||||||
|
switch (vkCode) {
|
||||||
|
case VK_LSHIFT:
|
||||||
|
case VK_RSHIFT:
|
||||||
|
case VK_SHIFT:
|
||||||
|
case VK_LCONTROL:
|
||||||
|
case VK_RCONTROL:
|
||||||
|
case VK_CONTROL:
|
||||||
|
case VK_LMENU:
|
||||||
|
case VK_RMENU:
|
||||||
|
case VK_MENU:
|
||||||
|
case VK_CAPITAL:
|
||||||
|
case VK_NUMLOCK:
|
||||||
|
case VK_SCROLL:
|
||||||
|
case VK_LWIN:
|
||||||
|
case VK_RWIN:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -89,6 +89,7 @@ private:
|
||||||
KeyModifierMask* maskOut);
|
KeyModifierMask* maskOut);
|
||||||
ButtonID mapButton(WPARAM button) const;
|
ButtonID mapButton(WPARAM button) const;
|
||||||
void updateKey(UINT vkCode, bool press);
|
void updateKey(UINT vkCode, bool press);
|
||||||
|
bool isModifier(UINT vkCode) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IPrimaryScreenReceiver* m_receiver;
|
IPrimaryScreenReceiver* m_receiver;
|
||||||
|
|
|
@ -60,7 +60,7 @@ CMSWindowsScreen::CMSWindowsScreen(IScreenReceiver* receiver,
|
||||||
m_threadID(0),
|
m_threadID(0),
|
||||||
m_lastThreadID(0),
|
m_lastThreadID(0),
|
||||||
m_nextClipboardWindow(NULL),
|
m_nextClipboardWindow(NULL),
|
||||||
m_clipboardOwner(NULL),
|
m_ownClipboard(false),
|
||||||
m_timer(0),
|
m_timer(0),
|
||||||
m_desk(NULL),
|
m_desk(NULL),
|
||||||
m_deskName(),
|
m_deskName(),
|
||||||
|
@ -107,11 +107,9 @@ CMSWindowsScreen::openDesktop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// poll input desktop to see if it changes (onPreDispatch()
|
// poll input desktop to see if it changes (onPreDispatch()
|
||||||
// handles WM_TIMER)
|
// handles WM_TIMER). this is also used for polling other
|
||||||
m_timer = 0;
|
// stuff.
|
||||||
if (!m_is95Family) {
|
|
||||||
m_timer = SetTimer(NULL, 0, 200, NULL);
|
m_timer = SetTimer(NULL, 0, 200, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
return m_window;
|
return m_window;
|
||||||
}
|
}
|
||||||
|
@ -321,14 +319,11 @@ CMSWindowsScreen::checkClipboards()
|
||||||
// next reboot we do this double check. clipboard ownership
|
// next reboot we do this double check. clipboard ownership
|
||||||
// won't be reflected on other screens until we leave but at
|
// won't be reflected on other screens until we leave but at
|
||||||
// least the clipboard itself will work.
|
// least the clipboard itself will work.
|
||||||
HWND clipboardOwner = GetClipboardOwner();
|
if (m_ownClipboard && !CMSWindowsClipboard::isOwnedBySynergy()) {
|
||||||
if (m_clipboardOwner != clipboardOwner) {
|
m_ownClipboard = false;
|
||||||
m_clipboardOwner = clipboardOwner;
|
|
||||||
if (m_clipboardOwner != m_window && m_clipboardOwner != NULL) {
|
|
||||||
m_receiver->onGrabClipboard(kClipboardClipboard);
|
m_receiver->onGrabClipboard(kClipboardClipboard);
|
||||||
m_receiver->onGrabClipboard(kClipboardSelection);
|
m_receiver->onGrabClipboard(kClipboardSelection);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -510,6 +505,10 @@ CMSWindowsScreen::onPreDispatch(const CEvent* event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let client do timer related stuff. ignore the return
|
||||||
|
// value though since the event has been handled here.
|
||||||
|
m_eventHandler->onPreDispatch(event);
|
||||||
}
|
}
|
||||||
else if (msg->wParam == m_oneShotTimer) {
|
else if (msg->wParam == m_oneShotTimer) {
|
||||||
// one shot timer expired
|
// one shot timer expired
|
||||||
|
@ -517,9 +516,11 @@ CMSWindowsScreen::onPreDispatch(const CEvent* event)
|
||||||
m_oneShotTimer = 0;
|
m_oneShotTimer = 0;
|
||||||
m_eventHandler->onOneShotTimerExpired(0);
|
m_eventHandler->onOneShotTimerExpired(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let client handle the event
|
||||||
return m_eventHandler->onPreDispatch(event);
|
return m_eventHandler->onPreDispatch(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,15 +561,17 @@ CMSWindowsScreen::onEvent(CEvent* event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// now notify client that somebody changed the clipboard (unless
|
// now notify client that somebody changed the clipboard (unless
|
||||||
// we're now the owner, in which case it's because we took
|
// we're the owner).
|
||||||
// ownership, or now it's owned by nobody, which will happen if
|
if (!CMSWindowsClipboard::isOwnedBySynergy()) {
|
||||||
// we owned it and switched desktops because we destroy our
|
if (m_ownClipboard) {
|
||||||
// window to do that).
|
m_ownClipboard = false;
|
||||||
m_clipboardOwner = GetClipboardOwner();
|
|
||||||
if (m_clipboardOwner != m_window && m_clipboardOwner != NULL) {
|
|
||||||
m_receiver->onGrabClipboard(kClipboardClipboard);
|
m_receiver->onGrabClipboard(kClipboardClipboard);
|
||||||
m_receiver->onGrabClipboard(kClipboardSelection);
|
m_receiver->onGrabClipboard(kClipboardSelection);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_ownClipboard = true;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case WM_CHANGECBCHAIN:
|
case WM_CHANGECBCHAIN:
|
||||||
|
@ -631,8 +634,8 @@ CMSWindowsScreen::createBlankCursor()
|
||||||
bool
|
bool
|
||||||
CMSWindowsScreen::switchDesktop(HDESK desk)
|
CMSWindowsScreen::switchDesktop(HDESK desk)
|
||||||
{
|
{
|
||||||
// did we own the clipboard?
|
// assume we don't own the clipboard until later
|
||||||
bool ownClipboard = (m_clipboardOwner == m_window && m_window != NULL);
|
m_ownClipboard = false;
|
||||||
|
|
||||||
// destroy old window
|
// destroy old window
|
||||||
if (m_window != NULL) {
|
if (m_window != NULL) {
|
||||||
|
@ -640,11 +643,6 @@ CMSWindowsScreen::switchDesktop(HDESK desk)
|
||||||
ChangeClipboardChain(m_window, m_nextClipboardWindow);
|
ChangeClipboardChain(m_window, m_nextClipboardWindow);
|
||||||
m_nextClipboardWindow = NULL;
|
m_nextClipboardWindow = NULL;
|
||||||
|
|
||||||
// we no longer own the clipboard
|
|
||||||
if (ownClipboard) {
|
|
||||||
m_clipboardOwner = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// let client clean up before we destroy the window
|
// let client clean up before we destroy the window
|
||||||
m_eventHandler->preDestroyWindow(m_window);
|
m_eventHandler->preDestroyWindow(m_window);
|
||||||
|
|
||||||
|
@ -712,12 +710,8 @@ CMSWindowsScreen::switchDesktop(HDESK desk)
|
||||||
// install our clipboard snooper
|
// install our clipboard snooper
|
||||||
m_nextClipboardWindow = SetClipboardViewer(m_window);
|
m_nextClipboardWindow = SetClipboardViewer(m_window);
|
||||||
|
|
||||||
// reassert clipboard ownership
|
// check if we own the clipboard
|
||||||
if (ownClipboard) {
|
m_ownClipboard = CMSWindowsClipboard::isOwnedBySynergy();
|
||||||
// FIXME -- take clipboard ownership, but we should also set
|
|
||||||
// the clipboard data.
|
|
||||||
}
|
|
||||||
m_clipboardOwner = GetClipboardOwner();
|
|
||||||
|
|
||||||
// save new desktop
|
// save new desktop
|
||||||
m_desk = desk;
|
m_desk = desk;
|
||||||
|
|
|
@ -172,7 +172,7 @@ private:
|
||||||
|
|
||||||
// clipboard stuff
|
// clipboard stuff
|
||||||
HWND m_nextClipboardWindow;
|
HWND m_nextClipboardWindow;
|
||||||
HWND m_clipboardOwner;
|
bool m_ownClipboard;
|
||||||
|
|
||||||
// the timer used to check for desktop switching
|
// the timer used to check for desktop switching
|
||||||
UINT m_timer;
|
UINT m_timer;
|
||||||
|
|
|
@ -254,7 +254,6 @@ mouseHook(int code, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_MOVE, x, y);
|
PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_MOVE, x, y);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue