From ce1175724a357d93b319625aa2f2a6457a15e3eb Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sun, 5 Oct 2025 14:40:45 -0400
Subject: [PATCH] win32: Don't overwrite a programmatically set window size
with old data
While in a modal loop, the size in WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED may only be updated if the window is being resized interactively. Set the SWP_NOSIZE flag if the size hasn't changed from the last move/size event, or a size set programmatically may end up being overwritten by old size data.
---
src/video/windows/SDL_windowsevents.c | 21 +++++++++++++++++++++
src/video/windows/SDL_windowswindow.h | 2 ++
2 files changed, 23 insertions(+)
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index f4bf6381e4da8..9c8bf6d103bc2 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -1708,6 +1708,21 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
case WM_WINDOWPOSCHANGING:
if (data->expected_resize) {
+ returnCode = 0;
+ } else if (data->in_modal_loop) {
+ WINDOWPOS *windowpos = (WINDOWPOS *)lParam;
+
+ /* While in a modal loop, the size may only be updated if the window is being resized interactively.
+ * Set the SWP_NOSIZE flag if the reported size hasn't changed from the last WM_WINDOWPOSCHANGING
+ * event, or a size set programmatically may end up being overwritten by old size data.
+ */
+ if (data->last_modal_width == windowpos->cx && data->last_modal_height == windowpos->cy) {
+ windowpos->flags |= SWP_NOSIZE;
+ }
+
+ data->last_modal_width = windowpos->cx;
+ data->last_modal_height = windowpos->cy;
+
returnCode = 0;
}
break;
@@ -1819,6 +1834,12 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
++data->in_modal_loop;
if (data->in_modal_loop == 1) {
+ RECT rect;
+ SDL_zero(rect);
+ GetWindowRect(data->hwnd, &rect);
+ data->last_modal_width = rect.right - rect.left;
+ data->last_modal_height = rect.bottom - rect.top;
+
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;
diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h
index 9175990954bca..5d22b4fb9ea12 100644
--- a/src/video/windows/SDL_windowswindow.h
+++ b/src/video/windows/SDL_windowswindow.h
@@ -86,6 +86,8 @@ struct SDL_WindowData
bool disable_move_size_events;
bool showing_window;
int in_modal_loop;
+ int last_modal_width;
+ int last_modal_height;
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