Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[X11] SDL_SetWindowPosition can not move window outside of desktop bounds #3813

Open
SDLBugzilla opened this issue Feb 11, 2021 · 0 comments
Assignees
Milestone

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

These attachments are available in the static archive:

Reported in version: 2.0.13
Reported for operating system, platform: Linux, x86_64

Comments on the original bug report:

On 2020-08-31 12:09:01 +0000, Rokas Kupstys wrote:

Created attachment 4456
Screen configuration

We are using SDL windows without decorations + SDL_SetWindowPosition() to move them. On X11 such windows can not move outside of desktop bounds. This behavior does not manifest on other platforms. This behavior is a consequence of xattr.override_redirect being set to false for normal windows. This flag is set to true only for tooltips and popups. Maybe it would also make sense to set it for borderless windows? A quick test overhere seems to work, though i do not know all implications of toggling this flag.

Steps to reproduce:

  1. git clone --single-branch --branch docking https://github.com/ocornut/imgui.git
  2. cd imgui/examples/example_sdl_opengl3
  3. make
  4. ./example_sdl_opengl3
  5. Drag either of Dear ImGui windows ("Hello, world!" or "Dear ImGui Demo") outside of main viewport and try to move window outside of desktop bounds.

Result: Window edge will get stuck at desktop edge. Note that this also confuses Dear ImGui and mouse inputs get registered in wrong locations, this is nothing to be concerned about.
In case of multi-monitor setups please use screen at the edge of global X11 display canvas (made up terminology, hope it makes sense). I have two monitors and i can drag these windows to stick outside of smaller screen. For clarity i attached a screenshot with market green area where window can stick out.

Expected result: Dear ImGui window should be able to stick outside of desktop bounds, just like we can drag any other window by it's decorations to stick out of bounds.

rokups added a commit to rokups/SDL that referenced this issue Jun 7, 2021
Currently it is not possible to move window with `SDL_WINDOW_BORDERLESS` flag outside of screen bounds using `SDL_SetWindowPosition()` (libsdl-org#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.
rokups added a commit to rokups/SDL that referenced this issue Jun 8, 2021
Currently it is not possible to move window with `SDL_WINDOW_BORDERLESS` flag outside of screen bounds using `SDL_SetWindowPosition()` (libsdl-org#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.
rokups added a commit to rokups/SDL that referenced this issue Jun 11, 2021
Currently it is not possible to move window with `SDL_WINDOW_BORDERLESS` flag outside of screen bounds using `SDL_SetWindowPosition()` (libsdl-org#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.

At the same time we get 100ms stalls when WM prevents window movement.

Solution: unconditionally update window struct with real window position while removing loop. This change may result in `SDL_GetWindowPosition()` returning different than requested coordinates if called right after `SDL_SetWindowPosition()`, however this is OK. We have no guarantees `SDL_SetWindowPosition()` would place a window at requested position anyhow. If WM continues to move window after `SDL_SetWindowPosition()` - these updates will be taken into account by `ConfigureNotify` event handler.
@slouken slouken removed the bug label May 11, 2022
@slouken slouken added this to the 3.2.0 milestone Nov 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants