SDL: wayland: Deduplicate calls to position fullscreen windows already on the correct output

From 9370f9ca85d83972b4a7c175a0c69a58cd1acee6 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sun, 12 Feb 2023 16:23:53 -0500
Subject: [PATCH] wayland: Deduplicate calls to position fullscreen windows
 already on the correct output

---
 src/video/wayland/SDL_waylandwindow.c | 32 +++++++++++++++++----------
 src/video/wayland/SDL_waylandwindow.h |  2 +-
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 55263fdfd33c..1b98e7c8f88b 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -549,11 +549,14 @@ static void handle_configure_xdg_toplevel(void *data,
                             maximized ? SDL_EVENT_WINDOW_MAXIMIZED : SDL_EVENT_WINDOW_RESTORED,
                             0, 0);
     } else {
-        /* If an exclusive fullscreen mode was requested, ensure it is placed on the appropriate output. */
-        if (window->fullscreen_exclusive && wind->fullscreen_display != window->fullscreen_mode.displayID) {
+        /* Unconditionally set the output for exclusive fullscreen windows when entering
+         * fullscreen from a compositor event, as where the compositor will actually
+         * place the fullscreen window is unknown.
+         */
+        if (window->fullscreen_exclusive && !wind->fullscreen_was_positioned) {
             SDL_VideoDisplay *disp = SDL_GetVideoDisplay(window->fullscreen_mode.displayID);
             if (disp) {
-                wind->fullscreen_display = disp->id;
+                wind->fullscreen_was_positioned = SDL_TRUE;
                 xdg_toplevel_set_fullscreen(xdg_toplevel, disp->driverdata->output);
             }
         }
@@ -760,11 +763,14 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
      * Always assume the configure is wrong.
      */
     if (fullscreen) {
-        /* If an exclusive fullscreen mode was requested, ensure it is placed on the appropriate output. */
-        if (window->fullscreen_exclusive && wind->fullscreen_display != window->fullscreen_mode.displayID) {
+        /* Unconditionally set the output for exclusive fullscreen windows when entering
+         * fullscreen from a compositor event, as where the compositor will actually
+         * place the fullscreen window is unknown.
+         */
+        if (window->fullscreen_exclusive && !wind->fullscreen_was_positioned) {
             SDL_VideoDisplay *disp = SDL_GetVideoDisplay(window->fullscreen_mode.displayID);
             if (disp) {
-                wind->fullscreen_display = disp->id;
+                wind->fullscreen_was_positioned = SDL_TRUE;
                 libdecor_frame_set_fullscreen(frame, disp->driverdata->output);
             }
         }
@@ -1583,8 +1589,8 @@ void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window,
     /* Called from within a configure event or the window is a popup, drop it. */
     if (wind->in_fullscreen_transition || wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) {
         if (!fullscreen) {
-            /* Clear the display ID so it will be set next time. */
-            wind->fullscreen_display = 0;
+            /* Clear the fullscreen positioned flag. */
+            wind->fullscreen_was_positioned = SDL_FALSE;
         }
         return;
     }
@@ -1592,7 +1598,7 @@ void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window,
     /* Don't send redundant fullscreen set/unset events. */
     if (wind->is_fullscreen != fullscreen) {
         wind->is_fullscreen = fullscreen;
-        wind->fullscreen_display = fullscreen ? display->id : 0;
+        wind->fullscreen_was_positioned = fullscreen ? SDL_TRUE : SDL_FALSE;
         SetFullscreen(window, fullscreen ? output : NULL);
 
         /* Roundtrip required to receive the updated window dimensions */
@@ -1601,10 +1607,12 @@ void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window,
         /*
          * If the window is already fullscreen, this is likely a request to switch between
          * fullscreen and fullscreen desktop, change outputs, or change the video mode.
-         * Update the geometry and trigger a commit.
+         *
+         * If the window is already positioned on the target output, just update the
+         * window geometry.
          */
-        if (wind->fullscreen_display != display->id) {
-            wind->fullscreen_display = display->id;
+        if (window->last_displayID != display->id) {
+            wind->fullscreen_was_positioned = SDL_TRUE;
             SetFullscreen(window, output);
         } else {
             ConfigureWindowGeometry(window);
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index 292a5f8130e9..7391408ff2e7 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -111,10 +111,10 @@ struct SDL_WindowData
     int wl_window_width, wl_window_height;
     int system_min_required_width;
     int system_min_required_height;
-    SDL_DisplayID fullscreen_display;
     SDL_bool floating;
     SDL_bool is_fullscreen;
     SDL_bool in_fullscreen_transition;
+    SDL_bool fullscreen_was_positioned;
 };
 
 extern void Wayland_ShowWindow(_THIS, SDL_Window *window);