x11/wayland: Ignore redundant restore and fullscreen leave requests when showing the window

The window may be initially maximized or made fullscreen by the window manager for various reasons, such as automatically declaring a window that precisely fills the usable desktop space as maximized, or a "kiosk-mode" automatically making the window fullscreen.

Don't redundantly make restored or unset fullscreen calls when initially showing a window, or the expected state can be unset.

(cherry picked from commit adad7dcae0)
This commit is contained in:
Frank Praznik
2025-04-06 12:29:41 -04:00
parent e225a10ea8
commit ba5325fba1
5 changed files with 28 additions and 0 deletions

View File

@@ -2055,6 +2055,10 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
struct wl_callback *cb = wl_display_sync(_this->internal->display);
wl_callback_add_listener(cb, &show_hide_sync_listener, (void*)((uintptr_t)window->id));
data->showing_window = true;
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_SHOWN, 0, 0);
data->showing_window = false;
// Send an exposure event to signal that the client should draw.
if (data->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_FRAME) {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 0, 0);
@@ -2277,6 +2281,11 @@ SDL_FullscreenResult Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Win
return SDL_FULLSCREEN_FAILED;
}
// Drop fullscreen leave requests when showing the window.
if (wind->showing_window && fullscreen == SDL_FULLSCREEN_OP_LEAVE) {
return SDL_FULLSCREEN_SUCCEEDED;
}
if (wind->show_hide_sync_required) {
WAYLAND_wl_display_roundtrip(_this->internal->display);
}
@@ -2331,6 +2340,11 @@ void Wayland_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
SDL_WindowData *wind = window->internal;
// Drop restore requests when showing the window.
if (wind->showing_window) {
return;
}
// Not currently fullscreen or maximized, and no state pending; nothing to do.
if (!(window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED)) &&
!wind->fullscreen_deadline_count && !wind->maximized_restored_deadline_count) {

View File

@@ -198,6 +198,7 @@ struct SDL_WindowData
bool is_fullscreen;
bool fullscreen_exclusive;
bool drop_fullscreen_requests;
bool showing_window;
bool fullscreen_was_positioned;
bool show_hide_sync_required;
bool scale_to_display;

View File

@@ -508,6 +508,7 @@ static void X11_DispatchMapNotify(SDL_WindowData *data)
SDL_Window *window = data->window;
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_SHOWN, 0, 0);
data->was_shown = true;
// This may be sent when restoring a minimized window.
if (window->flags & SDL_WINDOW_MINIMIZED) {
@@ -528,6 +529,8 @@ static void X11_DispatchUnmapNotify(SDL_WindowData *data)
if (!window->is_hiding) {
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_OCCLUDED, 0, 0);
} else {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_HIDDEN, 0, 0);
}
}

View File

@@ -1765,6 +1765,11 @@ void X11_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
void X11_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
// Don't restore the window the first time it is being shown.
if (!window->internal->was_shown) {
return;
}
if (window->internal->pending_operation & (X11_PENDING_OP_FULLSCREEN | X11_PENDING_OP_MAXIMIZE | X11_PENDING_OP_MINIMIZE)) {
SDL_SyncWindow(window);
}
@@ -1799,6 +1804,10 @@ static SDL_FullscreenResult X11_SetWindowFullscreenViaWM(SDL_VideoDevice *_this,
Atom _NET_WM_STATE = data->videodata->atoms._NET_WM_STATE;
Atom _NET_WM_STATE_FULLSCREEN = data->videodata->atoms._NET_WM_STATE_FULLSCREEN;
if (!data->was_shown && fullscreen == SDL_FULLSCREEN_OP_LEAVE) {
return SDL_FULLSCREEN_SUCCEEDED;
}
if (X11_IsWindowMapped(_this, window)) {
XEvent e;

View File

@@ -115,6 +115,7 @@ struct SDL_WindowData
bool previous_borders_nonzero;
bool toggle_borders;
bool fullscreen_borders_forced_on;
bool was_shown;
SDL_HitTestResult hit_test_result;
XPoint xim_spot;