diff --git a/DOCS/interface-changes/input-builtin-dragging.txt b/DOCS/interface-changes/input-builtin-dragging.txt new file mode 100644 index 0000000000000..5dbce769872e8 --- /dev/null +++ b/DOCS/interface-changes/input-builtin-dragging.txt @@ -0,0 +1 @@ +add `--input-builtin-dragging` option diff --git a/DOCS/interface-changes/input-dragging-deadzone.txt b/DOCS/interface-changes/input-dragging-deadzone.txt new file mode 100644 index 0000000000000..d2628d4cbd11a --- /dev/null +++ b/DOCS/interface-changes/input-dragging-deadzone.txt @@ -0,0 +1 @@ +add `--input-dragging-deadzone` option diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 9a34a69c50ab4..d47e997f0e1b3 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -4139,6 +4139,12 @@ Input option is applied only during (lib)mpv initialization, and if disabled then it will not be not possible to enable them later. May be useful to libmpv clients. +``--input-builtin-dragging=`` + Enable the built-in window-dragging behavior (default: yes). Setting it to no + disables the built-in dragging behavior. Note that unlike the ``window-dragging`` + option, this option only affects VOs which support the ``begin-vo-dragging`` + command, and does not disable window dragging initialized with the command. + ``--input-cmdlist`` Prints all commands that can be bound to keys. @@ -4236,8 +4242,7 @@ Input ``--input-cursor=`` Permit mpv to receive pointer events reported by the video output - driver. Necessary to use the OSC, or to select the buttons in DVD menus. - Support depends on the VO in use. + driver. Necessary to use the OSC. Support depends on the VO in use. ``--input-cursor-passthrough=`` Tell the backend windowing system to allow pointer events to passthrough @@ -4304,6 +4309,11 @@ Input for mouse key bindings and scripts which read mouse positions for platforms which do not support ``--native-touch=no`` (e.g. Wayland). +``--input-dragging-deadzone=`` + Begin the built-in window dragging when the mouse moves outside a deadzone of + ``N`` pixels while the mouse button is being held down (default: 3). This only + affects VOs which support the ``begin-vo-dragging`` command. + OSD --- diff --git a/input/input.c b/input/input.c index b75a2f1a5f7c1..3ae7215cd0ee4 100644 --- a/input/input.c +++ b/input/input.c @@ -120,6 +120,12 @@ struct input_ctx { int last_doubleclick_key_down; double last_doubleclick_time; + // VO dragging state + bool dragging_button_down; + int mouse_drag_x, mouse_drag_y; + // Raw mouse position before transform + int mouse_raw_x, mouse_raw_y; + // Mouse position on the consumer side (as command.c sees it) int mouse_x, mouse_y; int mouse_hover; // updated on mouse-enter/leave @@ -175,11 +181,13 @@ struct input_opts { // Autorepeat config (be aware of mp_input_set_repeat_info()) int ar_delay; int ar_rate; + int dragging_deadzone; bool use_alt_gr; bool use_gamepad; bool use_media_keys; bool default_bindings; bool builtin_bindings; + bool builtin_dragging; bool enable_mouse_movements; bool vo_key_input; bool test; @@ -197,6 +205,7 @@ const struct m_sub_options input_config = { {"input-cmdlist", OPT_PRINT(mp_print_cmd_list)}, {"input-default-bindings", OPT_BOOL(default_bindings)}, {"input-builtin-bindings", OPT_BOOL(builtin_bindings)}, + {"input-builtin-dragging", OPT_BOOL(builtin_dragging)}, {"input-test", OPT_BOOL(test)}, {"input-doubleclick-time", OPT_INT(doubleclick_time), M_RANGE(0, 1000)}, @@ -207,6 +216,7 @@ const struct m_sub_options input_config = { {"input-media-keys", OPT_BOOL(use_media_keys)}, {"input-preprocess-wheel", OPT_BOOL(preprocess_wheel)}, {"input-touch-emulate-mouse", OPT_BOOL(touch_emulate_mouse)}, + {"input-dragging-deadzone", OPT_INT(dragging_deadzone)}, #if HAVE_SDL2_GAMEPAD {"input-gamepad", OPT_BOOL(use_gamepad)}, #endif @@ -219,11 +229,13 @@ const struct m_sub_options input_config = { .doubleclick_time = 300, .ar_delay = 200, .ar_rate = 40, + .dragging_deadzone = 3, .use_alt_gr = true, .enable_mouse_movements = true, .use_media_keys = true, .default_bindings = true, .builtin_bindings = true, + .builtin_dragging = true, .vo_key_input = true, .allow_win_drag = true, .preprocess_wheel = true, @@ -733,6 +745,7 @@ static void feed_key(struct input_ctx *ictx, int code, double scale, if (code == MP_INPUT_RELEASE_ALL) { MP_TRACE(ictx, "release all\n"); release_down_cmd(ictx, false); + ictx->dragging_button_down = false; return; } if (code == MP_TOUCH_RELEASE_ALL) { @@ -771,13 +784,22 @@ static void feed_key(struct input_ctx *ictx, int code, double scale, 1, 1); } else if (code == MP_MBTN_LEFT) { // This is a mouse left botton down event which isn't part of a doubleclick. - // Initialize vo dragging in this case. - mp_cmd_t *cmd = mp_input_parse_cmd(ictx, bstr0("begin-vo-dragging"), ""); - queue_cmd(ictx, cmd); + // Mark the dragging mouse button down in this case. + ictx->dragging_button_down = true; + // Store the current mouse position for deadzone handling. + ictx->mouse_drag_x = ictx->mouse_raw_x; + ictx->mouse_drag_y = ictx->mouse_raw_y; } ictx->last_doubleclick_key_down = code; ictx->last_doubleclick_time = now; } + if (code & MP_KEY_STATE_UP) { + code &= ~MP_KEY_STATE_UP; + if (code == MP_MBTN_LEFT) { + // This is a mouse left botton up event. Mark the dragging mouse button up. + ictx->dragging_button_down = false; + } + } } void mp_input_put_key(struct input_ctx *ictx, int code) @@ -853,9 +875,11 @@ static void set_mouse_pos(struct input_ctx *ictx, int x, int y) { MP_TRACE(ictx, "mouse move %d/%d\n", x, y); - if (ictx->mouse_vo_x == x && ictx->mouse_vo_y == y) { + if (ictx->mouse_raw_x == x && ictx->mouse_raw_y == y) { return; } + ictx->mouse_raw_x = x; + ictx->mouse_raw_y = y; if (ictx->mouse_mangle) { struct mp_rect *src = &ictx->mouse_src; @@ -894,6 +918,22 @@ static void set_mouse_pos(struct input_ctx *ictx, int x, int y) queue_cmd(ictx, cmd); } } + + bool mouse_outside_dragging_deadzone = + abs(ictx->mouse_raw_x - ictx->mouse_drag_x) >= ictx->opts->dragging_deadzone || + abs(ictx->mouse_raw_y - ictx->mouse_drag_y) >= ictx->opts->dragging_deadzone; + if (ictx->dragging_button_down && mouse_outside_dragging_deadzone && + ictx->opts->builtin_dragging) + { + // Begin built-in VO dragging if the mouse moves while the dragging button is down. + ictx->dragging_button_down = false; + // Prevent activation of MBTN_LEFT key binding if VO dragging begins. + release_down_cmd(ictx, true); + // Prevent activation of MBTN_LEFT_DBL if VO dragging begins. + ictx->last_doubleclick_time = 0; + mp_cmd_t *drag_cmd = mp_input_parse_cmd(ictx, bstr0("begin-vo-dragging"), ""); + queue_cmd(ictx, drag_cmd); + } } void mp_input_set_mouse_pos_artificial(struct input_ctx *ictx, int x, int y)