x11: Set the pending window position immediately after mapping

Waiting until the first configure event to perform the move can result in the window visibly jumping in position.
This commit is contained in:
Frank Praznik
2025-02-17 13:46:14 -05:00
parent 1fd626939f
commit a7f01cd73c

View File

@@ -1444,12 +1444,16 @@ void X11_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
SDL_WindowData *data = window->internal; SDL_WindowData *data = window->internal;
Display *display = data->videodata->display; Display *display = data->videodata->display;
bool bActivate = SDL_GetHintBoolean(SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN, true); bool bActivate = SDL_GetHintBoolean(SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN, true);
bool position_is_absolute = false;
XEvent event; XEvent event;
if (SDL_WINDOW_IS_POPUP(window)) { if (SDL_WINDOW_IS_POPUP(window)) {
// Update the position in case the parent moved while we were hidden // Update the position in case the parent moved while we were hidden
X11_ConstrainPopup(window, true); X11_ConstrainPopup(window, true);
X11_UpdateWindowPosition(window, false); data->pending_position = true;
// Coordinates after X11_ConstrainPopup() are already in the global space.
position_is_absolute = true;
} }
/* Whether XMapRaised focuses the window is based on the window type and it is /* Whether XMapRaised focuses the window is based on the window type and it is
@@ -1458,6 +1462,20 @@ void X11_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
if (!X11_IsWindowMapped(_this, window)) { if (!X11_IsWindowMapped(_this, window)) {
X11_XMapRaised(display, data->xwindow); X11_XMapRaised(display, data->xwindow);
if (data->pending_position) {
int x, y;
if (position_is_absolute) {
x = window->pending.x;
y = window->pending.y;
} else {
SDL_RelativeToGlobalForWindow(window,
window->pending.x, window->pending.y,
&x, &y);
}
data->pending_position = false;
X11_XMoveWindow(display, data->xwindow, x, y);
}
/* Blocking wait for "MapNotify" event. /* Blocking wait for "MapNotify" event.
* We use X11_XIfEvent because pXWindowEvent takes a mask rather than a type, * We use X11_XIfEvent because pXWindowEvent takes a mask rather than a type,
* and XCheckTypedWindowEvent doesn't block */ * and XCheckTypedWindowEvent doesn't block */
@@ -1484,9 +1502,6 @@ void X11_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
X11_GetBorderValues(data); X11_GetBorderValues(data);
} }
// Apply the pending position, if any, after the window is mapped.
data->pending_position = window->last_position_pending;
/* Some window managers can send garbage coordinates while mapping the window, so don't emit size and position /* Some window managers can send garbage coordinates while mapping the window, so don't emit size and position
* events during the initial configure events. * events during the initial configure events.
*/ */