From 77809faea13f066fada8e58d190aeaeb047b0487 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Sat, 27 Apr 2024 02:23:58 -0400 Subject: [PATCH] input: add --input-touch-emulate-mouse option This adds --input-touch-emulate-mouse option, which controls whether to enable legacy touch handling where touch inputs are emulated as mouse inputs. This establishes a primary touch point (the one with the lowest index) as the emulated mouse position, and MBTN_LEFT up/down with the appearance of the first touch point and the disappearance of the last touch point. This fixes some problems with touch handling on Wayland, for example attempting to pinch results in a double click. --- .../input-touch-emulate-mouse.txt | 1 + DOCS/man/options.rst | 7 +++++++ input/input.c | 14 ++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 DOCS/interface-changes/input-touch-emulate-mouse.txt diff --git a/DOCS/interface-changes/input-touch-emulate-mouse.txt b/DOCS/interface-changes/input-touch-emulate-mouse.txt new file mode 100644 index 0000000000..00b08b7715 --- /dev/null +++ b/DOCS/interface-changes/input-touch-emulate-mouse.txt @@ -0,0 +1 @@ +add --input-touch-emulate-mouse option diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index bf1d55a294..bad1e75354 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -4281,6 +4281,13 @@ Input disabled by default in libmpv as well - it should be enabled if you want the mpv default key bindings. +``--input-touch-emulate-mouse=`` + When multi-touch support is enabled (either required by the platform, + or enabled by ``--native-touch``), emulate mouse move and button presses + for the touch events (default: yes). This is useful for compatibility + for mouse key bindings and scripts which read mouse positions for platforms + which do not support ``--native-touch=no`` (e.g. Wayland). + OSD --- diff --git a/input/input.c b/input/input.c index 1f747f01cd..92e2a6d5b9 100644 --- a/input/input.c +++ b/input/input.c @@ -187,6 +187,7 @@ struct input_opts { bool test; bool allow_win_drag; bool preprocess_wheel; + bool touch_emulate_mouse; }; const struct m_sub_options input_config = { @@ -207,6 +208,7 @@ const struct m_sub_options input_config = { {"input-vo-keyboard", OPT_BOOL(vo_key_input)}, {"input-media-keys", OPT_BOOL(use_media_keys)}, {"input-preprocess-wheel", OPT_BOOL(preprocess_wheel)}, + {"input-touch-emulate-mouse", OPT_BOOL(touch_emulate_mouse)}, #if HAVE_SDL2_GAMEPAD {"input-gamepad", OPT_BOOL(use_gamepad)}, #endif @@ -227,6 +229,7 @@ const struct m_sub_options input_config = { .vo_key_input = true, .allow_win_drag = true, .preprocess_wheel = true, + .touch_emulate_mouse = true, }, .change_flags = UPDATE_INPUT, }; @@ -927,6 +930,9 @@ static void update_touch_point(struct input_ctx *ictx, int idx, int id, int x, i return; ictx->touch_points[idx].x = x; ictx->touch_points[idx].y = y; + // Emulate mouse input from the primary touch point (the first one added) + if (ictx->opts->touch_emulate_mouse && idx == 0) + set_mouse_pos(ictx, x, y); notify_touch_update(ictx); } @@ -943,6 +949,11 @@ void mp_input_add_touch_point(struct input_ctx *ictx, int id, int x, int y) ictx->num_touch_points, id, x, y); MP_TARRAY_APPEND(ictx, ictx->touch_points, ictx->num_touch_points, (struct touch_point){id, x, y}); + // Emulate MBTN_LEFT down if this is the only touch point + if (ictx->opts->touch_emulate_mouse && ictx->num_touch_points == 1) { + set_mouse_pos(ictx, x, y); + feed_key(ictx, MP_MBTN_LEFT | MP_KEY_STATE_DOWN, 1, false); + } notify_touch_update(ictx); } input_unlock(ictx); @@ -967,6 +978,9 @@ void mp_input_remove_touch_point(struct input_ctx *ictx, int id) if (idx != -1) { MP_TRACE(ictx, "Touch point %d remove (id %d)\n", idx, id); MP_TARRAY_REMOVE_AT(ictx->touch_points, ictx->num_touch_points, idx); + // Emulate MBTN_LEFT up if there are no touch points left + if (ictx->opts->touch_emulate_mouse && ictx->num_touch_points == 0) + feed_key(ictx, MP_MBTN_LEFT | MP_KEY_STATE_UP, 1, false); notify_touch_update(ictx); } input_unlock(ictx);