From a5672b858ef6812d5f772b181e13681d4968661b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 5 Apr 2022 11:10:41 -0400 Subject: [PATCH] x11: Wait a bit to see if window pos changes when changing fullscreen. Helps prevent window from moving to 0,0 when leaving fullscreen. Fixes #4749. --- src/video/x11/SDL_x11window.c | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 5824cda76..65d308798 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -1312,6 +1312,20 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis if (X11_IsWindowMapped(_this, window)) { XEvent e; + /* !!! FIXME: most of this waiting code is copy/pasted from elsewhere. */ + int (*prev_handler) (Display *, XErrorEvent *) = NULL; + unsigned int childCount; + Window childReturn, root, parent; + Window* children; + XWindowAttributes attrs; + int orig_x, orig_y; + Uint64 timeout; + + X11_XSync(display, False); + X11_XQueryTree(display, data->xwindow, &root, &parent, &children, &childCount); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &orig_x, &orig_y, &childReturn); if (!(window->flags & SDL_WINDOW_RESIZABLE)) { /* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we @@ -1361,6 +1375,39 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, SubstructureNotifyMask | SubstructureRedirectMask, &e); } + + /* Wait a brief time to see if the window manager decided to let this happen. + If the window changes at all, even to an unexpected value, we break out. */ + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + + timeout = SDL_GetTicks64() + 100; + while (SDL_TRUE) { + int x, y; + + caught_x11_error = SDL_FALSE; + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &x, &y, &childReturn); + + if (!caught_x11_error) { + if ((x != orig_x) || (y != orig_y)) { + window->x = x; + window->y = y; + break; /* window moved, time to go. */ + } + } + + if (SDL_GetTicks64() >= timeout) { + break; + } + + SDL_Delay(10); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; } else { Uint32 flags;