Skip to content

Commit

Permalink
Fix X11_SetWindowPosition() edgecase
Browse files Browse the repository at this point in the history
Currently it is not possible to move window with `SDL_WINDOW_BORDERLESS` flag outside of screen bounds using `SDL_SetWindowPosition()` (#3813). Suppose we move such window at the bottom of the screen, and it's bottom border is stops at bottom border of the screen. If we proceed to move such window further out of the screen bounds (still using `SDL_SetWindowPosition()`), window position keeps getting updated in `SDL_SetWindowPosition()`, but position we requested is outside of screen bounds and therefore is not valid. WM forces our window to stay in the same position. When `X11_SetWindowPosition()` executes following happens:
1. `X11_XTranslateCoordinates(&orig_x, &orig_y);` - return position clamped within screen bounds. This is not what we requested in `X11_SetWindowPosition()` and not what `window->x`/`window->y` have currently set.
2. `X11_XMoveWindow();` - move to requested coordinates. However nothing happens because WM prevents moving outside of screen bounds. Window remains in the same location.
3. `X11_XTranslateCoordinates(&x, &y);` - checking if window moved. This call returns same coordinates as in step 1.
4. `if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout))` - eventually check passes and we break out of the loop.

So `SDL_SetWindowPosition()` updated `window->x`/`window->y`, then we failed to move window and kept our requested window position set in `SDL_Window`, making subsequent `SDL_GetWindowPosition()` calls return incorrect results.

Solution: unconditionally update window struct with real window position, because why not.
  • Loading branch information
rokups committed Jun 8, 2021
1 parent e13b43a commit f8115be
Showing 1 changed file with 3 additions and 4 deletions.
7 changes: 3 additions & 4 deletions src/video/x11/SDL_x11window.c
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ X11_SetWindowPosition(_THIS, SDL_Window * window)
Window childReturn, root, parent;
Window* children;
XWindowAttributes attrs;
int orig_x, orig_y;
int x, y, orig_x, orig_y;
Uint32 timeout;

X11_XSync(display, False);
Expand All @@ -812,15 +812,12 @@ X11_SetWindowPosition(_THIS, SDL_Window * window)
If the window changes at all, even to an unexpected value, we break out. */
timeout = SDL_GetTicks() + 100;
while (SDL_TRUE) {
int x, y;
X11_XSync(display, False);
X11_XGetWindowAttributes(display, data->xwindow, &attrs);
X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display),
attrs.x, attrs.y, &x, &y, &childReturn);

if ((x != orig_x) || (y != orig_y)) {
window->x = x;
window->y = y;
break; /* window moved, time to go. */
} else if ((x == window->x) && (y == window->y)) {
break; /* we're at the place we wanted to be anyhow, drop out. */
Expand All @@ -832,6 +829,8 @@ X11_SetWindowPosition(_THIS, SDL_Window * window)

SDL_Delay(10);
}
window->x = x;
window->y = y;
}

void
Expand Down

0 comments on commit f8115be

Please sign in to comment.