SDL: wayland: Eliminate excessive calls to SetFullscreen

From 650612fdcb74d99589a5ebbd12081922b4b94a3c Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sat, 13 Aug 2022 16:54:27 -0400
Subject: [PATCH] wayland: Eliminate excessive calls to SetFullscreen

Eliminate excessive calls to SetFullscreen by removing the calls in the libdecor and xdg-toplevel config callbacks.

These calls were being made there in case something explicitly called the window minimization function from within SDL, which unsets fullscreen, and as minimizing a window in Wayland is just a suggestion to the compositor and doesn't actually change the window state or communicate anything back to the application, it was necessary to call SetFullscreen in every call to the config functions just in case something minimized a window via SDL_MinimizeWindow() and later needed to restore it.  GNOME in particular had issues when fullscreen set/unset operations were being hammered, leading to overlapping acks and commits when switching to fullscreen.

With the new video system flag to disable unsetting fullscreen when minimizing a window, these calls in the configuration functions are no longer needed and can be removed. This significantly reduces calls to the SetFullscreen() function, reverts #6044 while fixing the issue, and fixes a similar problem when hiding and showing a window initially created with fullscreen flags.
---
 src/video/wayland/SDL_waylandvideo.c  |  3 ++-
 src/video/wayland/SDL_waylandwindow.c | 19 ++-----------------
 src/video/wayland/SDL_waylandwindow.h |  1 -
 3 files changed, 4 insertions(+), 19 deletions(-)

diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 10186a20ec7..4642c0d8bf9 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -279,7 +279,8 @@ Wayland_CreateDevice(void)
 
     device->free = Wayland_DeleteDevice;
 
-    device->quirk_flags = VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING;
+    device->quirk_flags = VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING |
+                          VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE;
 
     return device;
 }
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index c63bb1b94a1..571bce0475e 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -547,9 +547,6 @@ handle_configure_xdg_toplevel(void *data,
 
     if (!fullscreen) {
         if (window->flags & SDL_WINDOW_FULLSCREEN) {
-            /* We might need to re-enter fullscreen after being restored from minimized */
-            SetFullscreen(window, driverdata->output, SDL_FALSE);
-
             /* Foolishly do what the compositor says here. If it's wrong, don't
              * blame us, we were explicitly instructed to do this.
              *
@@ -785,13 +782,6 @@ decoration_frame_configure(struct libdecor_frame *frame,
     driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata;
 
     if (!fullscreen) {
-        if (window->flags & SDL_WINDOW_FULLSCREEN) {
-            /* We might need to re-enter fullscreen after being restored from minimized */
-            SetFullscreen(window, driverdata->output, SDL_FALSE);
-            fullscreen = SDL_TRUE;
-            floating = SDL_FALSE;
-        }
-
         /* Always send a maximized/restore event; if the event is redundant it will
          * automatically be discarded (see src/events/SDL_windowevents.c)
          *
@@ -1311,8 +1301,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
          * libdecor will call this as part of their configure event!
          * -flibit
          */
-        SDL_WaylandOutputData *odata = SDL_GetDisplayForWindow(window)->driverdata;
-        SetFullscreen(window, (window->flags & SDL_WINDOW_FULLSCREEN) ? odata->output : NULL, SDL_TRUE);
+        wl_surface_commit(data->surface);
         if (data->shell_surface.xdg.surface) {
             while (!data->shell_surface.xdg.initial_configure_seen) {
                 WAYLAND_wl_display_flush(c->display);
@@ -1370,10 +1359,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
      * Roundtrip required to avoid a possible protocol violation when
      * HideWindow was called immediately before ShowWindow.
      */
-    if (data->needs_roundtrip) {
-        data->needs_roundtrip = SDL_FALSE;
-        WAYLAND_wl_display_roundtrip(c->display);
-    }
+    WAYLAND_wl_display_roundtrip(c->display);
 }
 
 static void
@@ -1450,7 +1436,6 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
      * Roundtrip required to avoid a possible protocol violation when
      * ShowWindow is called immediately after HideWindow.
      */
-    wind->needs_roundtrip = SDL_TRUE;
     WAYLAND_wl_display_roundtrip(data->display);
 }
 
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index d408f14a439..703ec53da45 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -107,7 +107,6 @@ typedef struct {
     SDL_Rect viewport_rect;
     SDL_bool needs_resize_event;
     SDL_bool floating_resize_pending;
-    SDL_bool needs_roundtrip;
 } SDL_WindowData;
 
 extern void Wayland_ShowWindow(_THIS, SDL_Window *window);