SDL: win32: Let windows manage the floating state unless explicitly overridden

From 649556befa156201116a4f25089597463d0efd44 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sat, 13 Jan 2024 15:02:28 -0500
Subject: [PATCH] win32: Let windows manage the floating state unless
 explicitly overridden

Windows doesn't inform applications if the window is in the docked/tiled state, so let windows manage the window size when restoring from a fixed-size state, unless the application explicitly requested a new size/position.

Fixes the video_getSetWindowState test.
---
 src/video/windows/SDL_windowsevents.c | 19 +++++++++++++++++++
 src/video/windows/SDL_windowswindow.c |  4 ++++
 src/video/windows/SDL_windowswindow.h |  1 +
 3 files changed, 24 insertions(+)

diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index 98298afda17b..777291cdd127 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -1090,6 +1090,25 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         if (data->expected_resize) {
             returnCode = 0;
         }
+
+        if (data->floating_rect_pending &&
+            !IsIconic(hwnd) &&
+            !IsZoomed(hwnd) &&
+            (data->window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED)) &&
+            !(data->window->flags & SDL_WINDOW_FULLSCREEN)) {
+            /* If a new floating size is pending, apply it if moving from a fixed-size to floating state. */
+            WINDOWPOS *windowpos = (WINDOWPOS*)lParam;
+            int fx, fy, fw, fh;
+
+            WIN_AdjustWindowRect(data->window, &fx, &fy, &fw, &fh, SDL_WINDOWRECT_FLOATING);
+            windowpos->x = fx;
+            windowpos->y = fy;
+            windowpos->cx = fw;
+            windowpos->cy = fh;
+            windowpos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE);
+
+            data->floating_rect_pending = SDL_FALSE;
+        }
     } break;
 
     case WM_WINDOWPOSCHANGED:
diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c
index fbb816e531c5..896eb81266fd 100644
--- a/src/video/windows/SDL_windowswindow.c
+++ b/src/video/windows/SDL_windowswindow.c
@@ -829,6 +829,8 @@ int WIN_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
             return WIN_SetWindowPositionInternal(window,
                                                  window->driverdata->copybits_flag | SWP_NOZORDER | SWP_NOOWNERZORDER |
                                                  SWP_NOACTIVATE, SDL_WINDOWRECT_FLOATING);
+        } else {
+            window->driverdata->floating_rect_pending = SDL_TRUE;
         }
     } else {
         return SDL_UpdateFullscreenMode(window, SDL_TRUE, SDL_TRUE);
@@ -841,6 +843,8 @@ void WIN_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
 {
     if (!(window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED))) {
         WIN_SetWindowPositionInternal(window, window->driverdata->copybits_flag | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE, SDL_WINDOWRECT_FLOATING);
+    } else {
+        window->driverdata->floating_rect_pending = SDL_TRUE;
     }
 }
 
diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h
index 2e826230809f..9de65c3cc073 100644
--- a/src/video/windows/SDL_windowswindow.h
+++ b/src/video/windows/SDL_windowswindow.h
@@ -59,6 +59,7 @@ struct SDL_WindowData
     SDL_bool expected_resize;
     SDL_bool in_border_change;
     SDL_bool in_title_click;
+    SDL_bool floating_rect_pending;
     Uint8 focus_click_pending;
     SDL_bool skip_update_clipcursor;
     Uint64 last_updated_clipcursor;