SDL: windows: use the initial rect to anchor fixed aspect ratio resizing

From 18d21b36febb86abbf791e83bc61a8d4c85d85a4 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 15 Jan 2025 10:03:48 -0800
Subject: [PATCH] windows: use the initial rect to anchor fixed aspect ratio
 resizing

Fixes https://github.com/libsdl-org/SDL/issues/11688
---
 src/video/windows/SDL_windowsevents.c | 13 +++++++++----
 src/video/windows/SDL_windowswindow.h |  1 +
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index 18edb76d330d5..60ccac8ebe115 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -1682,6 +1682,11 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
     case WM_ENTERSIZEMOVE:
     case WM_ENTERMENULOOP:
     {
+        data->initial_size_rect.left = data->window->x;
+        data->initial_size_rect.right = data->window->x + data->window->w;
+        data->initial_size_rect.top = data->window->y;
+        data->initial_size_rect.bottom = data->window->y + data->window->h;
+
         SetTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks, USER_TIMER_MINIMUM, NULL);
     } break;
 
@@ -1775,7 +1780,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
             case WMSZ_LEFT:
                 clientDragRect.left = clientDragRect.right - w;
                 if (lock_aspect_ratio) {
-                    clientDragRect.top = (clientDragRect.bottom + clientDragRect.top - h) / 2;
+                    clientDragRect.top = (data->initial_size_rect.bottom + data->initial_size_rect.top - h) / 2;
                 }
                 clientDragRect.bottom = h + clientDragRect.top;
                 break;
@@ -1786,7 +1791,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
             case WMSZ_RIGHT:
                 clientDragRect.right = w + clientDragRect.left;
                 if (lock_aspect_ratio) {
-                    clientDragRect.top = (clientDragRect.bottom + clientDragRect.top - h) / 2;
+                    clientDragRect.top = (data->initial_size_rect.bottom + data->initial_size_rect.top - h) / 2;
                 }
                 clientDragRect.bottom = h + clientDragRect.top;
                 break;
@@ -1796,7 +1801,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
                 break;
             case WMSZ_TOP:
                 if (lock_aspect_ratio) {
-                    clientDragRect.left = (clientDragRect.right + clientDragRect.left - w) / 2;
+                    clientDragRect.left = (data->initial_size_rect.right + data->initial_size_rect.left - w) / 2;
                 }
                 clientDragRect.right = w + clientDragRect.left;
                 clientDragRect.top = clientDragRect.bottom - h;
@@ -1807,7 +1812,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
                 break;
             case WMSZ_BOTTOM:
                 if (lock_aspect_ratio) {
-                    clientDragRect.left = (clientDragRect.right + clientDragRect.left - w) / 2;
+                    clientDragRect.left = (data->initial_size_rect.right + data->initial_size_rect.left - w) / 2;
                 }
                 clientDragRect.right = w + clientDragRect.left;
                 clientDragRect.bottom = h + clientDragRect.top;
diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h
index 6d37e1630d454..467c5b893fffa 100644
--- a/src/video/windows/SDL_windowswindow.h
+++ b/src/video/windows/SDL_windowswindow.h
@@ -82,6 +82,7 @@ struct SDL_WindowData
     bool windowed_mode_was_maximized;
     bool in_window_deactivation;
     bool force_resizable;
+    RECT initial_size_rect;
     RECT cursor_clipped_rect; // last successfully committed clipping rect for this window
     RECT cursor_ctrlock_rect; // this is Windows-specific, but probably does not need to be per-window
     UINT windowed_mode_corner_rounding;