diff --git a/app/data/bash-completion/scrcpy b/app/data/bash-completion/scrcpy index f00fadae..b35ea5e4 100644 --- a/app/data/bash-completion/scrcpy +++ b/app/data/bash-completion/scrcpy @@ -50,6 +50,7 @@ _scrcpy() { --no-downsize-on-error --no-key-repeat --no-mipmaps + --no-mouse-hover --no-power-on --no-video --no-video-playback diff --git a/app/data/zsh-completion/_scrcpy b/app/data/zsh-completion/_scrcpy index 86fe0b0e..5afca977 100644 --- a/app/data/zsh-completion/_scrcpy +++ b/app/data/zsh-completion/_scrcpy @@ -56,6 +56,7 @@ arguments=( '--no-downsize-on-error[Disable lowering definition on MediaCodec error]' '--no-key-repeat[Do not forward repeated key events when a key is held down]' '--no-mipmaps[Disable the generation of mipmaps]' + '--no-mouse-hover[Do not forward mouse hover events]' '--no-power-on[Do not power on the device on start]' '--no-video[Disable video forwarding]' '--no-video-playback[Disable video playback]' diff --git a/app/scrcpy.1 b/app/scrcpy.1 index b2021f26..cf8dfa7f 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -317,6 +317,10 @@ Do not forward repeated key events when a key is held down. .B \-\-no\-mipmaps If the renderer is OpenGL 3.0+ or OpenGL ES 2.0+, then mipmaps are automatically generated to improve downscaling quality. This option disables the generation of mipmaps. +.TP +.B \-\-no\-mouse\-hover +Do not forward mouse hover (mouse motion without any clicks) events. + .TP .B \-\-no\-power\-on Do not power on the device on start. diff --git a/app/src/cli.c b/app/src/cli.c index d3ba3463..08a4aa3f 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -99,6 +99,7 @@ enum { OPT_HID_MOUSE_DEPRECATED, OPT_NO_WINDOW, OPT_MOUSE_BIND, + OPT_NO_MOUSE_HOVER, }; struct sc_option { @@ -568,6 +569,12 @@ static const struct sc_option options[] = { "mipmaps are automatically generated to improve downscaling " "quality. This option disables the generation of mipmaps.", }, + { + .longopt_id = OPT_NO_MOUSE_HOVER, + .longopt = "no-mouse-hover", + .text = "Do not forward mouse hover (mouse motion without any clicks) " + "events.", + }, { .longopt_id = OPT_NO_POWER_ON, .longopt = "no-power-on", @@ -2198,6 +2205,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], return false; } break; + case OPT_NO_MOUSE_HOVER: + opts->mouse_hover = false; + break; case OPT_HID_MOUSE_DEPRECATED: LOGE("--hid-mouse has been removed, use --mouse=aoa or " "--mouse=uhid instead."); @@ -2758,6 +2768,12 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], } } + if (opts->mouse_input_mode != SC_MOUSE_INPUT_MODE_SDK + && !opts->mouse_hover) { + LOGE("--no-mouse-over is specific to --mouse=sdk"); + return false; + } + if ((opts->tunnel_host || opts->tunnel_port) && !opts->force_adb_forward) { LOGI("Tunnel host/port is set, " "--force-adb-forward automatically enabled."); diff --git a/app/src/mouse_sdk.c b/app/src/mouse_sdk.c index 620fb52c..a7998972 100644 --- a/app/src/mouse_sdk.c +++ b/app/src/mouse_sdk.c @@ -58,17 +58,18 @@ convert_touch_action(enum sc_touch_action action) { static void sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp, const struct sc_mouse_motion_event *event) { - if (!event->buttons_state) { + struct sc_mouse_sdk *m = DOWNCAST(mp); + + if (!m->mouse_hover && !event->buttons_state) { // Do not send motion events when no click is pressed return; } - struct sc_mouse_sdk *m = DOWNCAST(mp); - struct sc_control_msg msg = { .type = SC_CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT, .inject_touch_event = { - .action = AMOTION_EVENT_ACTION_MOVE, + .action = event->buttons_state ? AMOTION_EVENT_ACTION_MOVE + : AMOTION_EVENT_ACTION_HOVER_MOVE, .pointer_id = event->pointer_id, .position = event->position, .pressure = 1.f, @@ -145,8 +146,10 @@ sc_mouse_processor_process_touch(struct sc_mouse_processor *mp, } void -sc_mouse_sdk_init(struct sc_mouse_sdk *m, struct sc_controller *controller) { +sc_mouse_sdk_init(struct sc_mouse_sdk *m, struct sc_controller *controller, + bool mouse_hover) { m->controller = controller; + m->mouse_hover = mouse_hover; static const struct sc_mouse_processor_ops ops = { .process_mouse_motion = sc_mouse_processor_process_mouse_motion, diff --git a/app/src/mouse_sdk.h b/app/src/mouse_sdk.h index 444a6ad5..142b89bb 100644 --- a/app/src/mouse_sdk.h +++ b/app/src/mouse_sdk.h @@ -13,9 +13,11 @@ struct sc_mouse_sdk { struct sc_mouse_processor mouse_processor; // mouse processor trait struct sc_controller *controller; + bool mouse_hover; }; void -sc_mouse_sdk_init(struct sc_mouse_sdk *m, struct sc_controller *controller); +sc_mouse_sdk_init(struct sc_mouse_sdk *m, struct sc_controller *controller, + bool mouse_hover); #endif diff --git a/app/src/options.c b/app/src/options.c index 352d9895..5556d1f9 100644 --- a/app/src/options.c +++ b/app/src/options.c @@ -92,6 +92,7 @@ const struct scrcpy_options scrcpy_options_default = { .camera_high_speed = false, .list = 0, .window = true, + .mouse_hover = true, }; enum sc_orientation diff --git a/app/src/options.h b/app/src/options.h index d5b090b7..f840a989 100644 --- a/app/src/options.h +++ b/app/src/options.h @@ -290,6 +290,7 @@ struct scrcpy_options { #define SC_OPTION_LIST_CAMERA_SIZES 0x8 uint8_t list; bool window; + bool mouse_hover; }; extern const struct scrcpy_options scrcpy_options_default; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 85b89935..5e78dbf3 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -681,7 +681,8 @@ scrcpy(struct scrcpy_options *options) { } if (options->mouse_input_mode == SC_MOUSE_INPUT_MODE_SDK) { - sc_mouse_sdk_init(&s->mouse_sdk, &s->controller); + sc_mouse_sdk_init(&s->mouse_sdk, &s->controller, + options->mouse_hover); mp = &s->mouse_sdk.mouse_processor; } else if (options->mouse_input_mode == SC_MOUSE_INPUT_MODE_UHID) { bool ok = sc_mouse_uhid_init(&s->mouse_uhid, &s->controller); diff --git a/doc/mouse.md b/doc/mouse.md index 42d70766..1c62ddd0 100644 --- a/doc/mouse.md +++ b/doc/mouse.md @@ -18,6 +18,14 @@ Note that on some devices, an additional option must be enabled in developer options for this mouse mode to work. See [prerequisites](/README.md#prerequisites). +### Mouse hover + +By default, mouse hover (mouse motion without any clicks) events are forwarded +to the device. This can be disabled with: + +``` +scrcpy --no-mouse-hover +``` ## Physical mouse simulation