Skip to content

Fix Windows maximize geometry at high DPI - #18254

Open
nx111 wants to merge 1 commit into
mpv-player:masterfrom
nx111:codex/mpv-w32-high-dpi-geometry
Open

Fix Windows maximize geometry at high DPI#18254
nx111 wants to merge 1 commit into
mpv-player:masterfrom
nx111:codex/mpv-w32-high-dpi-geometry

Conversation

@nx111

@nx111 nx111 commented Jul 11, 2026

Copy link
Copy Markdown

Problem

On Windows with PerMonitorV2 and fractional display scaling, WM_SIZE and
WM_DPICHANGED can arrive after the operating system has already selected the
native maximized geometry.

mpv may then recalculate the window using stale startup geometry. At the same
time, DWM can return invalid extended frame bounds, and applying the suggested
WM_DPICHANGED rectangle while maximized or fullscreen can disturb the native
window state.

This can leave a maximized window offset from the monitor work area or with
blank margins around the content.

Changes

  • Validate DWM extended frame bounds before using them to adjust the work area.
  • Do not recalculate window geometry for SIZE_MAXIMIZED.
  • Ignore the suggested WM_DPICHANGED rectangle while maximized or fullscreen.

This keeps native maximize and DPI transitions under Windows control while
preserving the existing behavior for normal windowed resizing.

Testing

  • Built mpv/libmpv successfully with the Windows Clang64 toolchain.
  • Built Jellyfin Desktop successfully against the patched libmpv.
  • Manually validated maximize/restore behavior on Windows 11 with a
    3840x2160 display and 250% scaling.
  • The patch applies cleanly to the current mpv master branch.

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.
Comment thread video/out/w32_common.c
&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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this condition?

Comment thread video/out/w32_common.c
// 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) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't it break the maximize state change in general, it won't trigger resize anymore, so title bar size will not be recalculated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants