Changed win32 client side cursor warping to be all relative motion
when not on the primary monitor. This should eliminate the flicker between virtual display 0,0 and the correct position. While this allows the user to confuse synergy by using the client's mouse, synergy recovers quickly and easily from any confusion.
This commit is contained in:
parent
2fc8780285
commit
dd339fe375
|
@ -350,35 +350,16 @@ CMSWindowsSecondaryScreen::hideWindow()
|
||||||
void
|
void
|
||||||
CMSWindowsSecondaryScreen::warpCursor(SInt32 x, SInt32 y)
|
CMSWindowsSecondaryScreen::warpCursor(SInt32 x, SInt32 y)
|
||||||
{
|
{
|
||||||
typedef UINT (WINAPI *SendInput_t)(UINT, LPINPUT, int);
|
|
||||||
static bool gotSendInput = false;
|
|
||||||
static SendInput_t SendInput = NULL;
|
|
||||||
|
|
||||||
// motion is simple (i.e. it's on the primary monitor) if there
|
// motion is simple (i.e. it's on the primary monitor) if there
|
||||||
// is only one monitor.
|
// is only one monitor.
|
||||||
bool simple = !m_screen->isMultimon();
|
bool simple = !m_screen->isMultimon();
|
||||||
/* disable attempts to use simple motion with multiple monitors for now
|
|
||||||
if (!simple) {
|
if (!simple) {
|
||||||
// also simple if motion is within the primary monitor
|
// also simple if motion is within the primary monitor
|
||||||
simple = (x >= 0 && x < GetSystemMetrics(SM_CXSCREEN) &&
|
simple = (x >= 0 && x < GetSystemMetrics(SM_CXSCREEN) &&
|
||||||
y >= 0 && y < GetSystemMetrics(SM_CYSCREEN));
|
y >= 0 && y < GetSystemMetrics(SM_CYSCREEN));
|
||||||
if (!simple && !m_is95Family) {
|
|
||||||
// also simple if not on windows 95 family since the
|
|
||||||
// NT family mouse_event() allows absolute moves to
|
|
||||||
// any monitor.
|
|
||||||
//
|
|
||||||
// note -- this is possibly untrue if the primary
|
|
||||||
// monitor isn't upper-left most so limit it to that
|
|
||||||
// situation.
|
|
||||||
SInt32 x0, y0, w, h;
|
|
||||||
m_screen->getShape(x0, y0, w, h);
|
|
||||||
simple = (x0 == 0 && y0 == 0);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// move the mouse directly to target position on NT family or if
|
// move the mouse directly to target position if motion is simple
|
||||||
// not using multiple monitors.
|
|
||||||
if (simple) {
|
if (simple) {
|
||||||
SInt32 x0, y0, w, h;
|
SInt32 x0, y0, w, h;
|
||||||
m_screen->getShape(x0, y0, w, h);
|
m_screen->getShape(x0, y0, w, h);
|
||||||
|
@ -394,39 +375,29 @@ CMSWindowsSecondaryScreen::warpCursor(SInt32 x, SInt32 y)
|
||||||
// words, "by design." apparently the designers of windows 2000
|
// words, "by design." apparently the designers of windows 2000
|
||||||
// we're a little less lazy and did it right.
|
// we're a little less lazy and did it right.
|
||||||
//
|
//
|
||||||
// we use the microsoft recommendation (Q193003): set the absolute
|
// microsoft recommends in Q193003 to absolute position the cursor
|
||||||
// position on the primary monitor, disable mouse acceleration,
|
// somewhere on the primary monitor then relative move to the
|
||||||
// relative move the mouse to the final location, restore mouse
|
// desired location. this doesn't work for us because when the
|
||||||
// acceleration. to avoid one kind of race condition (the user
|
// user drags a scrollbar, a window, etc. it causes the dragged
|
||||||
// clicking the mouse or pressing a key between the absolute and
|
// item to jump back a forth between the position on the primary
|
||||||
// relative move) we'll use SendInput() which guarantees that the
|
// monitor and the desired position. while it always ends up in
|
||||||
// events are delivered uninterrupted. we cannot prevent changes
|
// the right place, the effect is disconcerting.
|
||||||
// to the mouse acceleration at inopportune times, though. if
|
|
||||||
// SendInput() is unavailable then use mouse_event(); SendInput()
|
|
||||||
// is not available on Windows 95 and NT 4.0 prior to SP3.
|
|
||||||
//
|
//
|
||||||
// point-to-activate (x-mouse) doesn't seem to be bothered by the
|
// instead we'll get the cursor's current position and do just a
|
||||||
// absolute/relative combination. a window over the absolute
|
// relative move from there to the desired position. relative
|
||||||
// position (0,0) does *not* get activated (at least not on win2k)
|
// moves are subject to cursor acceleration which we don't want.
|
||||||
// if the relative move puts the cursor elsewhere. similarly, the
|
// so we disable acceleration, do the relative move, then restore
|
||||||
// app under the final mouse position does *not* get deactivated
|
// acceleration. there's a slight chance we'll end up in the
|
||||||
// by the absolute move to 0,0.
|
// wrong place if the user moves the cursor using this system's
|
||||||
|
// mouse while simultaneously moving the mouse on the server
|
||||||
|
// system. that defeats the purpose of synergy so we'll assume
|
||||||
|
// that won't happen. even if it does, the next mouse move will
|
||||||
|
// correct the position.
|
||||||
else {
|
else {
|
||||||
// lookup SendInput() function
|
|
||||||
if (!gotSendInput) {
|
|
||||||
gotSendInput = true;
|
|
||||||
HINSTANCE user32 = LoadLibrary("user32.dll");
|
|
||||||
if (user32 != NULL) {
|
|
||||||
SendInput = reinterpret_cast<SendInput_t>(
|
|
||||||
GetProcAddress(user32, "SendInput"));
|
|
||||||
FreeLibrary(user32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// save mouse speed & acceleration
|
// save mouse speed & acceleration
|
||||||
int oldSpeed[4];
|
int oldSpeed[4];
|
||||||
bool accelChanged =
|
bool accelChanged =
|
||||||
SystemParametersInfo(SPI_GETMOUSE,0, oldSpeed,0) &&
|
SystemParametersInfo(SPI_GETMOUSE,0, oldSpeed, 0) &&
|
||||||
SystemParametersInfo(SPI_GETMOUSESPEED, 0, oldSpeed + 3, 0);
|
SystemParametersInfo(SPI_GETMOUSESPEED, 0, oldSpeed + 3, 0);
|
||||||
|
|
||||||
// use 1:1 motion
|
// use 1:1 motion
|
||||||
|
@ -437,38 +408,12 @@ CMSWindowsSecondaryScreen::warpCursor(SInt32 x, SInt32 y)
|
||||||
SystemParametersInfo(SPI_SETMOUSESPEED, 0, newSpeed + 3, 0);
|
SystemParametersInfo(SPI_SETMOUSESPEED, 0, newSpeed + 3, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// send events
|
// get current mouse position
|
||||||
INPUT events[2];
|
POINT pos;
|
||||||
events[0].type = INPUT_MOUSE;
|
GetCursorPos(&pos);
|
||||||
events[0].mi.dx = 0;
|
|
||||||
events[0].mi.dy = 0;
|
// move relative to mouse position
|
||||||
events[0].mi.mouseData = 0;
|
mouse_event(MOUSEEVENTF_MOVE, x - pos.x, y - pos.y, 0, 0);
|
||||||
events[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
|
||||||
events[0].mi.time = GetTickCount();
|
|
||||||
events[0].mi.dwExtraInfo = 0;
|
|
||||||
events[1].type = INPUT_MOUSE;
|
|
||||||
events[1].mi.dx = x;
|
|
||||||
events[1].mi.dy = y;
|
|
||||||
events[1].mi.mouseData = 0;
|
|
||||||
events[1].mi.dwFlags = MOUSEEVENTF_MOVE;
|
|
||||||
events[1].mi.time = events[0].mi.time;
|
|
||||||
events[1].mi.dwExtraInfo = 0;
|
|
||||||
if (SendInput != NULL) {
|
|
||||||
SendInput(sizeof(events) / sizeof(events[0]),
|
|
||||||
events, sizeof(events[0]));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mouse_event(events[0].mi.dwFlags,
|
|
||||||
events[0].mi.dx,
|
|
||||||
events[0].mi.dy,
|
|
||||||
events[0].mi.mouseData,
|
|
||||||
events[0].mi.dwExtraInfo);
|
|
||||||
mouse_event(events[1].mi.dwFlags,
|
|
||||||
events[1].mi.dx,
|
|
||||||
events[1].mi.dy,
|
|
||||||
events[1].mi.mouseData,
|
|
||||||
events[1].mi.dwExtraInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// restore mouse speed & acceleration
|
// restore mouse speed & acceleration
|
||||||
if (accelChanged) {
|
if (accelChanged) {
|
||||||
|
|
Loading…
Reference in New Issue