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.
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 59 60 61 62 63 64 65
diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index 5824cda..65d3087 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;