diff --git a/lib/arch/CArchSleepWindows.cpp b/lib/arch/CArchSleepWindows.cpp index 9c0fe596..f6c8bed8 100644 --- a/lib/arch/CArchSleepWindows.cpp +++ b/lib/arch/CArchSleepWindows.cpp @@ -46,6 +46,9 @@ CArchSleepWindows::sleep(double timeout) if (mt != NULL) { HANDLE cancelEvent = mt->getCancelEventForCurrentThread(); WaitForSingleObject(cancelEvent, (DWORD)(1000.0 * timeout)); + if (timeout == 0.0) { + Sleep(0); + } } else { Sleep((DWORD)(1000.0 * timeout)); diff --git a/lib/platform/CMSWindowsPrimaryScreen.cpp b/lib/platform/CMSWindowsPrimaryScreen.cpp index 0e036a04..23476126 100644 --- a/lib/platform/CMSWindowsPrimaryScreen.cpp +++ b/lib/platform/CMSWindowsPrimaryScreen.cpp @@ -17,6 +17,7 @@ #include "IPrimaryScreenReceiver.h" #include "XScreen.h" #include "CLog.h" +#include "CArch.h" #include "CArchMiscWindows.h" #include @@ -311,7 +312,7 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event) if (!isActive()) { // motion on primary screen - m_receiver->onMouseMovePrimary(x, y); + m_receiver->onMouseMovePrimary(m_x, m_y); } else { // motion on secondary screen. warp mouse back to @@ -641,6 +642,22 @@ CMSWindowsPrimaryScreen::warpCursorNoFlush(SInt32 x, SInt32 y) // between the previous message and the following message. SetCursorPos(x, y); + // yield the CPU. there's a race condition when warping: + // a hardware mouse event occurs + // the mouse hook is not called because that process doesn't have the CPU + // we send PRE_WARP, SetCursorPos(), send POST_WARP + // we process all of those events and update m_x, m_y + // we finish our time slice + // the hook is called + // the hook sends us a mouse event from the pre-warp position + // we get the CPU + // we compute a bogus warp + // we need the hook to process all mouse events that occur + // before we warp before we do the warp but i'm not sure how + // to guarantee that. yielding the CPU here may reduce the + // chance of undesired behavior. + ARCH->sleep(0.0); + // send an event that we can recognize after the mouse warp PostThreadMessage(m_threadID, SYNERGY_MSG_POST_WARP, 0, 0); } diff --git a/lib/platform/CSynergyHook.cpp b/lib/platform/CSynergyHook.cpp index b5824efb..23fe82fa 100644 --- a/lib/platform/CSynergyHook.cpp +++ b/lib/platform/CSynergyHook.cpp @@ -229,8 +229,8 @@ mouseHook(int code, WPARAM wParam, LPARAM lParam) // desktop coordinates. bool inside = false; const MOUSEHOOKSTRUCT* info = (const MOUSEHOOKSTRUCT*)lParam; - SInt32 x = (SInt32)info->pt.x + g_xScreen; - SInt32 y = (SInt32)info->pt.y + g_yScreen; + SInt32 x = (SInt32)info->pt.x; + SInt32 y = (SInt32)info->pt.y; if (!inside && (g_zoneSides & kLeftMask) != 0) { inside = (x < g_xScreen + g_zoneSize); } @@ -246,6 +246,8 @@ mouseHook(int code, WPARAM wParam, LPARAM lParam) // if inside then eat event and notify our window if (inside) { + x += g_xScreen; + y += g_yScreen; restoreCursor(); PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_MOVE, x, y); return 1;