This commit adds a DND_INSERT_NEXT action option for drag-and-drop,
allows for selecting it through the --drag-and-drop=insert-next option,
and adds the necessary plumbing to make that happen when something is
dragged onto the player.
Wayland was the only backend that attempted this, but it can be done in
a centralized place for anything that supports this. hidpi-window-scale
is just the same as a normal window scale but with the OS DPI as the
factor.
It's only necessary to check the existance of cursor_shape_manager.
Also drop the pointer check to handle multi-seat since a removed seat
sets the cursor_seat to NULL.
For VOCTRL_SET_CURSOR_VISIBILITY, set cursors visibility for all seats.
The return is VO_NOTAVAIL is none of the seats have cursor, and
VO_FALSE if setting visibility failed for at least one seat.
The cursor_shape_device is per pointer, which is per seat. Handle it
together with other seat objects. This in turn also handles cursor
visibility per seat.
On a multi-seat setup, wl_registry_global advertises wl_seat multiple times,
one for each seat. if wl->seat is already set, the previous value will be
overwritten, preventing it from being freed.
Additionally, if the latter seat doesn't have the capabilities of the
former seat, the keyboard/pointer/touch input devices will be destroyed
because the current wl_seat_capabilities doesn't distinguish between
different seats. This casues keyboard/pointer/touch not working if the
latter seat has no such capabilities.
Fix this by implementing multi-seat support.
This allows receiving inputs from all devices on all seats.
All seat-specific objects (wl_keyboard/pointer/touch, wl_data_device)
are grouped with their respective seats so they can be managed together.
Note that currently inputs from all seats are interleaved with each other
and modify the same global input states.
Since 1f8013ff3f, if you release a modifier before a regular key on
Wayland, that key gets immediately pressed again because
keyboard_handle_modifiers() calls mp_input_put_key() regardless of
whether a modifier is pressed or released, e.g. if you press Ctrl+s it
easy to take an another screenshot with s by accident. Fix this by
releasing keys when releasing modifiers.
Ideally, releasing the modifier should input the key alone after
--input-ar-delay, while this patch disables it forever, e.g. on X11 if
you type something in the console, hold Ctrl+h, and release Ctrl, it
starts typing h instead of deleting characters. This doesn't work
because keyboard_handle_key() is only called when you first press a key,
while on X11 KeyPress keeps getting sent as you hold down the key. But
this difference in behavior between X11 and Wayland can also be
reproduced with GTK and Qt applications, so I guess this is acceptable.
When the mpv surface leaves the output, we no longer mark it as the
current output. However, this implicitly depends on there being a
preceding surface entrance event to a different output. This is not
necessarily the case. Consider moving the window from monitor 1, to
monitor 1-2, and then back to 1 again. mpv gets the entrance event to
monitor 2 and sets that as the current output to work off of. Then when
you move back to only monitor 1, it removes monitor 2 from the current
output. However, monitor 1 is not updated again as the current output
because there is not a new surface entrance event in this case (the
window never left). So the numbers that mpv's core is using are
incorrect and for the wrong monitor. Luckily, we already keep track of
what outputs the mpv surface is currently on no matter how many there
are so it is simply a matter of setting current output again in the
leave event if we have a different output that has the mpv surface.
Ref: https://github.com/swaywm/sway/issues/7932
Since the scroll event handler is moved to wl_pointer_frame, version 5 of
wl_seat is required. Warn that scrolling is broken if the compositor
doesn't support that verison.
Commit f54ad8eb05 broke high resolution
scrolling because one logical mouse click is generated for every scroll
event, no matter the magnitude. This makes scrolling on trackpad way
too fast.
Revert the axis scaling change in that commit and clamp the resulting
value between -1 and 1 to make sure mouse wheel scrolling works as
intended on compositors which send a value larger than 10 for these events.
Previously, all scaling was forced to 1 with this vo and all coordinates
were calculated as if the scale was 1. This works since viewport relies
on the compositor completely for scaling so it doesn't really matter if
we don't draw directly to the correct size since the compositor will
just scale the rest for us. This does have some downsides however since
the OSD text might not be drawn at the actual resolution of the final
size of the video.
We can instead handle this by getting rid of the dmabuf_wayland specific
scaling logic and using the same values as everything else. In the
resize in vo_dmabuf_wayland, we just need to adjust the viewport
destination calls so they go to the wayland local coordinates and not
the physical ones. This should ensure that vo_dmabuf_wayland directly
goes to the desired size and the compositor doesn't need to operate on
it after the fact.
If the scaling value changed for some reason, the window geometry would
be recalculated with the new scaling even if this option was disabled.
Properly ignore it.
The core wayland protocol way of handling scaling is to use the
buffer_scale mechanism. But this sucks in several ways for reasons I
won't list here and fractional scaling rightly avoids this altogether
and uses a buffer_scale of 1 (i.e. not setting it) along with
viewporter. When originally implemented, this was only specifically used
when the fractional scale protocol was available, but we actually can
use it as a full replacement instead. This means that mpv now hard
requires viewporter, but this protocol is supported by everyone and is
one of the few that is actually stable.
How it works is the same regardless of fractional scaling or not. When
the compositor has a scale value not equal to 1, it will always scale
the client by that factor (unless you set buffer_scale). What we do here
is pass a viewporter size that exactly undos the compositor-side scale
(sans a possible rounding error). So what we are left with is just the
exactly physical pixels we want to display. Fixes#13316.
Negative values are nonsense to mpv, and can cause protocol error afterwards,
like xdg_surface::set_window_geometry which doesn't accept negative values.
Treat any negative values as zero (client determines size) for now.
According to the xkbcommon docs, `xkb_state_mod_index_is_consumed` is
true when a modifier *may affect* key translation. A key modifier may
be consumed but not be active. See xkb documentation for this function
for further details. This breaks key modifiers in cases where
L_Shift+R_Shift for example is used to change keyboard layout with
`xkb_options grp:shifts_toggle`. Instead, replace it with a simple
check for a valid modifier.
XF86Back and XF86Forward are mostly used to navigate file and web browsers
to go back/forward in history. XF86Forward isn't recognized right now,
so add it.
Because XF86AudioForward already takes the "FORWARD" name, rename the
browse keys to GO_BACK and GO_FORWARD instead.
In the past, this worked by accident because the initial startup was
racy and sometimes the initial firing of handle_toplevel_config would
happen after reconfig. Since we now properly wait on all compositor
events we can save the initial size hint that is given to us and try to
use that as the window-size/geometry provided the --autofit/geometry
options aren't explictly set. Fixes#11134.
Fixes a899e14b which changed clamp from 0 to 1 ms which effectivelly
introduced 1ms sleep always, even if requested until_time_ns is in the
past and should request 0 timeout.
While at it also fix mp_poll wrapper to respect negative timeout which
should mean infinite wait.
Also keep the 37d6604 behaviour for very short timeouts, but round only
the ones > 100us, anything else is 0.
Fixes: a899e14b
There's some geometry-related things that mpv has to calculate before
the window is actually mapped onto the screen in wayland. But there's no
way to know which output the window will end up on before it happens, so
it's possible to calculate it using the wrong values. mpv corrects
itself later when the surface event happens, but making the initial
guess work better can help in certain cases.
find_output is the only thing that needs to be changed here. Its main
purpose is to grab the right output based on user settings when we're
trying to full screen and giving a fallback in case we don't have
wl->current_output yet. The x11 code already does something similar, so
we're basically just copying it. Allow user settings like --screen and
--screen-name to influence the initial wl_output guess. Those options
won't actually place the window on that specific screen since we can't
do that in wayland, but if the user knows where the window will end up
beforehand it makes sense to listen to the arguments they pass. If
something goes wrong, then we just fallback to 0 like before.
When this was originally written, the queuing/list approach was
deliberately removed since it adds more complication and xorg/wayland
don't really use it anyway. In practice, you only really have one frame
in flight with presentation timestamps. However, one slight annoyance is
that the drm code has its own thing which is almost exactly the same and
does its own calculations. Ideally, we'd port drm to this instead, but
the implementation there takes into account N-frames in flight which
probably does actually work. So we need to make present_sync smarter and
be able to handle this.
mpv does actually have its own linked list implementation already which
is a good fit for this. mp_present becomes the list and each
mp_present_entry has its own set of timestamps. During initialization,
we create all the entries we need and then simply treat it like a queue
during the lifecycle of the VO. When an entry is fully used
(present_sync_get_info), then we remove it from the list, zero it out,
and append it to the end for future use. This avoids needing to allocate
memory on every frame (which is what drm currently does) and allows for
a reasonable number of in flight frames at the same time as this should
never grow to some obscene number. The nice thing is that current users
of present_sync don't need to change anything besides the initialization
step.
In many cases, this is purely cosmetic because poll still only accepts
microseconds. There's still a gain here however since
pthread_cond_timedwait can take a realtime ts now.
Additionally, 37d6604d70 changed the value
added to timeout_ms in X11 and Wayland to ensure that it would never be
0 and rounded up. This was both incomplete, several other parts of the
player have this same problem like drm, and not really needed. Instead
the MPCLAMP is just adjusted to have a min of 1.
e125da2096 changed the z order of the
surfaces a bit, but it turns out this has a side effect. If the aspect
ratio of the actual video doesn't match your display, the osd surface
doesn't scale properly and gets clipped. Put the z ordering back where
it used to be. Instead when we have the force window case, simply attach
the already existing solid buffer to the video surface. This allows the
osd surface to actually draw over it instead of always being obscured so
it satisfies the case of not having any real video frames but still
wanting to draw the osd. Also don't mess with any of the viewport source
setting stuff with force window. Weston complains about it, and it's
nonsensical anyway. Fixes#12547.
Calling wl_display_disconnect closes the file descriptor, no need to
manually do it ourselves beforehand which causes a double close on the
fd.
Signed-off-by: Jack Mitchell <jack.mitchell@tuxable.co.uk>
With the addition of fractional scaling support, wl->scaling was
converted to a double. Some compositors (Plasma) can report values under
1 for fractional scaling, so this meant wl->scaling could be some
small fractional value. This is fine except that when using the legacy
code for drawing the mouse cursor (i.e. not the cursor-shape protocol),
it still uses the old integer scaling method in core wayland. The reason
for this is simply because fractionally scaling the mouse cursor surface
is nonsense and nobody even has cursor images for anything besides a
select few sizes anyways (32x32, 48x48, etc.). The existing integer
scaling sort of works but it's pretty bad too and you can get some weird
sizes anyway. This is why cursor-shape is preferred since it fixes this.
Anyways, since buffer scaling for the cursor only takes integers, there
could be truncation to 0 in the previously mentioned fractional scale
this. This naturally causes the compositor to send us an error and mpv
quits. The fix is to always make sure that the scale value used for the
cursor is at least 1. Anything less makes no sense. Fixes#12309.
The osd support was originally written with the requirement that we have
actual frames getting delivered to the VO. This isn't always the case
though. If you force a window on a blank audio file for example, then
there will be no frame thus draw_frame did nothing. Since the previous
commit allows us to reliably detect this, we can rearrange the code
around a little bit to make this possible. A key change is to make the
osd_subsurface have wl->surface as the parent. This is seemingly
required otherwise the osd_surface buffers are never visible above the
empty video_surface when we have a black window. Also nuke the desync
call since it's completely pointless. Fixes#12429.
So far all the keypad keys except for `0` and `,` mapped to the same
MP_KEY_* independent of numlock state, even though different key codes
are received.
Now all the alternative functions map to appropriate MP_KEY_* defines,
with missing ones added.
There was no known problem with this, but according to the wayland
spec*, "After this event client must assume that no keys are
pressed...", so go ahead and do that.
*: 72da004b3e/protocol/wayland.xml (L2449)
Introduced by 1f8013ff3f. We try to save
the mpkey so it can be used in the modifier event that comes next if
appropriate and also clear it when needed. The problem is that the
condition for clearing is too strict and things like mismatched cases
and so on can make mpkey on the corresponding key release event not
match the saved mpkey even though in reality they were the same key.
Loosen the check by simply always clearing the saved mpkey as long as
there was some key found and the state is up. We don't handle multiple
keys at the same time anyways (they're interpreted in a sequence), so it
should be hopefully OK.