mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
28.58k stars 2.92k forks source link

Rethink window resizing semantics #7204

Open ghost opened 4 years ago

ghost commented 4 years ago

mpv has the current semantics wrt. resizing the window:

This is pretty complex. The x11 backend implements it this way. I don't know if it's correct on the win32/wayland/swift backends. There's no shared code for that (always planned to, but the interactions with the native APIs are too complex I guess).

The situation changes further with making --geometry runtime queryable/settable. The https://github.com/mpv-player/mpv/tree/x11_geo branch makes the x11 backend set --geometry to the current window size at any time. This means the above semantics are broken, and the second video will not resize the window (so the video is upscaled or downscaled, maybe even letterboxed with black bars around it).

Things peripherally related to it: also I'm questioning that the initial window is placed by the OS window manager, instead of just centering it. Likewise, maybe it should auto-fit it by default if the video is larger than the available desktop space. You could claim that these things should be handled by the WM, but if they're not, why not override them.

Any opinions how this should work?

ghost commented 4 years ago

CC @rossy @Akemi @Dudemanguy @philipl and all users/developers

avih commented 4 years ago

Maybe there could be an option --window-sizing which would could take values like:

The auto mode (and possibly manual too) might need to remember only the width rather than width+height, or else there would be black bars if the aspect changes with the next video/image - which I think is undesirable behavior.

ghost commented 4 years ago

More options to choose the behavior => more complexity. (Now you have to implement all the variants, on every VO.)

occivink commented 4 years ago

I personally don't see the point of resizing the window to match the resolution of the content, mpv already up/down-scales properly, and you only rarely care about pixel-perfect reproduction. Maybe to avoid black bars, but I find them less invasive than the constant size changes. It could be useful to allow scripts to change the window size, to be able to implement these features as user configuration.

ghost commented 4 years ago

Regarding geometry-as-property, I could side-step its problem by writing the actual window bounds into a separate "geometry-current" property. A slightly annoying consequence is that the "geometry" property still needs to change in order to apply it. (Consider a script wants to regularly move a window to position (50,50) even if the user moves the window. Then it'd need to first set a value other than "50:50", and then "50:50", because redundant sets with the same value as now ignored.)

DanOscarsson commented 4 years ago

A quick test with vlc, kodi and mpv on my system (linux/gnome/opensuse) playing several videos. vlc resizes window keeping its upper left corner fixed. kodi retains window size and scales video to fit. mpv resizes window keeping center position fixed. The way kodi does it is the least annoying for me. This way the window do not change size or position so it does not disrupt what I am doing on the desktop in other windows.

ghost commented 4 years ago

I've never seen vlc doing anything sane when the video size changes, I think they don't care about this case. But I doubt mpv's behavior is perfect in all cases either. kodi is just designed to be run at fullscreen, so they won't bother with resizing the window.

ghost commented 4 years ago

PS: you can get the static window size behavior with --geometry by simply setting a width and height.

ghost commented 4 years ago

While we're at it, does anyone have nice ideas for better --geometry syntax? Should be compatible. It's ok if the new syntax can't do all the fancy stuff, since I'll keep the old syntax.

Dudemanguy commented 4 years ago

I personally mostly like how it is right now to be honest. I guess the only thing I'd change is that I don't think resizing the next video in a playlist needs to be complicated. I'd just have two options: resize to the video resolution or don't resize.

P.S. Wayland's behavior is the same as X11.

ghost commented 4 years ago

When the wayland backend was initially added, there were a few extra review rounds to get this right.

Anyway, the thing with making the "geometry" a property (that directly reflects the window state) is that it'll keep the window size:

aerobounce commented 4 years ago

I've never tried mpv on OS other than macOS, but, I've had used lots of video players and, this is just a personal thought — but mpv handles window things the best. Sometimes window exceeds a screen when a video resolution is large and that's kinda weird, but you can just suppress that with autofit-larger=50%x50% like that.

I wanted something like Picture in Picture alike feature, that:

I thought this is impossible in current version, but Akemi introduced me very script that does that: https://gist.github.com/TheAMM/5e07ad787dd95d76131b61840f403a79

I mean mpv's quite flexible and can deliver what you want today. If something is impossible with vanilla config, you can cover that with scripting. How nice? "No problem", just an opinion from a macOS user.

For geometry syntax, I agree that better syntax would be nice. However imagemagick is also like that or even more complex. So I wouldn't think mpv's syntax is bad.

One idea is like geometry=w=25%h=25%x=100%y=0% or geometry=w=25%:h=25%:x=100px:y=100px Or another: geometry-w=25% geometry-h=25% geometry-x=100px geometry-y=100px

The latter is clear what it is doing, but obviously needs more new implementations. I'm not sure how complex it would be though...

ghost commented 4 years ago

Generally making the window size static if the user resizes it might be a good idea, but probably hard to implement. (Not sure, at least every backend would have to do it, unless we finally add something that tries to share the code for this behavior.)

Sometimes window exceeds a screen when a video resolution is large and that's kinda weird, but you can just suppress that with autofit-larger=50%x50% like that.

Something like that should probably be default.

I thought this is impossible in current version, but Akemi introduced me very script that does that: https://gist.github.com/TheAMM/5e07ad787dd95d76131b61840f403a79

This shouldn't work, because currently nothing reacts to runtime changes to this option.

One idea is like geometry=w=25%h=25%x=100%y=0% or geometry=w=25%:h=25%:x=100px:y=100px

Yeah, possibly. Something into this direction.

Akemi commented 4 years ago

Sometimes window exceeds a screen when a video resolution is large

that's a behaviour from the old cocoa code and i personally like it like that. i always though the autofit option is exactly there for that case.

This shouldn't work, because currently nothing reacts to runtime changes to this option.

it doesn't need to be runtime changeable just when the next file in the playlist is started, eg it will calculate the screen size again in that case. same thing when setting geometry and truning the video off and on again.

Samillion commented 4 years ago

vlc resizes window keeping its upper left corner fixed.

This would honestly be great. On dual screens, an aspect ratio change would move the window slightly to the second screen if the geometry is set to the edge of the first screen.

mpv-dual-screen

Also, before I noticed this post, I created #7265 which is about maximized window behavior on aspect ratio change.

As a user, it would definitely be great to have the window resizing behavior improved a bit.

aerobounce commented 4 years ago

In the case some new consistent behavior of window is needed in the end, how about making a script for that and include it as a default script? In that way, you can easily share actions through platforms.\ Additionally this approach can be applied to all the other implementation of mpv that must be implemented for all the platforms supported, I guess. (Of course not for platform depending impl like renderings, though)

Rather than implementing features in each platform's language, implementing what scripting is capable of in each platforms might be lighter work.

Just popped into my head today. Just an idea. Although only for things what scripting is capable of, though.

ghost commented 4 years ago

A script is unsuitable for this because it can't do that without race conditions. Also I already said:

There's no shared code for that (always planned to, but the interactions with the native APIs are too complex I guess).

ailispaw commented 3 years ago

I made another script based on @Akemi 's. It works for me.

local msg = require 'mp.msg'

function on_width_change(name, osd_w)
    if osd_w ~= nil then
        osd_h = mp.get_property_number("osd-dimensions/h")
        local geometry = ("%dx%d"):format(osd_w, osd_h)
        msg.debug("OSD resized: " .. geometry .. ", setting geometry property")
        mp.set_property_native("geometry", geometry)
    end
end
mp.observe_property("osd-dimensions/w", "number", on_width_change)
haasn commented 3 years ago

Old issue, but some food for thought:

Resizing the window is only tangentially related to the goal of black bar prevention. For that task it would be sufficient to merely adjust the aspect ratio of the window, while preserving the window size.

So in the interest of keeping things simple and predictable, here's what I would do:

  1. If --keepaspect-window is enabled, then the aspect ratio of the window will be updated to the aspect ratio of the new file, on file switches. (If the old resolution and the new resolution are identical, this is already a no-op, so there's no need for the confusing file-change semantics)
  2. If --keepaspect-window is disabled, then mpv will not touch the window size on file changes.

In terms of the aspect ratio resizing, the goal should be to preserve the area of the window. That invariant will also ensure it correctly round-trips and stuff.

So for example, if the current file is 16:9 and the user has manually resized the window to 1000x562, and the new file is 4:3, the new window size would be 866 x 649.