Преглед на файлове

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.
Frank Praznik преди 1 седмица
родител
ревизия
adad7dcae0

+ 14 - 0
src/video/wayland/SDL_waylandwindow.c

@@ -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) {

+ 1 - 0
src/video/wayland/SDL_waylandwindow.h

@@ -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;

+ 3 - 0
src/video/x11/SDL_x11events.c

@@ -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);
     }
 }
 

+ 9 - 0
src/video/x11/SDL_x11window.c

@@ -1773,6 +1773,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);
     }
@@ -1807,6 +1812,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;
 

+ 1 - 0
src/video/x11/SDL_x11window.h

@@ -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;