[client] spice: use xlib directly for warping

This change allows us to look for and filter out the warp completion
event as we can obtain and use the serial number of the warp request to
do so. This is far more elegant then the x/y match that we were doing
prior.
This commit is contained in:
Geoffrey McRae 2021-01-04 15:40:23 +11:00
parent 5d5b7b3d3c
commit 3b0a98ede2
2 changed files with 43 additions and 5 deletions

View File

@ -775,23 +775,50 @@ void spiceClipboardRequest(const SpiceDataType type)
static void warpMouse(int x, int y) static void warpMouse(int x, int y)
{ {
if (!g_cursor.inWindow) if (g_cursor.warpState == WARP_STATE_OFF)
return; return;
if (g_cursor.warpState == WARP_STATE_WIN_EXIT) if (g_cursor.warpState == WARP_STATE_WIN_EXIT)
{ {
if (g_state.wminfo.subsystem == SDL_SYSWM_X11)
{
XWarpPointer(
g_state.wminfo.info.x11.display,
None,
g_state.wminfo.info.x11.window,
0, 0, 0, 0,
x, y);
}
else
SDL_WarpMouseInWindow(g_state.window, x, y); SDL_WarpMouseInWindow(g_state.window, x, y);
g_cursor.warpState = WARP_STATE_OFF; g_cursor.warpState = WARP_STATE_OFF;
return; return;
} }
if (g_cursor.warpState == WARP_STATE_ON) if (g_cursor.warpState == WARP_STATE_ON)
{
g_cursor.warpState = WARP_STATE_ACTIVE;
if (g_state.wminfo.subsystem == SDL_SYSWM_X11)
{
/* with X11 we can be far more elegent and use the warp serial number to
* determine when the warp is complete instead of trying to match the
* target x/y coordinates */
g_cursor.warpSerial = NextRequest(g_state.wminfo.info.x11.display);
XWarpPointer(
g_state.wminfo.info.x11.display,
None,
g_state.wminfo.info.x11.window,
0, 0, 0, 0,
x, y);
}
else
{ {
g_cursor.warpTo.x = x; g_cursor.warpTo.x = x;
g_cursor.warpTo.y = y; g_cursor.warpTo.y = y;
g_cursor.warpState = WARP_STATE_ACTIVE;
SDL_WarpMouseInWindow(g_state.window, x, y); SDL_WarpMouseInWindow(g_state.window, x, y);
} }
}
} }
static bool isValidCursorLocation(int x, int y) static bool isValidCursorLocation(int x, int y)
@ -1125,6 +1152,16 @@ int eventFilter(void * userdata, SDL_Event * event)
} }
case MotionNotify: case MotionNotify:
/* detect and filter out the warp event */
if (g_cursor.warpState == WARP_STATE_ACTIVE &&
xe.xmotion.serial == g_cursor.warpSerial)
{
g_cursor.warpState = WARP_STATE_ON;
g_cursor.last.x = xe.xmotion.x;
g_cursor.last.y = xe.xmotion.y;
break;
}
handleMouseMoveEvent(xe.xmotion.x, xe.xmotion.y); handleMouseMoveEvent(xe.xmotion.x, xe.xmotion.y);
break; break;

View File

@ -209,6 +209,7 @@ struct CursorState
/* the mouse warp state and target */ /* the mouse warp state and target */
enum WarpState warpState; enum WarpState warpState;
unsigned long warpSerial;
SDL_Point warpTo; SDL_Point warpTo;
/* the guest's cursor position */ /* the guest's cursor position */