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.
This commit is contained in:
Ryan C. Gordon 2022-04-05 11:10:41 -04:00
parent 45372b1c27
commit a5672b858e
No known key found for this signature in database
GPG Key ID: FA148B892AB48044
1 changed files with 47 additions and 0 deletions

View File

@ -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;