From 6449339ae353de91440a05305222c56ed328602c Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Mon, 20 Jan 2025 14:04:33 -0500
Subject: [PATCH] win32: Restore the base size of a window when leaving
fullscreen
Always restore the base floating size of a window before possibly entering the maximized state, as base size can be lost during the fullscreen transition, resulting in the window de-maximizing to the wrong size.
---
src/video/windows/SDL_windowsevents.c | 28 ++++++++++++++-------------
src/video/windows/SDL_windowswindow.c | 17 +++++++++-------
src/video/windows/SDL_windowswindow.h | 1 +
3 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index 459f43dfa5202..3ef492ec5679b 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -1633,23 +1633,25 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
break;
}
- if (GetClientRect(hwnd, &rect) && !WIN_IsRectEmpty(&rect)) {
- ClientToScreen(hwnd, (LPPOINT) &rect);
- ClientToScreen(hwnd, (LPPOINT) &rect + 1);
+ if (!data->disable_move_size_events) {
+ if (GetClientRect(hwnd, &rect) && !WIN_IsRectEmpty(&rect)) {
+ ClientToScreen(hwnd, (LPPOINT) &rect);
+ ClientToScreen(hwnd, (LPPOINT) &rect + 1);
- x = rect.left;
- y = rect.top;
+ x = rect.left;
+ y = rect.top;
- SDL_GlobalToRelativeForWindow(data->window, x, y, &x, &y);
- SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MOVED, x, y);
- }
+ SDL_GlobalToRelativeForWindow(data->window, x, y, &x, &y);
+ SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MOVED, x, y);
+ }
- // Moving the window from one display to another can change the size of the window (in the handling of SDL_EVENT_WINDOW_MOVED), so we need to re-query the bounds
- if (GetClientRect(hwnd, &rect) && !WIN_IsRectEmpty(&rect)) {
- w = rect.right;
- h = rect.bottom;
+ // Moving the window from one display to another can change the size of the window (in the handling of SDL_EVENT_WINDOW_MOVED), so we need to re-query the bounds
+ if (GetClientRect(hwnd, &rect) && !WIN_IsRectEmpty(&rect)) {
+ w = rect.right;
+ h = rect.bottom;
- SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED, w, h);
+ SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED, w, h);
+ }
}
WIN_UpdateClipCursor(data->window);
diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c
index b3d2d69f23b9f..6ca0bfde57bc6 100644
--- a/src/video/windows/SDL_windowswindow.c
+++ b/src/video/windows/SDL_windowswindow.c
@@ -1377,28 +1377,31 @@ SDL_FullscreenResult WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window
https://bugzilla.libsdl.org/show_bug.cgi?id=3215 can reproduce!
*/
if (data->windowed_mode_was_maximized && !data->in_window_deactivation) {
- style |= WS_MAXIMIZE;
enterMaximized = true;
+ data->disable_move_size_events = true;
}
menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
WIN_AdjustWindowRectWithStyle(window, style, styleEx, menu,
&x, &y,
&w, &h,
- data->windowed_mode_was_maximized ? SDL_WINDOWRECT_WINDOWED : SDL_WINDOWRECT_FLOATING);
+ SDL_WINDOWRECT_FLOATING);
data->windowed_mode_was_maximized = false;
}
+
+ /* Always reset the window to the base floating size before possibly re-applying the maximized state,
+ * otherwise, the base floating size can seemingly be lost in some cases.
+ */
SetWindowLong(hwnd, GWL_STYLE, style);
data->expected_resize = true;
+ SetWindowPos(hwnd, top, x, y, w, h, data->copybits_flag | SWP_NOACTIVATE);
+ data->expected_resize = false;
+ data->disable_move_size_events = false;
- if (!enterMaximized) {
- SetWindowPos(hwnd, top, x, y, w, h, data->copybits_flag | SWP_NOACTIVATE);
- } else {
+ if (enterMaximized) {
WIN_MaximizeWindow(_this, window);
}
- data->expected_resize = false;
-
#ifdef HIGHDPI_DEBUG
SDL_Log("WIN_SetWindowFullscreen: %d finished. Set window to %d,%d, %dx%d", (int)fullscreen, x, y, w, h);
#endif
diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h
index 467c5b893fffa..1430dee572b08 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;
+ bool disable_move_size_events;
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