From 10a5b388df7102e1fc089b689c4a8a0b6b8da572 Mon Sep 17 00:00:00 2001 From: Frank Praznik 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 3ef492ec56..0fcb08b00c 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 6ca0bfde57..1711fc0a59 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 1430dee572..d8165d0b52 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