From eb6837e35345d5ac447cfbb9fa24100b9ad1913b Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Tue, 2 May 2023 21:15:00 -0400 Subject: [PATCH] wayland: Validate and trigger the repositioning of popups in more cases Validate and reposition popups in any case where the position or size may have changed. In particular, this fixes cases where the position parameters were adjusted while the window was hidden, as the new values weren't being applied in all cases. --- src/video/wayland/SDL_waylandwindow.c | 33 +++++++++++++++++++-------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index cbd09c88ee..fc4fe6b4ec 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -421,6 +421,25 @@ static void GetPopupPosition(SDL_Window *popup, int x, int y, int *adj_x, int *a } } +static void RepositionPopup(SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP && + wind->shell_surface.xdg.roleobj.popup.positioner && + xdg_popup_get_version(wind->shell_surface.xdg.roleobj.popup.popup) >= XDG_POPUP_REPOSITION_SINCE_VERSION) { + int x, y; + + EnsurePopupPositionIsValid(window); + GetPopupPosition(window, window->x, window->y, &x, &y); + xdg_positioner_set_size(wind->shell_surface.xdg.roleobj.popup.positioner, window->w, window->h); + xdg_positioner_set_offset(wind->shell_surface.xdg.roleobj.popup.positioner, x, y); + xdg_popup_reposition(wind->shell_surface.xdg.roleobj.popup.popup, + wind->shell_surface.xdg.roleobj.popup.positioner, + 0); + } +} + static const struct wl_callback_listener surface_frame_listener; static void surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) @@ -1331,6 +1350,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) xdg_positioner_set_size(data->shell_surface.xdg.roleobj.popup.positioner, window->w, window->h); /* Set the popup initial position */ + EnsurePopupPositionIsValid(window); GetPopupPosition(window, window->x, window->y, &position_x, &position_y); xdg_positioner_set_offset(data->shell_surface.xdg.roleobj.popup.positioner, position_x, position_y); @@ -2129,20 +2149,12 @@ int Wayland_SetWindowPosition(_THIS, SDL_Window *window) SDL_WindowData *wind = window->driverdata; /* Only popup windows can be positioned relative to the parent. */ - if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP && wind->shell_surface.xdg.roleobj.popup.popup) { if (xdg_popup_get_version(wind->shell_surface.xdg.roleobj.popup.popup) < XDG_POPUP_REPOSITION_SINCE_VERSION) { return SDL_Unsupported(); } - if (!(window->flags & SDL_WINDOW_HIDDEN)) { - int x, y; - EnsurePopupPositionIsValid(window); - GetPopupPosition(window, window->x, window->y, &x, &y); - xdg_positioner_set_offset(wind->shell_surface.xdg.roleobj.popup.positioner, x, y); - xdg_popup_reposition(wind->shell_surface.xdg.roleobj.popup.popup, - wind->shell_surface.xdg.roleobj.popup.positioner, - 0); - } + RepositionPopup(window); return 0; } return SDL_SetError("wayland cannot position non-popup windows"); @@ -2167,6 +2179,7 @@ void Wayland_SetWindowSize(_THIS, SDL_Window *window) wind->requested_window_height = window->windowed.h; ConfigureWindowGeometry(window); + RepositionPopup(window); } /* Always commit, as this may be in response to a min/max limit change. */