Skip to content

Commit

Permalink
Add option to configure mouse bindings
Browse files Browse the repository at this point in the history
Add a new option --mouse-bind=xxxx.

The argument must be exactly 4 characters, one for each secondary click:

    --mouse-bind=xxxx
                 ^^^^
                 ||||
                 ||| `- 5th click
                 || `-- 4th click
                 | `--- middle click
                  `---- right click

Each character must be one of the following:
 - `+`: forward the click to the device
 - `-`: ignore the click
 - `b`: trigger shortcut BACK (or turn screen on if off)
 - `h`: trigger shortcut HOME
 - `s`: trigger shortcut APP_SWITCH
 - `n`: trigger shortcut "expand notification panel"

This deprecates --forward-all-clicks (use --mouse-bind=++++ instead).

Refs <Genymobile#2258 (comment)>
PR Genymobile#5022 <Genymobile#5022>
  • Loading branch information
rom1v committed Jun 24, 2024
1 parent 40493df commit 035d60c
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 69 deletions.
2 changes: 1 addition & 1 deletion app/data/bash-completion/scrcpy
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ _scrcpy() {
-e --select-tcpip
-f --fullscreen
--force-adb-forward
--forward-all-clicks
-h --help
-K
--keyboard=
Expand All @@ -41,6 +40,7 @@ _scrcpy() {
-M
--max-fps=
--mouse=
--mouse-bind=
-n --no-control
-N --no-playback
--no-audio
Expand Down
2 changes: 1 addition & 1 deletion app/data/zsh-completion/_scrcpy
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ arguments=(
{-e,--select-tcpip}'[Use TCP/IP device]'
{-f,--fullscreen}'[Start in fullscreen]'
'--force-adb-forward[Do not attempt to use \"adb reverse\" to connect to the device]'
'--forward-all-clicks[Forward clicks to device]'
{-h,--help}'[Print the help]'
'-K[Use UHID keyboard (same as --keyboard=uhid)]'
'--keyboard=[Set the keyboard input mode]:mode:(disabled sdk uhid aoa)'
Expand All @@ -47,6 +46,7 @@ arguments=(
'-M[Use UHID mouse (same as --mouse=uhid)]'
'--max-fps=[Limit the frame rate of screen capture]'
'--mouse=[Set the mouse input mode]:mode:(disabled sdk uhid aoa)'
'--mouse-bind=[Configure bindings of secondary clicks]'
{-n,--no-control}'[Disable device control \(mirror the device in read only\)]'
{-N,--no-playback}'[Disable video and audio playback]'
'--no-audio[Disable audio forwarding]'
Expand Down
21 changes: 17 additions & 4 deletions app/scrcpy.1
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,6 @@ Start in fullscreen.
.B \-\-force\-adb\-forward
Do not attempt to use "adb reverse" to connect to the device.

.TP
.B \-\-forward\-all\-clicks
By default, right-click triggers BACK (or POWER on) and middle-click triggers HOME. This option disables these shortcuts and forward the clicks to the device instead.

.TP
.B \-h, \-\-help
Print this help.
Expand Down Expand Up @@ -261,6 +257,23 @@ LAlt, LSuper or RSuper toggle the capture mode, to give control of the mouse bac

Also see \fB\-\-keyboard\fR.

.TP
.BI "\-\-mouse\-bind " xxxx
Configure bindings of secondary clicks.

The argument must be exactly 4 characters, one for each secondary click (in order: right click, middle click, 4th click, 5th click).

Each character must be one of the following:

- '+': forward the click to the device
- '-': ignore the click
- 'b': trigger shortcut BACK (or turn screen on if off)
- 'h': trigger shortcut HOME
- 's': trigger shortcut APP_SWITCH
- 'n': trigger shortcut "expand notification panel"

Default is 'bhsn'.


.TP
.B \-n, \-\-no\-control
Expand Down
88 changes: 84 additions & 4 deletions app/src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ enum {
OPT_HID_KEYBOARD_DEPRECATED,
OPT_HID_MOUSE_DEPRECATED,
OPT_NO_WINDOW,
OPT_MOUSE_BIND,
};

struct sc_option {
Expand Down Expand Up @@ -352,11 +353,9 @@ static const struct sc_option options[] = {
"device.",
},
{
// deprecated
.longopt_id = OPT_FORWARD_ALL_CLICKS,
.longopt = "forward-all-clicks",
.text = "By default, right-click triggers BACK (or POWER on) and "
"middle-click triggers HOME. This option disables these "
"shortcuts and forwards the clicks to the device instead.",
},
{
.shortopt = 'h',
Expand Down Expand Up @@ -490,6 +489,23 @@ static const struct sc_option options[] = {
"control of the mouse back to the computer.\n"
"Also see --keyboard.",
},
{
.longopt_id = OPT_MOUSE_BIND,
.longopt = "mouse-bind",
.argdesc = "xxxx",
.text = "Configure bindings of secondary clicks.\n"
"The argument must be exactly 4 characters, one for each "
"secondary click (in order: right click, middle click, 4th "
"click, 5th click).\n"
"Each character must be one of the following:\n"
" '+': forward the click to the device\n"
" '-': ignore the click\n"
" 'b': trigger shortcut BACK (or turn screen on if off)\n"
" 'h': trigger shortcut HOME\n"
" 's': trigger shortcut APP_SWITCH\n"
" 'n': trigger shortcut \"expand notification panel\"\n"
"Default is 'bhsn'.",
},
{
.shortopt = 'n',
.longopt = "no-control",
Expand Down Expand Up @@ -2043,6 +2059,58 @@ parse_pause_on_exit(const char *s, enum sc_pause_on_exit *pause_on_exit) {

}

static bool
parse_mouse_binding(char c, enum sc_mouse_binding *b) {
switch (c) {
case '+':
*b = SC_MOUSE_BINDING_CLICK;
return true;
case '-':
*b = SC_MOUSE_BINDING_DISABLED;
return true;
case 'b':
*b = SC_MOUSE_BINDING_BACK;
return true;
case 'h':
*b = SC_MOUSE_BINDING_HOME;
return true;
case 's':
*b = SC_MOUSE_BINDING_APP_SWITCH;
return true;
case 'n':
*b = SC_MOUSE_BINDING_EXPAND_NOTIFICATION_PANEL;
return true;
default:
LOGE("Invalid mouse binding: '%c' "
"(expected '+', '-', 'b', 'h', 's' or 'n')", c);
return false;
}
}

static bool
parse_mouse_bindings(const char *s, struct sc_mouse_bindings *mb) {
if (strlen(s) != 4) {
LOGE("Invalid mouse bindings: '%s' (expected exactly 4 characters from "
"{'+', '-', 'b', 'h', 's', 'n'})", s);
return false;
}

if (!parse_mouse_binding(s[0], &mb->right_click)) {
return false;
}
if (!parse_mouse_binding(s[1], &mb->middle_click)) {
return false;
}
if (!parse_mouse_binding(s[2], &mb->click4)) {
return false;
}
if (!parse_mouse_binding(s[3], &mb->click5)) {
return false;
}

return true;
}

static bool
parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
const char *optstring, const struct option *longopts) {
Expand Down Expand Up @@ -2125,6 +2193,11 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
return false;
}
break;
case OPT_MOUSE_BIND:
if (!parse_mouse_bindings(optarg, &opts->mouse_bindings)) {
return false;
}
break;
case OPT_HID_MOUSE_DEPRECATED:
LOGE("--hid-mouse has been removed, use --mouse=aoa or "
"--mouse=uhid instead.");
Expand Down Expand Up @@ -2322,7 +2395,14 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
}
break;
case OPT_FORWARD_ALL_CLICKS:
opts->forward_all_clicks = true;
LOGW("--forward-all-clicks is deprecated, "
"use --mouse-bind=++++ instead.");
opts->mouse_bindings = (struct sc_mouse_bindings) {
.right_click = SC_MOUSE_BINDING_CLICK,
.middle_click = SC_MOUSE_BINDING_CLICK,
.click4 = SC_MOUSE_BINDING_CLICK,
.click5 = SC_MOUSE_BINDING_CLICK,
};
break;
case OPT_LEGACY_PASTE:
opts->legacy_paste = true;
Expand Down
19 changes: 13 additions & 6 deletions app/src/input_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <SDL2/SDL_events.h>

#include "coords.h"
#include "options.h"

/* The representation of input events in scrcpy is very close to the SDL API,
* for simplicity.
Expand Down Expand Up @@ -437,15 +438,21 @@ sc_mouse_button_from_sdl(uint8_t button) {

static inline uint8_t
sc_mouse_buttons_state_from_sdl(uint32_t buttons_state,
bool forward_all_clicks) {
const struct sc_mouse_bindings *mb) {
assert(buttons_state < 0x100); // fits in uint8_t

uint8_t mask = SC_MOUSE_BUTTON_LEFT;
if (forward_all_clicks) {
mask |= SC_MOUSE_BUTTON_RIGHT
| SC_MOUSE_BUTTON_MIDDLE
| SC_MOUSE_BUTTON_X1
| SC_MOUSE_BUTTON_X2;
if (!mb || mb->right_click == SC_MOUSE_BINDING_CLICK) {
mask |= SC_MOUSE_BUTTON_RIGHT;
}
if (!mb || mb->middle_click == SC_MOUSE_BINDING_CLICK) {
mask |= SC_MOUSE_BUTTON_MIDDLE;
}
if (!mb || mb->click4 == SC_MOUSE_BINDING_CLICK) {
mask |= SC_MOUSE_BUTTON_X1;
}
if (!mb || mb->click5 == SC_MOUSE_BINDING_CLICK) {
mask |= SC_MOUSE_BUTTON_X2;
}

return buttons_state & mask;
Expand Down
Loading

0 comments on commit 035d60c

Please sign in to comment.