diff options
-rw-r--r-- | DOCS/interface-changes.rst | 2 | ||||
-rw-r--r-- | DOCS/man/options.rst | 6 | ||||
-rw-r--r-- | options/options.c | 1 | ||||
-rw-r--r-- | options/options.h | 1 | ||||
-rw-r--r-- | video/out/wayland_common.c | 19 | ||||
-rw-r--r-- | video/out/x11_common.c | 27 |
6 files changed, 54 insertions, 2 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index bb503fcede..6fa814afff 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -80,6 +80,8 @@ Interface changes - add `--corner-rounding` option - change `--subs-with-matching-audio` default from `yes` to `no` - change `--slang` default from blank to `auto` + - add `--input-cursor-passthrough` option to allow pointer events to completely + passthrough the mpv window --- mpv 0.35.0 --- - add the `--vo=gpu-next` video output driver, as well as the options `--allow-delayed-peak-detect`, `--builtin-scalers`, diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 99f7f2b078..acdf098585 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -4060,6 +4060,12 @@ Input driver. Necessary to use the OSC, or to select the buttons in DVD menus. Support depends on the VO in use. +``--input-cursor-passthrough``, ``--no-input-cursor-passthrough`` + (X11 and Wayland only) + Tell the backend windowing system to allow pointer events to passthrough + the mpv window. This allows windows under mpv to instead receive pointer + events as if the mpv window was never there. + ``--input-media-keys=<yes|no>`` On systems where mpv can choose between receiving media keys or letting the system handle them - this option controls whether mpv should receive diff --git a/options/options.c b/options/options.c index 24160a0a84..92790dfb01 100644 --- a/options/options.c +++ b/options/options.c @@ -135,6 +135,7 @@ static const m_option_t mp_vo_opt_list[] = { M_RANGE(1.0/32.0, 32.0)}, {"fullscreen", OPT_BOOL(fullscreen)}, {"fs", OPT_ALIAS("fullscreen")}, + {"input-cursor-passthrough", OPT_BOOL(cursor_passthrough)}, {"native-keyrepeat", OPT_BOOL(native_keyrepeat)}, {"panscan", OPT_FLOAT(panscan), M_RANGE(0.0, 1.0)}, {"video-zoom", OPT_FLOAT(zoom), M_RANGE(-20.0, 20.0)}, diff --git a/options/options.h b/options/options.h index 6dbe509a5b..0125c433f5 100644 --- a/options/options.h +++ b/options/options.h @@ -32,6 +32,7 @@ typedef struct mp_vo_opts { int x11_netwm; int x11_bypass_compositor; int x11_present; + bool cursor_passthrough; bool native_keyrepeat; float panscan; diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index ed9c7a911a..28cd6eb55b 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -1548,7 +1548,8 @@ static void greatest_common_divisor(struct vo_wayland_state *wl, int a, int b) { } } -static void guess_focus(struct vo_wayland_state *wl) { +static void guess_focus(struct vo_wayland_state *wl) +{ // We can't actually know if the window is focused or not in wayland, // so just guess it with some common sense. Obviously won't work if // the user has no keyboard. @@ -1717,6 +1718,17 @@ static void set_geometry(struct vo_wayland_state *wl, bool resize) } } +static void set_input_region(struct vo_wayland_state *wl, bool passthrough) +{ + if (passthrough) { + struct wl_region *region = wl_compositor_create_region(wl->compositor); + wl_surface_set_input_region(wl->surface, region); + wl_region_destroy(region); + } else { + wl_surface_set_input_region(wl->surface, NULL); + } +} + static int set_screensaver_inhibitor(struct vo_wayland_state *wl, int state) { if (!wl->idle_inhibit_manager) @@ -1967,6 +1979,8 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg) } if (opt == &opts->content_type) set_content_type(wl); + if (opt == &opts->cursor_passthrough) + set_input_region(wl, opts->cursor_passthrough); if (opt == &opts->fullscreen) toggle_fullscreen(wl); if (opt == &opts->hidpi_window_scale) @@ -2255,6 +2269,9 @@ bool vo_wayland_reconfig(struct vo *vo) wl->geometry = wl->window_size; } + if (wl->vo_opts->cursor_passthrough) + set_input_region(wl, true); + if (wl->vo_opts->fullscreen) toggle_fullscreen(wl); diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 3faae5ef19..b3bdf1c014 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -35,6 +35,7 @@ #include <X11/extensions/scrnsaver.h> #include <X11/extensions/dpms.h> +#include <X11/extensions/shape.h> #include <X11/extensions/Xinerama.h> #include <X11/extensions/Xpresent.h> #include <X11/extensions/Xrandr.h> @@ -149,6 +150,7 @@ static void vo_x11_move_resize(struct vo *vo, bool move, bool resize, struct mp_rect rc); static void vo_x11_maximize(struct vo *vo); static void vo_x11_minimize(struct vo *vo); +static void vo_x11_set_input_region(struct vo *vo, bool passthrough); static void vo_x11_sticky(struct vo *vo, bool sticky); #define XA(x11, s) (XInternAtom((x11)->display, # s, False)) @@ -1641,6 +1643,9 @@ static void vo_x11_map_window(struct vo *vo, struct mp_rect rc) vo_x11_selectinput_witherr(vo, x11->display, x11->window, events); XMapWindow(x11->display, x11->window); + if (x11->opts->cursor_passthrough) + vo_x11_set_input_region(vo, true); + if (x11->opts->window_maximized) // don't override WM default on "no" vo_x11_maximize(vo); if (x11->opts->window_minimized) // don't override WM default on "no" @@ -1978,7 +1983,8 @@ static void vo_x11_set_geometry(struct vo *vo) vo_x11_config_vo_window(vo); } -bool vo_x11_check_visible(struct vo *vo) { +bool vo_x11_check_visible(struct vo *vo) +{ struct vo_x11_state *x11 = vo->x11; struct mp_vo_opts *opts = x11->opts; @@ -1987,6 +1993,23 @@ bool vo_x11_check_visible(struct vo *vo) { return render; } +static void vo_x11_set_input_region(struct vo *vo, bool passthrough) +{ + struct vo_x11_state *x11 = vo->x11; + + if (passthrough) { + XRectangle rect = {0, 0, 0, 0}; + Region region = XCreateRegion(); + XUnionRectWithRegion(&rect, region, region); + XShapeCombineRegion(x11->display, x11->window, ShapeInput, 0, 0, + region, ShapeSet); + XDestroyRegion(region); + } else { + XShapeCombineMask(x11->display, x11->window, ShapeInput, 0, 0, + 0, ShapeSet); + } +} + int vo_x11_control(struct vo *vo, int *events, int request, void *arg) { struct vo_x11_state *x11 = vo->x11; @@ -2012,6 +2035,8 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg) vo_x11_minimize(vo); if (opt == &opts->window_maximized) vo_x11_maximize(vo); + if (opt == &opts->cursor_passthrough) + vo_x11_set_input_region(vo, opts->cursor_passthrough); if (opt == &opts->x11_present) xpresent_set(x11); if (opt == &opts->geometry || opt == &opts->autofit || |