From ce1175724a357d93b319625aa2f2a6457a15e3eb Mon Sep 17 00:00:00 2001 From: Frank Praznik 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 f4bf6381e4..9c8bf6d103 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 9175990954..5d22b4fb9e 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