From 3b0a98ede214287e2e1b8e92644cb38cca8b3b46 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Mon, 4 Jan 2021 15:40:23 +1100 Subject: [PATCH] [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. --- client/src/main.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- client/src/main.h | 1 + 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/client/src/main.c b/client/src/main.c index c631e73b..41900524 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -775,22 +775,49 @@ void spiceClipboardRequest(const SpiceDataType type) static void warpMouse(int x, int y) { - if (!g_cursor.inWindow) + if (g_cursor.warpState == WARP_STATE_OFF) return; if (g_cursor.warpState == WARP_STATE_WIN_EXIT) { - SDL_WarpMouseInWindow(g_state.window, x, y); + 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); + g_cursor.warpState = WARP_STATE_OFF; return; } if (g_cursor.warpState == WARP_STATE_ON) { - g_cursor.warpTo.x = x; - g_cursor.warpTo.y = y; g_cursor.warpState = WARP_STATE_ACTIVE; - SDL_WarpMouseInWindow(g_state.window, x, y); + 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.y = y; + SDL_WarpMouseInWindow(g_state.window, x, y); + } } } @@ -1125,6 +1152,16 @@ int eventFilter(void * userdata, SDL_Event * event) } 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); break; diff --git a/client/src/main.h b/client/src/main.h index 861318ac..8ff51ec9 100644 --- a/client/src/main.h +++ b/client/src/main.h @@ -209,6 +209,7 @@ struct CursorState /* the mouse warp state and target */ enum WarpState warpState; + unsigned long warpSerial; SDL_Point warpTo; /* the guest's cursor position */