diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 1fea144e17..e43584e150 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -181,7 +181,7 @@ static void SetMinMaxDimensions(SDL_Window *window) #ifdef HAVE_LIBDECOR_H if (wind->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_LIBDECOR) { - if (!wind->shell_surface.libdecor.initial_configure_seen || !wind->shell_surface.libdecor.frame) { + if (!wind->shell_surface.libdecor.frame) { return; // Can't do anything yet, wait for ShowWindow } /* No need to change these values if the window is non-resizable, @@ -198,7 +198,7 @@ static void SetMinMaxDimensions(SDL_Window *window) } else #endif if (wind->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_XDG_TOPLEVEL) { - if (wind->shell_surface.xdg.toplevel.xdg_toplevel == NULL) { + if (!wind->shell_surface.xdg.toplevel.xdg_toplevel) { return; // Can't do anything yet, wait for ShowWindow } xdg_toplevel_set_min_size(wind->shell_surface.xdg.toplevel.xdg_toplevel, @@ -753,7 +753,9 @@ static void handle_configure_xdg_shell_surface(void *data, struct xdg_surface *x xdg_surface_ack_configure(xdg, serial); } - wind->shell_surface.xdg.initial_configure_seen = true; + if (wind->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) { + wind->shell_surface_status = WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_FRAME; + } } static const struct xdg_surface_listener shell_surface_listener_xdg = { @@ -970,10 +972,6 @@ static void handle_configure_xdg_toplevel(void *data, wind->active = active; window->tiled = tiled; wind->resizing = resizing; - - if (wind->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) { - wind->shell_surface_status = WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_FRAME; - } } static void handle_close_xdg_toplevel(void *data, struct xdg_toplevel *xdg_toplevel) @@ -1122,9 +1120,7 @@ static void handle_configure_zxdg_decoration(void *data, WAYLAND_wl_display_roundtrip(internal->waylandData->display); Wayland_HideWindow(device, window); - SDL_zero(internal->shell_surface); internal->shell_surface_type = WAYLAND_SHELL_SURFACE_TYPE_LIBDECOR; - Wayland_ShowWindow(device, window); } } @@ -1406,11 +1402,8 @@ static void decoration_frame_configure(struct libdecor_frame *frame, libdecor_state_free(state); } - if (!wind->shell_surface.libdecor.initial_configure_seen) { - LibdecorGetMinContentSize(frame, &wind->system_limits.min_width, &wind->system_limits.min_height); - wind->shell_surface.libdecor.initial_configure_seen = true; - } if (wind->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) { + LibdecorGetMinContentSize(frame, &wind->system_limits.min_width, &wind->system_limits.min_height); wind->shell_surface_status = WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_FRAME; } @@ -1819,12 +1812,10 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) } } - /* The window was hidden, but the sync point hasn't yet been reached. - * Pump events to avoid a possible protocol violation. - */ - if (data->show_hide_sync_required) { + // Always roundtrip to ensure there are no pending buffer attachments. + do { WAYLAND_wl_display_roundtrip(c->display); - } + } while (data->show_hide_sync_required); data->shell_surface_status = WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE; @@ -1984,7 +1975,7 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) #ifdef HAVE_LIBDECOR_H if (data->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_LIBDECOR) { if (data->shell_surface.libdecor.frame) { - while (!data->shell_surface.libdecor.initial_configure_seen) { + while (data->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) { WAYLAND_wl_display_flush(c->display); WAYLAND_wl_display_dispatch(c->display); } @@ -1998,7 +1989,7 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) */ wl_surface_commit(data->surface); if (data->shell_surface.xdg.surface) { - while (!data->shell_surface.xdg.initial_configure_seen) { + while (data->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) { WAYLAND_wl_display_flush(c->display); WAYLAND_wl_display_dispatch(c->display); } @@ -2158,26 +2149,27 @@ void Wayland_HideWindow(SDL_VideoDevice *_this, SDL_Window *window) if (wind->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_LIBDECOR) { if (wind->shell_surface.libdecor.frame) { libdecor_frame_unref(wind->shell_surface.libdecor.frame); - wind->shell_surface.libdecor.frame = NULL; SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_SURFACE_POINTER, NULL); SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_TOPLEVEL_POINTER, NULL); } } else #endif + { if (wind->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_XDG_POPUP) { - Wayland_ReleasePopup(_this, window); - } else if (wind->shell_surface.xdg.toplevel.xdg_toplevel) { - xdg_toplevel_destroy(wind->shell_surface.xdg.toplevel.xdg_toplevel); - wind->shell_surface.xdg.toplevel.xdg_toplevel = NULL; - SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_TOPLEVEL_POINTER, NULL); - } - if (wind->shell_surface.xdg.surface) { - xdg_surface_destroy(wind->shell_surface.xdg.surface); - wind->shell_surface.xdg.surface = NULL; - SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_SURFACE_POINTER, NULL); + Wayland_ReleasePopup(_this, window); + } else if (wind->shell_surface.xdg.toplevel.xdg_toplevel) { + xdg_toplevel_destroy(wind->shell_surface.xdg.toplevel.xdg_toplevel); + SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_TOPLEVEL_POINTER, NULL); + } + + if (wind->shell_surface.xdg.surface) { + xdg_surface_destroy(wind->shell_surface.xdg.surface); + SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_SURFACE_POINTER, NULL); + } } + SDL_zero(wind->shell_surface); wind->show_hide_sync_required = true; struct wl_callback *cb = wl_display_sync(_this->internal->display); wl_callback_add_listener(cb, &show_hide_sync_listener, (void*)((uintptr_t)window->id)); diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index ee27f337b8..1afec8892f 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -48,7 +48,6 @@ struct SDL_WindowData struct { struct libdecor_frame *frame; - bool initial_configure_seen; } libdecor; #endif struct @@ -66,7 +65,6 @@ struct SDL_WindowData struct xdg_positioner *xdg_positioner; } popup; }; - bool initial_configure_seen; } xdg; } shell_surface; enum