From 19c10b41fd0435e259c1da675733cc446541f9fa Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 30 May 2023 17:04:31 -0400 Subject: [PATCH] x11: Attempt to wait for SDL_MaximizeWindow to complete before returning. Fixes #7070. (cherry picked from commit 379a6f4dabc448d37a5823724d507967e2e069eb) --- src/video/x11/SDL_x11window.c | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 408ac3910..2dd693a9d 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -1403,8 +1403,25 @@ static void X11_SetWindowMaximized(SDL_VideoDevice *_this, SDL_Window *window, S } if (X11_IsWindowMapped(_this, window)) { + /* !!! FIXME: most of this waiting code is copy/pasted from elsewhere. */ + int (*prev_handler)(Display *, XErrorEvent *) = NULL; + XWindowAttributes attrs; + Window childReturn, root, parent; + Window *children; + unsigned int childCount; + int orig_w, orig_h, orig_x, orig_y; + int x, y; + Uint64 timeout; XEvent e; + 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); + orig_w = attrs.width; + orig_h = attrs.height; + SDL_zero(e); e.xany.type = ClientMessage; e.xclient.message_type = _NET_WM_STATE; @@ -1418,6 +1435,40 @@ static void X11_SetWindowMaximized(SDL_VideoDevice *_this, SDL_Window *window, S 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() + 1000; + while (SDL_TRUE) { + 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) || (attrs.width != orig_w) || (attrs.height != orig_h)) { + break; /* window changed, time to go. */ + } + } + + if (SDL_GetTicks64() >= timeout) { + break; + } + + SDL_Delay(10); + } + + if (!caught_x11_error) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, attrs.width, attrs.height); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; } else { X11_SetNetWMState(_this, data->xwindow, window->flags); }