From 10a5b388df7102e1fc089b689c4a8a0b6b8da572 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Mon, 20 Jan 2025 14:17:39 -0500
Subject: [PATCH] win32: Retain the WS_MAXIMIZEDBOX style while in fullscreen
This needs to be preserved while in fullscreen, or leaving fullscreen for the maximized state can cause the taskbar to disappear with borderless windows.
---
src/video/windows/SDL_windowsevents.c | 14 +++++++++-----
src/video/windows/SDL_windowswindow.c | 16 +++++++++-------
src/video/windows/SDL_windowswindow.h | 2 +-
3 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index 3ef492ec5679b..0fcb08b00c27e 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -1611,13 +1611,17 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
}
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
- data->force_resizable = true;
+ data->force_ws_maximizebox = true;
} else if (data->window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED)) {
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
- // If resizable was forced on for the maximized window, clear the style flags now.
- data->force_resizable = false;
- WIN_SetWindowResizable(SDL_GetVideoDevice(), data->window, !!(data->window->flags & SDL_WINDOW_RESIZABLE));
+ /* If resizable was forced on for the maximized window, clear the style flags now,
+ * but not if the window is fullscreen, as this needs to be preserved in that case.
+ */
+ if (!(data->window->flags & SDL_WINDOW_FULLSCREEN)) {
+ data->force_ws_maximizebox = false;
+ WIN_SetWindowResizable(SDL_GetVideoDevice(), data->window, !!(data->window->flags & SDL_WINDOW_RESIZABLE));
+ }
}
if (windowpos->flags & SWP_HIDEWINDOW) {
@@ -2038,7 +2042,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
params->rgrc[0] = info.rcWork;
}
}
- } else if (!(window_flags & SDL_WINDOW_RESIZABLE) && !data->force_resizable) {
+ } else if (!(window_flags & SDL_WINDOW_RESIZABLE) && !data->force_ws_maximizebox) {
int w, h;
if (data->window->last_size_pending) {
w = data->window->pending.w;
diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c
index 6ca0bfde57bc6..1711fc0a597c0 100644
--- a/src/video/windows/SDL_windowswindow.c
+++ b/src/video/windows/SDL_windowswindow.c
@@ -185,22 +185,24 @@ static DWORD GetWindowStyle(SDL_Window *window)
/* The WS_MAXIMIZEBOX style flag needs to be retained for as long as the window is maximized,
* or restoration from minimized can fail, and leaving maximized can result in an odd size.
*/
- if ((window->flags & SDL_WINDOW_RESIZABLE) || (window->internal && window->internal->force_resizable)) {
+ if (window->flags & SDL_WINDOW_RESIZABLE) {
/* You can have a borderless resizable window, but Windows doesn't always draw it correctly,
see https://bugzilla.libsdl.org/show_bug.cgi?id=4466
*/
if (!(window->flags & SDL_WINDOW_BORDERLESS) ||
SDL_GetHintBoolean("SDL_BORDERLESS_RESIZABLE_STYLE", true)) {
style |= STYLE_RESIZABLE;
- } else if (window->flags & SDL_WINDOW_BORDERLESS) {
- /* Even if the resizable style hint isn't set, WS_MAXIMIZEBOX is still needed, or
- * maximizing the window will make it fullscreen and cover the taskbar, instead
- * of entering a normal maximized state that fills the usable desktop area.
- */
- style |= WS_MAXIMIZEBOX;
}
}
+ if (window->internal && window->internal->force_ws_maximizebox) {
+ /* Even if the resizable flag is cleared, WS_MAXIMIZEBOX is still needed as long
+ * as the window is maximized, or de-maximizing or minimizing and restoring the
+ * maximized window can result in the window disappearing or being the wrong size.
+ */
+ style |= WS_MAXIMIZEBOX;
+ }
+
// Need to set initialize minimize style, or when we call ShowWindow with WS_MINIMIZE it will activate a random window
if (window->flags & SDL_WINDOW_MINIMIZED) {
style |= WS_MINIMIZE;
diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h
index 1430dee572b08..d8165d0b52e03 100644
--- a/src/video/windows/SDL_windowswindow.h
+++ b/src/video/windows/SDL_windowswindow.h
@@ -81,7 +81,7 @@ struct SDL_WindowData
bool skip_update_clipcursor;
bool windowed_mode_was_maximized;
bool in_window_deactivation;
- bool force_resizable;
+ bool force_ws_maximizebox;
bool disable_move_size_events;
RECT initial_size_rect;
RECT cursor_clipped_rect; // last successfully committed clipping rect for this window