Fixed interactions between mouse capture and grab on X11 Fixes https://github.com/libsdl-org/SDL/issues/6072
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c
index 4fb0afa..4fd8fa9 100644
--- a/src/video/x11/SDL_x11mouse.c
+++ b/src/video/x11/SDL_x11mouse.c
@@ -358,16 +358,20 @@ static int
X11_CaptureMouse(SDL_Window *window)
{
Display *display = GetDisplay();
+ SDL_Window *mouse_focus = SDL_GetMouseFocus();
if (window) {
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
+ Window confined = (data->mouse_grabbed ? data->xwindow : None);
const int rc = X11_XGrabPointer(display, data->xwindow, False,
mask, GrabModeAsync, GrabModeAsync,
- None, None, CurrentTime);
+ confined, None, CurrentTime);
if (rc != GrabSuccess) {
return SDL_SetError("X server refused mouse capture");
}
+ } else if (mouse_focus) {
+ SDL_UpdateWindowGrab(mouse_focus);
} else {
X11_XUngrabPointer(display, CurrentTime);
}
diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index f7ec281..e8fee1c 100644
--- a/src/video/x11/SDL_x11window.c
+++ b/src/video/x11/SDL_x11window.c
@@ -1600,6 +1600,7 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
if (data == NULL) {
return;
}
+ data->mouse_grabbed = SDL_FALSE;
display = data->videodata->display;
@@ -1622,6 +1623,7 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
result = X11_XGrabPointer(display, data->xwindow, True, mask, GrabModeAsync,
GrabModeAsync, data->xwindow, None, CurrentTime);
if (result == GrabSuccess) {
+ data->mouse_grabbed = SDL_TRUE;
break;
}
SDL_Delay(50);
diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h
index 6f7560a..c32955b 100644
--- a/src/video/x11/SDL_x11window.h
+++ b/src/video/x11/SDL_x11window.h
@@ -59,6 +59,7 @@ typedef struct
int border_right;
int border_top;
int border_bottom;
+ SDL_bool mouse_grabbed;
Uint32 last_focus_event_time;
PendingFocusEnum pending_focus;
Uint32 pending_focus_time;