summaryrefslogtreecommitdiffstats
path: root/video/out/wayland_common.c
Commit message (Collapse)AuthorAgeFilesLines
* wayland: only use presentation on CLOCK_MONOTONICDudemanguy2020-05-181-2/+2
| | | | | | | 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.
* wayland: explictly send an UP event for left clickDudemanguy2020-04-231-0/+2
| | | | | | | | | | | | | | | 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.
* wayland: use mp_time deltas for presentation timeDudemanguy2020-04-201-24/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* wayland: simplify mouse wheel direction calculationJan Ekström2020-03-191-3/+2
| | | | | Based on an idea by sfan5. Remove abs usage, and instead just check for negative value, and set variable to either +/-1.
* options: change option macros and all option declarationswm42020-03-181-3/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* wayland: notify vo if an output changesDudemanguy2020-03-151-0/+2
| | | | | | | | 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.
* wayland: always use the fs-screen id for fsDudemanguy2020-03-081-33/+31
| | | | | | | | | 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.
* wayland: make resizing betterDudemanguy2020-02-131-5/+29
| | | | | | | | | 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.
* wayland: fix autofit and rotating issuesDudemanguy2020-02-131-5/+7
| | | | | | 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: adjust vo_wayland_wait_frame logicDudemanguy2020-02-071-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* wayland: toplevel config fixesDudemanguy2020-02-061-3/+16
| | | | | | | | | | | | | | | | | | | | | | | 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.
* wayland: remove wayland-frame-wait-offset optiondudemanguy2020-01-311-4/+2
| | | | | | | | | | | | | | | | | 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.
* wayland: support maximize/minimize on startupDudemanguy2020-01-121-0/+6
| | | | | | | 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.
* wayland: unscrew up cursorsdudemanguy2020-01-121-6/+4
| | | | | | | | | | | | | | 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.
* wayland: don't set cursor before pointer idDudemanguy2020-01-111-1/+1
| | | | | | | | | | | 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.
* wayland: don't exit the option loopDudemanguy2020-01-041-16/+12
| | | | | More than one option may change at the same time so don't break out of this loop.
* wayland: disable by default for gnomeDudemanguy2020-01-011-0/+4
| | | | | | | | | 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.
* wayland: remove unnecessary VO_EVENT_FULLSCREEN_STATEwm42019-12-121-3/+0
| | | | | This is needed and used only for VOCTRL_GET_FULLSCREEN, which the wayland code got rid of.
* wayland: adjust hidden state detectiondudemanguy2019-12-101-4/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 enough (a few seconds). When using presentation time, this causes mpv to feed in some bad values in its vsync timing mechanism thus causing the A/V desync spike as described in issue #7223. This solution is not really ideal. It would be better if the presentation time events received by the compositors did not have the aforementioned inconsistency. However since this occurs in both Sway and Weston and clients can't really fight compositors in wayland-world, here's a reasonable enough workaround. Basically, just add a slight delay before we start feeding information into the vo_sync_info again. We already do this when the window is hidden, so it's not a huge leap. The delay chosen here is arbitrary, and it basically just recycles the same parameters used to detect if a window is hidden. If vo_wayland_wait_frame times out 60 times in a row (or whatever your monitor's refresh rate is), then we assume the window is hidden. This is a pretty safe assumption; something has to be terribly wrong for you to miss 60 vblanks in a row while a window is on the screen. In this case, we basically just do the reverse of that. If mpv receives 60 frame callbacks in a row (or whatever your monitor's refresh rate is), then it assumes the window is not hidden. Previously, as soon as it received 1 frame callback it was declared not hidden. Essentially, there's just 1 second of delay after reshowing a window before the presentation time statistics are used again. This should be more than enough time to skip over the weird inconsistent behavior presentation time behavior and avoid the A/V desync spike. Fixes #7223
* osc: rework window control configuration to add auto modePhilip Langdale2019-12-041-1/+8
| | | | | | | | | | | | | | | | To aid in discoverability, and to address the most common case directly, I'm adding an 'auto' mode for the window controls. In this case, we will show the controls if there is no window border and hide them if there are borders. This also respects the option being toggled at runtime. To ensure that it works in the wayland case, I've also made sure that the wayland code explicitly forces the option to false if decoration support is missing. Based on feedback, I've split the config in two, with one option for whether controls are active, and one for alignment. These are new enough that we can get away with ignoring compatibility.
* wayland: fix cursor behavior on an edge casedudemanguy2019-12-041-6/+2
| | | | | | | | | | | | | | | | | This small regression was introduced by #7216. Previously, the wayland backend used a trick which kept track of the previous fullscreen state and used that logic for showing the cursor. Since vo_opts now keeps track of the current fullscreen state, most of this stopped being neccessary. However, there was one edge case where the cursor didn't behave the same: passing a fullscreen flag for the inital window. The cursor would initially be visible here which is not desirable. This can be remedied pretty easily by just setting the cursor visiblity to false if the pointer entry event occurs on fullscreen. The only thing we need to do is to make sure that the autohide delay isn't completely disabled (i.e. the cursor is always visible). Hence the need for the previous commit.
* wayland: update remaining legacy VOCTRL usage to optionsPhilip Langdale2019-12-021-30/+27
| | | | | | | | | | | The remaining legacy VOCTRLs are for the fullscreen and border properties. For fullscreen this largely just replacing the private state field with the vo option but there are small semantic differences that we need to be careful of. For the border setting, it's trivial as we don't have external mechanisms for changing the state, but I also can't test it as I'm not using a compositor that supports it.
* wayland: update Maximize and Minimize handling to use new optionsPhilip Langdale2019-12-011-22/+40
| | | | | | | | | | | I wanted to get this done quickly as I introduced the new VOCTRL behaviour for minimize and maximize and it was immediately made legacy, so best to purge it before anyone gets confused. I did not sort out fullscreen as that's more involved and not something I've educated myself about yet. But I did replace the VOCTRL_FULLSCREEN usage with the new option change mechanism as that seemed simple enough.
* wayland: implement minimize and maximize related VOCTRLsPhilip Langdale2019-11-291-0/+27
| | | | | | | We primarily care about pseudo-decorations for wayland, where the compositor may not support server-side decorations. So let's implement the minimize and maximize commands and return the maximized window state.
* wayland: restore window geometry after un-maximizePhilip Langdale2019-11-291-3/+2
| | | | | | | | | | | | | At least with gnome-shell (I know, I know), the compositor does not provide the old window size when leaving the maximized state. Instead, we get a toplevel_config event with a 0x0 size and no additional states. Today, we already save the window geometry to restore it when leaving the fullscreen state, so we just need a small change for it to kick in for leaving the maximized state. If I read this correctly, we'll still respect the size passed by a compositor that actually provides the old size.
* wayland: make the edge grab zone width user configurablePhilip Langdale2019-11-291-5/+6
| | | | | | | Rather than hard-coding the edge grab zone width, we can make it user configurable. It seems worthwhile to have separate configs for pointer and touch usage as the defaults should be different, and a user might have both input methods in use.
* wayland: add grab zone for resizing window with mousePhilip Langdale2019-11-291-40/+52
| | | | | | | | Today, we support resizing wayland windows when we detect a touch event in a defined grab zone. As part of implementing pseudo-decorations, we should have equivalent functionality for mouse input. And if we detect support for actual decorations we will not activate the grab zone as the decorations will provide this.
* wayland: use hidpi-window-scale optiondudemanguy2019-11-121-0/+2
|
* wayland: don't get data device if wl_seat is nulldudemanguy2019-10-221-2/+2
|
* wayland: fix presentation timeDudemanguy9112019-10-201-0/+10
| | | | | | | | | | There's 2 stupid things here that need to be fixed. First of all, vulkan wasn't actually using presentation time because somehow the get_vsync function in context.c disappeared. Secondly, if the mpv window was hidden it was updating the ust time based on the refresh_usec but really it should simply just not feed any information to the vsync info structure. So this adds some logic to assume whether or not a window is hidden.
* wayland: add various render-related optionsdudemanguy2019-10-201-2/+18
| | | | | The newest wayland changes have some new logic that make sense to expose to users as configurable options.
* wayland: add presentation timedudemanguy2019-10-201-2/+104
| | | | | Use ust/msc/refresh values from wayland's presentation time in mpv's ra_swapchain_fns.get_vsync for the wayland contexts.
* wayland: use callback flag + poll for buffer swapdudemanguy2019-10-101-19/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The old way of using wayland in mpv relied on an external renderloop for semi-accurate timings. This had multiple issues though. Display sync would break whenever the window was hidden (since the frame callback stopped being executed) which was really annoying. Also the entire external renderloop logic was kind of fragile and didn't play well with mpv's internal structure (i.e. using presentation time in that old paradigm breaks stats.lua). Basically the problem is that swap buffers blocks on wayland which is crap whenever you hide the mpv window since it looks up the entire player. So you have to make swap buffers not block, but this has a different problem. Timings will be terrible if you use the unblocked swap buffers call. Based on some discussion in #wayland, the trick here is relatively simple and works well enough for our purposes. Instead we basically build a way to block with a timeout in the wayland buffer swap functions. A bool is set in the frame callback function that indicates whether or not mpv is waiting for a frame to be displayed. In the actual buffer swap function, we enter into a while loop waiting for this flag to be set. At the same time, the wl_display is polled to block the thread and wakeup if it receives any events from the compositor. This loop only breaks if enough time has passed or if the frame callback bool is received. In the near future, it is better to set whether or not frame a frame has been displayed in the presentation feedback. However as a first pass, doing it in the frame callback is more than good enough. The "downside" is that we render frames that aren't actually shown on screen when the player is hidden (it seems like wayland people don't like that). But who cares. Accurate timings are way more important. It's probably not too hard to add that behavior back in the player though.
* Revert "vo: add support for externally driven renderloop and make wayland ↵dudemanguy2019-10-101-15/+0
| | | | | | | | | | use it" The externally driven renderloop was originally added for the wayland context (to make display sync somewhat work), but it has a lot of issues with mpv's internal structure. A different approach should be used. This reverts commit a743fef837bcab206b1e576db7e7a64b02890449.
* Revert "wayland: free wayland_state on a false return"dudemanguy2019-10-031-11/+3
| | | | | | | | Dumb idea. The correct thing to do is to fix the preinit and context creation so that the uninit is correctly executed when probing fails (and then everything gets freed). This reverts commit defc8f359c5e4bb666e8ad1d4a097a8ac66cc1e2.
* wayland: free wayland_state on a false returnDudemanguy9112019-10-021-3/+11
| | | | | | wm4 mentioned that the wayland autoprobe leaked. A simple oversight in the wayland_common code forgot to free the vo_wayland_state if vo_wayland_init returned false.
* wayland: always create wl_output before renderingDudemanguy9112019-10-021-7/+6
| | | | | | | | | | | I previously skipped creating the wl_output if the --fullscreen flag with no --fsscreen_id was inputted, so the fullscreen video lands on the correct output (where mpv was launched). This has breakage if someone combines the --autofit flag (or other similar options with it). Instead, just actually read xdg_shell spec and realize that you can pass NULL to xdg_toplevel_set_fullscreen and let the compositor choose the output if the user doesn't specify it. If this has issues, get a better compositor.
* wayland: create current_output in wayland_reconfigdudemanguy2019-09-221-5/+6
| | | | | | | | Certain mpv config options require wl->current_output to be created before the video can actually start rendering. Just always create it here if the current_output doesn't exist (the one exception being the --fs option with no --fs-screen flag). Incidentally, this also fixes --fs-screen not working on wayland.
* wayland: avoid handling a 0-value axis eventDudemanguy9112019-09-211-0/+2
| | | | This shouldn't be possible, but an extra check never hurts.
* wayland: read xcursor size from XCURSOR_SIZE envemersion2019-09-211-1/+13
| | | | | This allows compositors to set the cursor size from user configuration.
* wayland: don't show cursor when fullscreeningdudemanguy2019-09-211-0/+6
|
* wayland: reconfigure cursor on pointer enter eventThomas Weißschuh2019-09-211-1/+3
| | | | | | | | | | | | | | | | | | | | | On wayland the cursor has to be configured each time the pointer enters. Currently if the window (re)gains the focus, the pointer is not hidden, even when configured. After the mouse has been moved the pointer hides correctly. https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_pointer: wl_pointer::enter - enter event ... When a seat's focus enters a surface, the pointer image is undefined and a client should respond to this event by setting an appropriate pointer image with the set_cursor request. Fixes #6185. Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
* wayland: add mouse buttons and fix axis scalingdudemanguy2019-09-211-4/+24
| | | | | | | | | | Previously, the only mouse buttons supported in wayland were left, right, and middle click. This adds the thumb back/forward buttons as valid bindings. Also it removes the old, default behavior of always sending a right click if an unrecognized mouse button is clicked. In a related but different fix, the magnitude of an axis event in wayland is not impo