| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a property that returns whether the window is focused, currently
only for X11 and Wayland.
My use cause for this is having an equivalent of pause-when-minimize.lua
for tiling window managers: make mpv play only while it's in the current
workspace or is focused (I'm fine with either one but prefer focus).
On X I do this by observing display-names, which is empty when the
rectangles of the display and mpv don't intersect, but on Wayland its
value doesn't change when mpv leaves the current workspace (and the same
check doesn't work since the geometries still intersect).
This could later be made writable as requested in #6252.
Note that on Wayland se shouldn't consider an unactivated window with
keyboard input focused.
The wlroots compositors I tested set activated after changing the
keyboard focus, so if you set wl->focused only in
keyboard_handle_enter() and keyboard_handle_leave() to avoid adding the
"has_keyboard_input" member, focused isn't set to true when first
opening mpv until you focus another window and focus mpv again.
Conversely, if that order can't be assumed for all compositors, we
should toggle wl->focused when necessary in keyboard_handle_enter() and
keyboard_handle_leave() as well as in handle_toplevel_config().
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Oversight in b0f0be7. The user_sbc value would update but not last_sbc
if no presentation events were received. This would result in an
incorrect sbc_passed value (in practice, this should always be 1 since,
as far I know, all wayland compositors are currently only capable of
double buffering). When bring the window back into view, it would result
in a single frame of very high vsync jitter. Although in most cases it
was imperceptible, rarely I was able to completely break playback (i.e.
constant mistimed/dropped frames). Fix this by simply incrementing
last_sbc by 1 if the window is hidden. The buffer swap call did still
occur. The user just didn't see it.
|
|
|
|
|
|
|
|
|
|
|
| |
Why on earth did I ever bother with this dumb crap? If we do not have
any presentation statistics, just set the relevant vo_sync_info values
to -1 to disable it. It's much simpler than using mp deltas and trying
to keep up with mpv's clock. This also appears to fix audio/video
desynchronization if you start a video with the pause flag, move it out
of view, and then unpause it. Technically harmless since the video
wasn't even in view and putting back in view recovered it, but a quieter
terminal is better.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The original goal was to simplify all this logic to make it less fragile
and breaky. Unfortunately, that didn't exactly happen and things might
actually be more complicated in some ways (well in other ways it's
simplier). There's a lot of negotiation back and forth between the
client and the compositor regarding sizes. The client (aka mpv) can do a
resize on its own. But also the compositor can request its own resize
(which we should be nice and listen to of course). The older method had
a lot of breakfalls/edgecases that were gradually patched up as time
went on, but that approach is really fragile. This refactor should,
hopefully, be on a more solid foundation.
Don't call any of the xdg toplevel state changing functions
(fullscreen, maximized, etc.) directly. Use the toggle wrapper
functions. These signal that the state was changed which is later
handled in the toplevel listener.
Introduce a new vdparams variable that stores the actual dimensions of
the video. This does create some new (but neccesary) complexity.
wl->vdparams stores what the actual dimensions of the video are
(according to mpv). wl->window_size stores the last size of the window
(so it includes any manual resizes for instance). wl->geometry is the
actual size of the output that gets displayed on the screen.
|
|
|
|
| |
Fixes #8014.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We've had some serious issues with GNOME in the past, but since then
their compositor has undergone some major internal improvements. The
most severe one [1], random vsync spikes and mistimed frames, can no
longer be reproduced by the original author of the issue. There are some
minor UI-related things (lack of window decorations for instance since
there is no xdg-decoration support), but users don't seem to complain
about that too much and they aren't revelant to playback.
3.38 isn't out quite yet, but that should also fix playback issues when
on a multimonitor setup (the fix is in the master branch at the moment).
In terms of playback, the only real concerning issue is the lack of idle
inhibit so a warning is still displayed. But GNOME has their own
workaround that users can use for that so if anyone happens to complain,
we can just point them to that.
[1] https://gitlab.gnome.org/GNOME/mutter/-/issues/957
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When using presentation time, we have to be sure to update the ust when
no presentation events are received to make sure playback is still
smooth and in sync. Part of the recent presentation time refactor was to
use the presentation discarded event to signal that the window is
hidden. Evidently, this doesn't work the same everywhere for whatever
reason (drivers?? hardware??) and at least one user experienced issues
with playback getting out of sync since (presumably) the discarded event
didn't occur when hiding the window. Instead, let's just go back to the
old way of checking if the last_ust is equal to the ust value of the
last member in the wayland sync queue. Fixes #8010.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The motivation for this change was a segfault caused by e107342 which
has complicated reasons for occuring (i.e. I'm not 100% sure but I think
it is a really weird race). The major part of this commit is moving the
initialization of presentation listener to the frame_callback function.
Calling it in swap_buffers worked fine but in practice it meant a lot of
meaningless function calls if a window was hidden (the presentation
would just be immediately discarded). By calling it in frame_callback,
we ensure the listener is only created when it is possible to receive a
presentation event.
Of course calling the presentation listener in feedback_presented or
feedback_discarded was considered, but ultimately these events are too
slow. Receiving the ust/msc/sbc triplet here and then passing it to mpv
results in higher vsync judder since there is (likely) not enough time
before the next pageflip. By design, the frame callback is meant to give
us as much time as possible before the next repaint so calling it here
is probably optimal.
Additionally, we can make better use of the feedback_discarded event.
The wp_presentation_feedback should not be destroyed here. It will be
taken care of either when we get feedback again or when the player
quits. Instead what we can do is set a bool that tells wayland_sync_swap
to update itself based on mp_time delta. In practice, the result is not
any different than before, but it should be more understandable what is
going on now.
Of course, the segfault mentioned at the beginning is fixed with this as
well.
|
|
|
|
|
|
|
| |
Nothing major but it's technically possible for the
wp_presentation_feedback struct to still be allocated when quitting the
player. Just destroy it if it exists like all of the other wayland
objects.
|
|
|
|
|
|
|
| |
In a playlist of videos with different sizes, going to the next video
would not properly resize the window. This actually broke way back in
7170910 (oops), but somehow nobody ever complained. The fix is simple.
If a window isn't maximized, be sure to set the window geometry again.
|
|
|
|
|
| |
This is extremely similar to x11's WM_CLASS. This commit allows users to
set mpv's app-id at runtime for any of the wayland backends.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Just some small changes when creating the xdg_surface. Don't set the
toplevel title (or app id) in create_xdg_surface anymore because it's
entirely pointless. Also make it possible for create_xdg_surface to
return something other than 0 so the error checking is somewhat
meaningful. It's not really clear if these xdg functions can even fail
in the first place (perhaps some weird proxy marshalling crap could
possibly go wrong somehow), but it can't hurt. Note that all app id
stuff has been removed (temporarily) in this commit. See the next commit
which adds it back in.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Sway 1.5 started sending more pointer motion events to mpv which broke
the autohiding behavior. The cursor would appear again if you
fullscreened. Sway had a good reason to do this because certain
applications had inconsistencies between hardware cursor and software
cursor without rebasing on state changes[1]. So mpv needs to take this
special case into consideration.
Initially, simply checking mouse coordinates for changes was considered,
but this doesn't work. All coordinates are surface-local in wayland so
something can appear to move in the local coordinate space but not
globally. You're not allowed to know global mouse coordinates in
wayland, and we don't care about local coordinate changes in mpv so this
approach isn't viable.
Instead, let's just keep track of a local state change. If the toplevel
surface changes in some way (fullscreen, maximized, etc.), then just set
a bool that lets us ignore the mp_input_set_mouse_pos function. This
keeps the cursor from appearing simply because the state was changed
(i.e. fullscreening). For compositors that don't send pointer motion
events on a state change, this does technically mean that the initial
mp_input_set_mouse_pos is never set. In practice, this isn't a
noticeable difference though because moving a mouse generates a ton of
motion events so you'll immediately see it on the second motion event.
[1] https://github.com/swaywm/sway/issues/5594
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
wl_display_dispatch is dangerous because it will block forever if the
event queue is empty. Any direct calls to this function should just be
replaced with wl_display_dispatch_pending which accomplishes the same
thing for mpv's purposes without any chance of blocking.
The other potential trap is wl_display_roundtrip. It can internally call
wl_display_dispatch which in certain circumstances could potentially
block. There are cases where we need the server to finish processing
client requests before doing anything else so this can not be cleanly
avoided. The dangerous call is the usage of wl_display_roundtrip in
vo_wayland_wait_frame. In the majority of cases, this shouldn't be a
problem because the previous wl_display_read_events should always queue
up some events on the fd for wl_display_roundtrip to send. However, the
compositor could potentially send us an error in the display queue that
could lead to bad behavior when wl_display_roundtrip is called.
The wl_display_roundtrip can't be removed because we are relying on its
semi-blocking capabilities, but the logic can be slightly adjusted to be
safer. The obvious thing to do is to make sure we check the pollfd for
any errors. If one is returned, then we call wl_display_cancel_read and
try again. The less obvious trick is to call wl_display_dispatch_pending
and move wl_display_roundtrip outside of the blocking + timeout loop.
This change has some subtle but important differences. Previously,
vo_wayland_wait_frame would read an event and wait on the server to
process it one-by-one. With this change, the events are dispatched as
soon as possible to the server and then we wait on all of those
(potentially multiple) events to be processed after we have either
received frame callback or the loop times out.
After that is done, we can then check for if there are any errors on the
display. If it's all clear, we can run wl_display_roundtrip without any
worries. If some error happens, then don't execute the function at all.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously, the compositor was signaled that a drag-and-drop ended with
wl_data_offer_finish in check_dnd_fd. This is, however, erroneous
because it is outside of the data_device_listener and in some cases
caused errors with certain compositors. check_dnd_fd itself does not
need to know or care about anything that happens in wayland. It just
needs to read data from an fd. The simple fix is to just always signal
the end of a drag-and-drop in data_device_handle_drop. check_dnd_fd can
free memory and close the fd later, but it should not talk to the
compositor. Fixes #7954.
|
|
|
|
|
|
|
| |
The read of the wayland display fd in vo_wayland_wait_events was
incorrect and technically vulnerable to race conditions. The correct
usage as per the client api is to use wl_display_prepare_read as well as
wl_display_read_events.
|
|
|
|
|
|
| |
Broken by previous commit. I've split a commit incorrectly.
Fixes: #7802
|
|
|
|
| |
Force them into a more consistent naming schema.
|
|
|
|
|
|
|
| |
Trying to use anything other than CLOCK_MONOTONIC here would be a
disaster. No idea if it's even possible for the clockid here to be
something other than CLOCK_MONOTONIC in this function but it's better
safe than sorry. Closes #7740.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the wayland code, the left mouse click is treated a bit differently.
Dragging the left click allows mpv to request a window move to the
compositor. In some cases, this can also request a window resize if the
osc-windowcontrols are enabled. These functions had the strange side
effect of messing up mpv's deadzone (it seemed to disappear completely).
A harmless enough workaround is to just explictly send an UP event for
left click after the move/resize functions are finished executing. The
xdg_toplevel move and resize functions both finish after the button
press is let go, so we are guarenteed to have the left click in the UP
state here. Sending this event probably unconfuses some calculation
somewhere thus fixing the deadzone bug. It feels a little silly, but
it's safe and works. Fixes #7651.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
One not-so-nice hack in the wayland code is the assumption of when a
window is hidden (out of view from the compositor) and an arbitrary
delay for enabling/disabling the usage of presentation time. Since you
do not receive any presentation feedback when a window is hidden on
wayland (a feature or misfeature depending on who you ask), the ust is
updated based on the refresh_nsec statistic gathered from the previous
feedback event.
The flaw with this is that refresh_nsec basically just reports back the
display's refresh rate (1 / refresh_rate * 10^9). It doesn't tell you
how long the vsync interval really was. So as a video is left playing
out of view, the wl->last_queue_display_time becomes increasingly
inaccurate. This led to a vsync spike when bringing the mpv window back
into sight after it was hidden for a period of time. The hack for
working around this is to just wait a while before enabling presentation
time again. The discrepancy between the "bogus"
wl->last_queue_display_time and the actual value you get from the
feedback only happens initially after a switch. If you just discard
those values, you avoid the dramatic vsync spike.
It turns out that there's a smarter way to do this. Just use mp_time_us
deltas. The whole reason for these hacks is because
wl->last_queue_display_time wasn't close enough to how long it would
take for a frame to actually display if it wasn't hidden. Instead, mpv's
internal timer can be used, and the difference between wayland_sync_swap
calls is a close enough proxy for the vsync interval (certainly better
than using the monitor's refresh rate). This avoids the entire conundrum
of massive vsync spikes when bringing the player back into view, and it
means we can get rid of extra crap like wl->hidden.
|
|
|
|
|
| |
Based on an idea by sfan5. Remove abs usage, and instead just
check for negative value, and set variable to either +/-1.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Change all OPT_* macros such that they don't define the entire m_option
initializer, and instead expand only to a part of it, which sets certain
fields. This requires changing almost every option declaration, because
they all use these macros. A declaration now always starts with
{"name", ...
followed by designated initializers only (possibly wrapped in macros).
The OPT_* macros now initialize the .offset and .type fields only,
sometimes also .priv and others.
I think this change makes the option macros less tricky. The old code
had to stuff everything into macro arguments (and attempted to allow
setting arbitrary fields by letting the user pass designated
initializers in the vararg parts). Some of this was made messy due to
C99 and C11 not allowing 0-sized varargs with ',' removal. It's also
possible that this change is pointless, other than cosmetic preferences.
Not too happy about some things. For example, the OPT_CHOICE()
indentation I applied looks a bit ugly.
Much of this change was done with regex search&replace, but some places
required manual editing. In particular, code in "obscure" areas (which I
didn't include in compilation) might be broken now.
In wayland_common.c the author of some option declarations confused the
flags parameter with the default value (though the default value was
also properly set below). I fixed this with this change.
|
|
|
|
|
|
|
|
| |
Previously, the vo wasn't always informed if something about the output
changed during playback. For instance, changing a display's refresh rate
during playback would not update mpv's display fps. Fix this by simply
using VO_EVENT_WIN_STATE in output_handle_done which executes whenever
something about the output is changed.
|
|
|
|
|
|
|
|
|
| |
Previously if the --fs-screen option was set, it would only use the
screen if mpv was launched with --fs and only on startup. During
runtime, the toggle would ignore it. Rework the logic here so that mpv's
fullscreen always uses --fs-screen if it is set. Additionally, cleanup
some unneeded cruft in vo_wayland_reconfig and make find_output more
useful.
|
|
|
|
|
|
|
|
|
| |
Resizing the window while preserving the aspect ratio actually kind of
sucked. The window size could make big dramatic changes which was pretty
unintuitive with respect to where the mouse was actually located.
Instead, let's just do some math to ensure that the window size is
always contained inside the width/height reported by
handle_toplevel_config while preserving the aspect ratio. Fixes #7426.
|
|
|
|
|
|
| |
Fixes #7441. Just set screenrc to be equal to current_output's geometry.
Also remove some pointless/extra variables and print a warning/fallback
to screen 0 if a bad id is passed to --fs-screen.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Wayland uses vo_wayland_wait_frame plus some polling with a timeout for
blocking on vsync. Here are a couple of changes that seem to be
improvements. First, the poll time is always rounded up instead of
truncated. When rendering frames longer than the standard 16.666 ms
timeout, it seems that truncating the poll time slightly early may cause
some vsync jitter spikes. Waiting longer, even if it's too long, appears
to behave better.
The second change is to use wl_display_roundtrip instead of
wl_display_dispatch_pending. wl_display_dispatch_pending dispatches all
events immediately. This is good to avoid blocking, but it's not
guaranteed to wait long enough for all events to be processed on the
display fd. The preceding wl_display_read_events routine ensures that
all events on the display fd are queued. We just need a semi-blocking
routine to dispatch them for the most reliable vsync.
wl_display_roundtrip will dispatch any events for us, but also wait for
a reply from the display server. This makes it ideal for this role. If
the compositor doesn't reply to the client something else is probably
horribly broken and wrong anyway. It's also not a permanently blocking
call like wl_display_dispatch. If there's no frame callback (i.e. the
window is hidden), then it does not dispatch any events and returns
immediately.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There were a couple of erroneous things in the handle_toplevel_config
function. Firstly, looping through the different states was not handled
correctly. Launching a window as maximized (can happen in sway for
example) was always stuck on true and would never be set to false. Fix
this by always checking if XDG_TOPLEVEL_STATE_MAXIMIZED is found or not.
Also do a similar thing for the fullscreen state.
Additionally, there were some issues with resizing windows and
window-scale going back to old sizes. The root of this problem is that
the width and height arguments of handle_toplevel_config aren't actually
guarenteed to be the actual width and height of the surface. There are
times when mpv will set the surface size on its own (like with
window-scale) which will be unknown to the toplevel listener. To
complicate matters, there are times when we do want to use the width and
height arguments (like when resizing with the mouse).
Fix this by checking if the width and height arguments reported by
handle_toplevel_config changed from the previous call of the function.
If the value is different, then we go ahead and use them when setting
mpv's geometry. If not, then we just ignore it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This originally existed as a hack for weston. In certain scenarios, a
frame taking too long to render would cause vo_wayland_wait_frame to
timeout which would result in a ton of dropped frames. The naive
solution was to just to add a slight delay to the time value. If a
frame took too long, it would likely to fall under the timeout value and
all was well. This was exposed to the user since the default delay
(1000) was completely arbitrary.
However with presentation time, this doesn't appear to be neccesary.
Fresh frames that take longer than the display's refresh rate (16.666 ms
in most cases) behave well in Weston. In the other two main compositors
without presentation time (GNOME and Plasma), they also do not
experience any ill effects. It's better not to overcomplicate things, so
this "feature" can be removed now.
|
|
|
|
|
|
|
| |
Allow the --window-maximized and --window-minimized flags to actually
work when the player is started on wayland. If the compositor doesn't
support maximization or minimization, then these options just do
nothing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fixes #7345
There was a multitude of issues with cursor handling in wayland and
behavior seemed to vary for strange reasons across compositors and also
bad things were being done in wayland_common. The problem is complicated
and involved fullscreen states being set incorrectly under certain
instances and so on. The best solution is to just remove most of the
extra cruft. In handle_toplevel_config, instead of automatically
assuming is_fullscreen and is_maximized are false, we should use
whatever value is currently set vo_opts which matters when we initially
launch the window.
|
|
|
|
|
|
|
|
|
|
|
| |
This shouldn't really matter, but it's probably best to avoid.
vo_wayland_control would execute set_cursor_visibility while wl->pointer
existed but it didn't check if wl->pointer_id existed. So
wl_pointer_set_cursor would be set to a null surface with an id of 0.
Instead, just wait until we have an actual, non-zero pointer id so that
the cursor is set with the correct, actual id and not a fictious 0 id.
This ensures that the pointer isn't set until it enters the wl_surface
which is what we want.
|
|
|
|
|
| |
More than one option may change at the same time so don't break out of
this loop.
|
|
|
|
|
|
|
|
|
| |
It turns out that gnome wayland still has very serious issues that make
it unusable for playback with mpv. Other compositors mostly behave fine
(Plasma is just missing feature but it's not seriously broken), so GNOME
gets the special honor of having a warning printed out. The only
solution for GNOME users at this time of writing is to either use the
Xorg session or use another wayland compositor.
|
|
|
|
|
| |
This is needed and used only for VOCTRL_GET_FULLSCREEN, which the
wayland code got rid of.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The wayland backend needs to keep track of whether or not a window is
hidden for presentation time. There is no presentation feedback when a
window is hidden which means we shouldn't be sending information to the
vo_sync_info structure (i.e. just leave it all at -1). This seemed to
work fine, but recent changes to presentation time in one notable
compositor (Sway; it was probably always broken in Weston actually)
changed the presentation time behavior.
For reasons that aren't clear, there is a greater than 16.666ms delay
between the first presentation time event and the second presentation
time event (compositor latency?) when you switch back to an mpv window
after it is hidden for long eno |