From 1f0bc4b808a5da933ce4fedee89e2d42eb862498 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Sun, 30 Jun 2024 12:16:50 -0400 Subject: [PATCH] x11: Check for button presses before clearing an XInput2 pointer grab XInput2 will grab the pointer on button presses, which causes the grab attempt to fail and ultimately timeout since the pointer is already grabbed, however, ungrabbing the pointer when no buttons are pressed and the pointer is outside the window can generate enter/leave notify events, which result in further calls of the grab function. The end result is an infinite loop of grab/ungrab attempts generating enter/leave events. This causes a hang in testautomation when creating a window with the grabbed flag if the pointer is not positioned within window bounds. Check the button state and only ungrab if a mouse button is in the pressed state. --- src/video/x11/SDL_x11window.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index d696ced794..60e5a32817 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -1856,10 +1856,11 @@ int X11_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool } /* If XInput2 is enabled, it will grab the pointer on button presses, - * which results in XGrabPointer returning AlreadyGrabbed. Clear any - * existing grabs before attempting the confinement grab. + * which results in XGrabPointer returning AlreadyGrabbed. If buttons + * are currently pressed, clear any existing grabs before attempting + * the confinement grab. */ - if (data->xinput2_mouse_enabled) { + if (data->xinput2_mouse_enabled && SDL_GetMouseState(NULL, NULL)) { X11_XUngrabPointer(display, CurrentTime); }