diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 4802303cca..641ff9b272 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -1473,8 +1473,13 @@ 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; } 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 (windowpos->flags & SWP_HIDEWINDOW) { @@ -1873,14 +1878,14 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam; WINDOWPLACEMENT placement; if (GetWindowPlacement(hwnd, &placement) && placement.showCmd == SW_MAXIMIZE) { - // Maximized borderless windows should use the full monitor size + // Maximized borderless windows should use the monitor work area. HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL); if (hMonitor) { MONITORINFO info; SDL_zero(info); info.cbSize = sizeof(info); if (GetMonitorInfo(hMonitor, &info)) { - params->rgrc[0] = info.rcMonitor; + params->rgrc[0] = info.rcWork; } } } else if (!(window_flags & SDL_WINDOW_RESIZABLE)) { diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index b07d7dc0fb..a5d17c0f30 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -180,13 +180,22 @@ static DWORD GetWindowStyle(SDL_Window *window) style |= STYLE_NORMAL; } - if (window->flags & SDL_WINDOW_RESIZABLE) { + /* 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)) { /* 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", false)) { 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; } } diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h index ddc3ddd6d9..3a21a1c258 100644 --- a/src/video/windows/SDL_windowswindow.h +++ b/src/video/windows/SDL_windowswindow.h @@ -81,6 +81,7 @@ struct SDL_WindowData bool skip_update_clipcursor; bool windowed_mode_was_maximized; bool in_window_deactivation; + bool force_resizable; 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 UINT windowed_mode_corner_rounding;