From b835f8e77c5bdee351958d0785bb19fb1607d8dd Mon Sep 17 00:00:00 2001 From: nx111 Date: Fri, 10 Jul 2026 22:45:21 +0800 Subject: [PATCH] Fix Windows maximize geometry at high DPI On Windows, DWM can report stale or out-of-range extended frame bounds during maximize and DPI transitions. Applying those values unconditionally can distort the working area and preserve stale startup geometry. Validate the reported extended frame before using it, avoid recalculating geometry after native maximize has selected the work-area rectangle, and ignore suggested WM_DPICHANGED rectangles while maximized or fullscreen. This keeps native maximize and monitor-DPI transitions under Windows control without changing normal windowed resizing. --- video/out/w32_common.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/video/out/w32_common.c b/video/out/w32_common.c index ba4f3825ec176..e9f57957967a7 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -830,7 +830,11 @@ static void adjust_working_area_for_extended_frame(RECT *wa_rect, RECT *wnd_rect RECT frame = {0}; if (DwmGetWindowAttribute(wnd, DWMWA_EXTENDED_FRAME_BOUNDS, - &frame, sizeof(RECT)) == S_OK) { + &frame, sizeof(RECT)) == S_OK && + rect_w(frame) > 0 && rect_h(frame) > 0 && + frame.left >= wnd_rect->left && frame.top >= wnd_rect->top && + frame.right <= wnd_rect->right && frame.bottom <= wnd_rect->bottom) + { wa_rect->left -= frame.left - wnd_rect->left; wa_rect->top -= frame.top - wnd_rect->top; wa_rect->right += wnd_rect->right - frame.right; @@ -1440,11 +1444,16 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, bool updated = (m_config_cache_write_opt(w32->opts_cache, &w32->opts->window_maximized) || m_config_cache_write_opt(w32->opts_cache, &w32->opts->window_minimized)); if (updated || w32->pending_resize) { - // We call window resize here, only to recalculate possible window - // size after changing the style, but we want to preserve the client - // size. - w32->window_state_changed = true; - window_resize(w32); + // Native maximize has already selected the work-area rectangle. + // Re-entering geometry calculation here can overwrite it with + // stale startup bounds, especially on a high-DPI display. + if (wParam != SIZE_MAXIMIZED) { + // We call window resize here, only to recalculate possible window + // size after changing the style, but we want to preserve the client + // size. + w32->window_state_changed = true; + window_resize(w32); + } events |= VO_EVENT_WIN_STATE; } @@ -1476,6 +1485,9 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, case WM_DPICHANGED: update_display_info(w32); + if (IsMaximized(w32->window) || w32->current_fs) + break; + RECT *rc = (RECT*)lParam; w32->current_rect = *rc; subtract_window_borders(w32, w32->window, &w32->current_rect);