diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c index 4fb0afa1a..4fd8fa9f7 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 f7ec281b9..e8fee1c12 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 6f7560afe..c32955b26 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;