From 19c10b41fd0435e259c1da675733cc446541f9fa Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
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 408ac3910fbc..2dd693a9dfc3 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);
}