Added workaround for win32 low-level mouse hook position weirdness.
The low-level hook can report mouse positions outside the boundaries of the screen and bogus retrograde motion. This messes up switch on double tap. This change attempts to detect and suppress the bogus events.
This commit is contained in:
parent
6d6ebf7926
commit
3db9facb6c
|
@ -457,6 +457,33 @@ mouseHookHandler(WPARAM wParam, SInt32 x, SInt32 y, SInt32 data)
|
|||
return true;
|
||||
}
|
||||
else if (g_mode == kHOOK_WATCH_JUMP_ZONE) {
|
||||
// low level hooks can report bogus mouse positions that are
|
||||
// outside of the screen. jeez. naturally we end up getting
|
||||
// fake motion in the other direction to get the position back
|
||||
// on the screen, which plays havoc with switch on double tap.
|
||||
// CServer deals with that. we'll clamp positions onto the
|
||||
// screen. also, if we discard events for positions outside
|
||||
// of the screen then the mouse appears to get a bit jerky
|
||||
// near the edge. we can either accept that or pass the bogus
|
||||
// events. we'll try passing the events.
|
||||
bool bogus = false;
|
||||
if (x < g_xScreen) {
|
||||
x = g_xScreen;
|
||||
bogus = true;
|
||||
}
|
||||
else if (x >= g_xScreen + g_wScreen) {
|
||||
x = g_xScreen + g_wScreen - 1;
|
||||
bogus = true;
|
||||
}
|
||||
if (y < g_yScreen) {
|
||||
y = g_yScreen;
|
||||
bogus = true;
|
||||
}
|
||||
else if (y >= g_yScreen + g_hScreen) {
|
||||
y = g_yScreen + g_hScreen - 1;
|
||||
bogus = true;
|
||||
}
|
||||
|
||||
// check for mouse inside jump zone
|
||||
bool inside = false;
|
||||
if (!inside && (g_zoneSides & kLeftMask) != 0) {
|
||||
|
@ -475,8 +502,8 @@ mouseHookHandler(WPARAM wParam, SInt32 x, SInt32 y, SInt32 data)
|
|||
// relay the event
|
||||
PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_MOVE, x, y);
|
||||
|
||||
// if inside then eat the event
|
||||
return inside;
|
||||
// if inside and not bogus then eat the event
|
||||
return inside && !bogus;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,13 +545,13 @@ mouseHook(int code, WPARAM wParam, LPARAM lParam)
|
|||
// them.
|
||||
switch (g_wheelSupport) {
|
||||
case kWheelModern:
|
||||
w = static_cast<SInt32>(LOWORD(info->dwExtraInfo));
|
||||
w = static_cast<SInt16>(LOWORD(info->dwExtraInfo));
|
||||
break;
|
||||
|
||||
case kWheelWin2000: {
|
||||
const MOUSEHOOKSTRUCTWin2000* info2k =
|
||||
(const MOUSEHOOKSTRUCTWin2000*)lParam;
|
||||
w = static_cast<SInt32>(HIWORD(info2k->mouseData));
|
||||
w = static_cast<SInt16>(HIWORD(info2k->mouseData));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -561,7 +588,8 @@ getMessageHook(int code, WPARAM wParam, LPARAM lParam)
|
|||
if (msg->message == g_wmMouseWheel) {
|
||||
// post message to our window
|
||||
PostThreadMessage(g_threadID,
|
||||
SYNERGY_MSG_MOUSE_WHEEL, msg->wParam, 0);
|
||||
SYNERGY_MSG_MOUSE_WHEEL,
|
||||
static_cast<SInt16>(msg->wParam & 0xffffu), 0);
|
||||
|
||||
// zero out the delta in the message so it's (hopefully)
|
||||
// ignored
|
||||
|
@ -627,9 +655,9 @@ mouseLLHook(int code, WPARAM wParam, LPARAM lParam)
|
|||
if (code >= 0) {
|
||||
// decode the message
|
||||
MSLLHOOKSTRUCT* info = reinterpret_cast<MSLLHOOKSTRUCT*>(lParam);
|
||||
SInt32 x = (SInt32)info->pt.x;
|
||||
SInt32 y = (SInt32)info->pt.y;
|
||||
SInt32 w = (SInt32)HIWORD(info->mouseData);
|
||||
SInt32 x = static_cast<SInt32>(info->pt.x);
|
||||
SInt32 y = static_cast<SInt32>(info->pt.y);
|
||||
SInt32 w = static_cast<SInt16>(HIWORD(info->mouseData));
|
||||
|
||||
// handle the message
|
||||
if (mouseHookHandler(wParam, x, y, w)) {
|
||||
|
|
|
@ -40,6 +40,10 @@ CServer::CServer(const CConfig& config, CPrimaryClient* primaryClient) :
|
|||
m_primaryClient(primaryClient),
|
||||
m_active(primaryClient),
|
||||
m_seqNum(0),
|
||||
m_xDelta(0),
|
||||
m_yDelta(0),
|
||||
m_xDelta2(0),
|
||||
m_yDelta2(0),
|
||||
m_config(config),
|
||||
m_activeSaver(NULL),
|
||||
m_switchDir(kNoDirection),
|
||||
|
@ -374,8 +378,12 @@ CServer::switchScreen(IClient* dst, SInt32 x, SInt32 y, bool forScreensaver)
|
|||
stopSwitch();
|
||||
|
||||
// record new position
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_xDelta = 0;
|
||||
m_yDelta = 0;
|
||||
m_xDelta2 = 0;
|
||||
m_yDelta2 = 0;
|
||||
|
||||
// wrapping means leaving the active screen and entering it again.
|
||||
// since that's a waste of time we skip that and just warp the
|
||||
|
@ -758,7 +766,29 @@ CServer::armSwitchTwoTap(SInt32 x, SInt32 y)
|
|||
}
|
||||
if (x >= ax + tapZone && x < ax + aw - tapZone &&
|
||||
y >= ay + tapZone && y < ay + ah - tapZone) {
|
||||
m_switchTwoTapArmed = true;
|
||||
// win32 can generate bogus mouse events that appear to
|
||||
// move in the opposite direction that the mouse actually
|
||||
// moved. try to ignore that crap here.
|
||||
switch (m_switchDir) {
|
||||
case kLeft:
|
||||
m_switchTwoTapArmed = (m_xDelta > 0 && m_xDelta2 > 0);
|
||||
break;
|
||||
|
||||
case kRight:
|
||||
m_switchTwoTapArmed = (m_xDelta < 0 && m_xDelta2 < 0);
|
||||
break;
|
||||
|
||||
case kTop:
|
||||
m_switchTwoTapArmed = (m_yDelta > 0 && m_yDelta2 > 0);
|
||||
break;
|
||||
|
||||
case kBottom:
|
||||
m_switchTwoTapArmed = (m_yDelta < 0 && m_yDelta2 < 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1242,9 +1272,17 @@ CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
|
|||
return false;
|
||||
}
|
||||
|
||||
// save last delta
|
||||
m_xDelta2 = m_xDelta;
|
||||
m_yDelta2 = m_yDelta;
|
||||
|
||||
// save current delta
|
||||
m_xDelta = x - m_x;
|
||||
m_yDelta = y - m_y;
|
||||
|
||||
// save position
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
|
||||
// get screen shape
|
||||
SInt32 ax, ay, aw, ah;
|
||||
|
@ -1305,9 +1343,17 @@ CServer::onMouseMoveSecondary(SInt32 dx, SInt32 dy)
|
|||
const SInt32 xOld = m_x;
|
||||
const SInt32 yOld = m_y;
|
||||
|
||||
// save last delta
|
||||
m_xDelta2 = m_xDelta;
|
||||
m_yDelta2 = m_yDelta;
|
||||
|
||||
// save current delta
|
||||
m_xDelta = dx;
|
||||
m_yDelta = dy;
|
||||
|
||||
// accumulate motion
|
||||
m_x += dx;
|
||||
m_y += dy;
|
||||
m_x += dx;
|
||||
m_y += dy;
|
||||
|
||||
// get screen shape
|
||||
SInt32 ax, ay, aw, ah;
|
||||
|
|
|
@ -278,6 +278,13 @@ private:
|
|||
// whichever screen is active
|
||||
SInt32 m_x, m_y;
|
||||
|
||||
// last mouse deltas. this is needed to smooth out double tap
|
||||
// on win32 which reports bogus mouse motion at the edge of
|
||||
// the screen when using low level hooks, synthesizing motion
|
||||
// in the opposite direction the mouse actually moved.
|
||||
SInt32 m_xDelta, m_yDelta;
|
||||
SInt32 m_xDelta2, m_yDelta2;
|
||||
|
||||
// current configuration
|
||||
CConfig m_config;
|
||||
|
||||
|
|
Loading…
Reference in New Issue