Skip to content

win32: remove SC_RESTORE handling#16127

Merged
kasper93 merged 6 commits intompv-player:masterfrom
kasper93:fix_fs_opt
Mar 13, 2026
Merged

win32: remove SC_RESTORE handling#16127
kasper93 merged 6 commits intompv-player:masterfrom
kasper93:fix_fs_opt

Conversation

@kasper93
Copy link
Member

No description provided.

@kasper93
Copy link
Member Author

@na-na-hi do you know where this would be needed? I couldn't reproduce on my end. Maybe it was FSE mode that is no longer with us.

@github-actions
Copy link

Download the artifacts for this pull request:

Windows
macOS

@na-na-hi
Copy link
Contributor

do you know where this would be needed?

After a maximized window is put in fullscreen, when you press win+down, it exits fullscreen in a maximized state.

@kasper93
Copy link
Member Author

do you know where this would be needed?

After a maximized window is put in fullscreen, when you press win+down, it exits fullscreen in a maximized state.

I see, but what is expected behavior in this case? Shouldn't it exit fullscreen? Same as win+down goes from maximized to windowed first.

@na-na-hi
Copy link
Contributor

I see, but what is expected behavior in this case? Shouldn't it exit fullscreen?

It does. As I already said, currently win+down in fullscreen exits fullscreen if window-maximized=yes. With this PR, it instead restores to the unmaximized size while still retaining the fullscreen state, so the window has no titlebar and cannot be resized or dragged.

@kasper93
Copy link
Member Author

kasper93 commented Mar 27, 2025

I see, but what is expected behavior in this case? Shouldn't it exit fullscreen?

It does. As I already said, currently win+down in fullscreen exits fullscreen if window-maximized=yes.

But if it is not maximized it minimize instead. Is this expected to you?

I found dozen other bugs when testing this again, so we can postpone this discussion. I only wanted to know if this is expected that fs=yes window-maximized=no minimizes the window instead of restoring it to window state.

@na-na-hi
Copy link
Contributor

But if it is not maximized it minimize instead. Is this expected to you?

win+down on a non-maximized window normally minimizes it. Technically fs=yes window-maximized=no is non-maximized. MPC-HC does the same thing, just in a more buggy way. VLC does nothing with win+down on fullscreen.

I don't think there is any expected behavior in this case. As long as it does not leave the window in a buggy state it should be fine.

@kasper93 kasper93 marked this pull request as draft July 4, 2025 19:36
@kasper93 kasper93 marked this pull request as ready for review March 5, 2026 20:16
@kasper93
Copy link
Member Author

kasper93 commented Mar 5, 2026

@na-na-hi: Could you help testing this one? I had it long in the backlog. Let me know of any undesirable behavior, maybe we will manage to get this in.

@kasper93 kasper93 force-pushed the fix_fs_opt branch 3 times, most recently from d857d7a to 32dae59 Compare March 5, 2026 20:43
@na-na-hi
Copy link
Contributor

na-na-hi commented Mar 6, 2026

The latest version still has this issue: #16127 (comment)

@kasper93
Copy link
Member Author

kasper93 commented Mar 6, 2026

The latest version still has this issue: #16127 (comment)

Should be fine now, could you try again?

@na-na-hi
Copy link
Contributor

na-na-hi commented Mar 6, 2026

Should be fine now, could you try again?

That issue is fixed but there is a new one: maximize, fullscreen, then print the value of window-maximized shows no, when it should be yes.

@kasper93
Copy link
Member Author

kasper93 commented Mar 6, 2026

Should be fine now, could you try again?

That issue is fixed but there is a new one: maximize, fullscreen, then print the value of window-maximized shows no, when it should be yes.

Updated. One thing I really wanted to have is to keep window-maximized and window-minimized state actually reflect the window state. And apparently in fullscreen we need to restore window to normal, to avoid (external) window restore to do bad things to us. So, now I made an exception that window_maximized = w32->pending_maximize && w32->current_fs, so when we have pending maximize (i.e. we will go back to maximize after fullscreen) window-maximized will report yes.

Hopefully, this doesn't cause domino effect in some other parts. But when it really matters, I tried to use IsMaximized() to get real state.

@kasper93
Copy link
Member Author

kasper93 commented Mar 7, 2026

Will merge if there are no more comments.

@na-na-hi
Copy link
Contributor

na-na-hi commented Mar 7, 2026

Setting geometry when only x or y is changed without w or h changing does not work.

Setting geometry wxh without specifying x/y and where w or h is larger than screen size results in window being partly off screen. Window size is eventually confined to screen size but x/y are not.

@kasper93
Copy link
Member Author

kasper93 commented Mar 7, 2026

Setting geometry when only x or y is changed without w or h changing does not work.

Fixed.

Setting geometry wxh without specifying x/y and where w or h is larger than screen size results in window being partly off screen. Window size is eventually confined to screen size but x/y are not.

Would you prefer to contain whole window in working area? Or only top-left corner? What if user moves 90% of window outside of screen? Should we on resize bring it fully in view?

@kasper93 kasper93 force-pushed the fix_fs_opt branch 2 times, most recently from ac6d090 to 86c0744 Compare March 7, 2026 09:01
@kasper93
Copy link
Member Author

kasper93 commented Mar 7, 2026

Setting geometry wxh without specifying x/y and where w or h is larger than screen size results in window being partly off screen. Window size is eventually confined to screen size but x/y are not.

I've added explicit size constrain also for geometry. Let me know what do you think. Previously it was constrained by Windows in this case.

@kasper93
Copy link
Member Author

kasper93 commented Mar 7, 2026

@na-na-hi: have you had a chance to retest this?

Options may be at different state when caller is using it's own cached
copy. This makes opts consistent in usage.
Will be useful to limit the size directly based on platform requirement.
We don't support other ways of fullscreening.

Fixes: mpv-player#16119
It doesn't seem to be neeeded anymore.
Fixes lots of issues with current window resizing and window style
modifications.
@kasper93 kasper93 merged commit fbdaddf into mpv-player:master Mar 13, 2026
28 of 30 checks passed
@kasper93 kasper93 deleted the fix_fs_opt branch March 13, 2026 14:13
@verygoodlee
Copy link
Contributor

Fixes #16132 and #16910 , good job.

@verygoodlee
Copy link
Contributor

The behavior of the --autofit-* options seems to have changed, the percentage size is inconsistent with before.

On Windows 11, Display Resolution: 2560x1440

  • mpv --no-config --idle --force-window --geometry=50%:50% --autofit=50%

    Before: 1280x720 image
    After: 1278x718 image
  • mpv --no-config --idle --force-window --geometry=50%:50% --autofit=75%

    Before: 1920x1080 image
    After: 1916x1077 image

It seems that the border has an impact on the calculation result. If the --border=no option is added, their results will be the same.

@kasper93
Copy link
Member Author

kasper93 commented Mar 13, 2026

It seems that the border has an impact on the calculation result. If the --border=no option is added, their results will be the same.

Yes, it does. And there is good reason for this.

autofit is calculating video area size (client size) based on available space for it. For resolution of 2560x1440, you may have usable area 2560x1380 or 2558x1341 depending if you have border and title bar, both are subtracted of taskbar too. Exact values may differ depending on sizes of system decorations and so on, but the point is, it's smaller.

Now if you do 50% of usable available space it will be smaller than 50% of display resolution and this is what happens. You may say now, why not calculate it from display resolution. Because in this case there are all sort of other issues, first --geometry=50%:50% will not calculate correct center point, it will be offset. This is probably not a big deal, but it all falls apart when we are near the size limit. suddenly our decorations will go out of the screen, because we moved window wrong or window size will be too big and so on.

The easiest to think about this is when you think what happens when --autofit=100%, with window decorations it will not produce 2560x1440, because this is simply not the available area that we work with.

I know that intuitively 50% should give 50% of screen size, but you need to account for borders, taskbars and so on. This makes positioning and sizing consistent across all the decorations option.

If you need exact size, use --autofit=x1080 for example.

tl;dr You are setting window size, not video size.

@verygoodlee
Copy link
Contributor

If you need exact size, use --autofit=x1080 for example.

I personally never set the exact size because it doesn't work well on multi-display.

e.g. If the primary display is 4k and and the non-primary display is 1080p, --autofit-smaller=960 is too small for the primary display, while --autofit-smaller=1920 is too large for the non-primary display, percentage size such as --autofit-smaller=50% is always a better choice for this use case.

the calculation result of percentage size now differs between bordered and borderless window, making it almost impossible to set the desired target video size in bordered window, as there may always be a few pixel difference, for example, 50% is a few pixels smaller, while 51% is a few pixels larger.

@Jules-A
Copy link

Jules-A commented Mar 14, 2026

This make it impossible to go back to windowed maximized state :/
I've been using

geometry=3840x2100+0+0
no-border

for years since borderless windowed with taskbar hasn't really been possible any other way for years (an official way would be nice).
The problem now is if I resize the window for a bit and want to go back to the default size it's no longer possible without resizing manually (which can take a while depending on where the window was). Prior to this PR I was able to just double twice to get back to default state.
Is there another way? I think I can probably set a bind or something?

@kasper93
Copy link
Member Author

kasper93 commented Mar 14, 2026

I personally never set the exact size because it doesn't work well on multi-display.

That's fair. But you have to pick your poison. % is a %, you may not get the exact same numeric values, but it will be exactly the amount you requested.


@Jules-A: I don't understand what you are trying to achieve. Is this what you want?

window-maximized=yes
no-border

@na-na-hi: Do you have opinion of autofit and decorations? This could be fixed, by autofitting to monitor dimensions, instead of working area, but still size constrain to screen. I feel like the current approach is correct, from the math point of view. Because it's consistent scaling across whole 0-100%.

diff --git a/video/out/win_state.c b/video/out/win_state.c
index 3ca22fecf3..fc409cf29f 100644
--- a/video/out/win_state.c
+++ b/video/out/win_state.c
@@ -121,9 +121,9 @@ void vo_calc_window_geometry(struct vo *vo, struct mp_vo_opts *opts,

     calc_monitor_aspect(opts, mon_w, mon_h, &out_geo->monitor_par, &d_w, &d_h);

-    apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit, true, true);
-    apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit_smaller, true, false);
-    apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit_larger, false, true);
+    apply_autofit(&d_w, &d_h, mon_w, mon_h, &opts->autofit, true, true);
+    apply_autofit(&d_w, &d_h, mon_w, mon_h, &opts->autofit_smaller, true, false);
+    apply_autofit(&d_w, &d_h, mon_w, mon_h, &opts->autofit_larger, false, true);
     if (size_constraint)
         apply_autofit(&d_w, &d_h, scr_w, scr_h, size_constraint, false, true);

@Jules-A
Copy link

Jules-A commented Mar 14, 2026

I don't understand what you are trying to achieve. Is this what you want?

It is but it's always been and still is buggy. Most notably I wasn't able to double click twice to re-enter windowed-maximized state (which doesn't matter now that it doesn't work with geometry) and when I go to resize, it's no longer able to be resized to fit the windowed-maximized size because it removes the black bars on the side and keeps assuming fullscreen resolution. Also I can still reproduce #8728 with windows-maximized.

@kasper93
Copy link
Member Author

It is but it's always been and still is buggy. Most notably I wasn't able to double click twice to re-enter windowed-maximized state (which doesn't matter now that it doesn't work with geometry) and when I go to resize, it's no longer able to be resized to fit the windowed-maximized size because it removes the black bars on the side and keeps assuming fullscreen resolution.

Sorry, I don't know what steps you are doing. Could you report issue, with clear 1 2 3 steps to reproduce the unexpected behavior? Once I will be able to reproduce, I can fix that.

@Jules-A
Copy link

Jules-A commented Mar 14, 2026

Sorry, I don't know what steps you are doing. Could you report issue, with clear 1 2 3 steps to reproduce the unexpected behavior? Once I will be able to reproduce, I can fix that.

Hmm... I could have sworn there was an old bug open with it already but I can't find it now, possibly been closed with a partial fix. There's tonne of related issues, I'll have to look better next time when I get more time then create an issue if I can't find it I guess. Some of these related issues you'd likely end up running into what I'm describing while trying to fix them though...

@Jules-A
Copy link

Jules-A commented Mar 15, 2026

This PR also causes MPV opening to now play the Windows 10 opening animation instead of opening instantly which is extremely annoying, was that intentional??? Do you know if there's any way to disable it without having to disable it system-wide? If you're wondering why I don't it's because it causes bugs in many programs like Explorer that causes white flashes.

@Sneakpeakcss
Copy link

There also seems to be an issue with geometry positioning now.

Setting --geometry=0:0 will ignore the border and place the window at pos 8:0. Weirdly enough, the y position is still working and only x has issues. An oversight perhaps? Because i would still expect 0:0 to place the window in the very corner even in border mode.

Works as expected when set at runtime.

@kasper93
Copy link
Member Author

Setting --geometry=0:0 will ignore the border and place the window at pos 8:0. Weirdly enough, the y position is still working and only x has issues. An oversight perhaps? Because i would still expect 0:0 to place the window in the very corner even in border mode.

Weirdly enough this works fine for me on Windows 11 at least. Your description is pretty clear, however. Before we show window, DWM will not give us correct invisible border sizes, so when we move window to 0:0 it is actually not taking into account. I wonder what's the diff that it works differently for you, I can try on Windows 10 later to see.

kasper93 added a commit to kasper93/mpv that referenced this pull request Mar 16, 2026
DWMWA_EXTENDED_FRAME_BOUNDS is not available before window is shown, so
show it off-screen to get correct values.

Fixes: mpv-player#16127 (comment)
kasper93 added a commit to kasper93/mpv that referenced this pull request Mar 16, 2026
DWMWA_EXTENDED_FRAME_BOUNDS is not available before window is shown, so
show it off-screen to get correct values.

Fixes: mpv-player#16127 (comment)
kasper93 added a commit to kasper93/mpv that referenced this pull request Mar 17, 2026
DWMWA_EXTENDED_FRAME_BOUNDS is not available before window is shown, so
show it off-screen to get correct values.

Fixes: mpv-player#16127 (comment)
kasper93 added a commit that referenced this pull request Mar 17, 2026
DWMWA_EXTENDED_FRAME_BOUNDS is not available before window is shown, so
show it off-screen to get correct values.

Fixes: #16127 (comment)
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.

5 participants