summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst2
-rw-r--r--DOCS/man/options.rst6
-rw-r--r--options/options.c1
-rw-r--r--options/options.h1
-rw-r--r--video/out/wayland_common.c19
-rw-r--r--video/out/x11_common.c27
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 ||