Add --raw-key-events
This option allows to inject all input keys as key events, and ignore text events. Fixes #2816 <https://github.com/Genymobile/scrcpy/issues/2816> PR #2831 <https://github.com/Genymobile/scrcpy/pull/2831>
This commit is contained in:
parent
5e918ac0c3
commit
bd56d81f72
5 changed files with 93 additions and 1 deletions
|
@ -833,7 +833,13 @@ scrcpy --prefer-text
|
||||||
|
|
||||||
(but this will break keyboard behavior in games)
|
(but this will break keyboard behavior in games)
|
||||||
|
|
||||||
This option has no effect on HID keyboard (all key events are sent as
|
On the contrary, you could force to always inject raw key events:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scrcpy --raw-key-events
|
||||||
|
```
|
||||||
|
|
||||||
|
These options have no effect on HID keyboard (all key events are sent as
|
||||||
scancodes in this mode).
|
scancodes in this mode).
|
||||||
|
|
||||||
[textevents]: https://blog.rom1v.com/2018/03/introducing-scrcpy/#handle-text-input
|
[textevents]: https://blog.rom1v.com/2018/03/introducing-scrcpy/#handle-text-input
|
||||||
|
|
|
@ -165,6 +165,10 @@ Set the target directory for pushing files to the device by drag & drop. It is p
|
||||||
|
|
||||||
Default is "/sdcard/Download/".
|
Default is "/sdcard/Download/".
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-\-raw\-key\-events
|
||||||
|
Inject key events for all input keys, and ignore text events.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI "\-r, \-\-record " file
|
.BI "\-r, \-\-record " file
|
||||||
Record screen to
|
Record screen to
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#define OPT_TUNNEL_PORT 1031
|
#define OPT_TUNNEL_PORT 1031
|
||||||
#define OPT_NO_CLIPBOARD_AUTOSYNC 1032
|
#define OPT_NO_CLIPBOARD_AUTOSYNC 1032
|
||||||
#define OPT_TCPIP 1033
|
#define OPT_TCPIP 1033
|
||||||
|
#define OPT_RAW_KEY_EVENTS 1034
|
||||||
|
|
||||||
struct sc_option {
|
struct sc_option {
|
||||||
char shortopt;
|
char shortopt;
|
||||||
|
@ -282,6 +283,11 @@ static const struct sc_option options[] = {
|
||||||
"drag & drop. It is passed as is to \"adb push\".\n"
|
"drag & drop. It is passed as is to \"adb push\".\n"
|
||||||
"Default is \"/sdcard/Download/\".",
|
"Default is \"/sdcard/Download/\".",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.longopt_id = OPT_RAW_KEY_EVENTS,
|
||||||
|
.longopt = "raw-key-events",
|
||||||
|
.text = "Inject key events for all input keys, and ignore text events."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.shortopt = 'r',
|
.shortopt = 'r',
|
||||||
.longopt = "record",
|
.longopt = "record",
|
||||||
|
@ -1350,8 +1356,19 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
||||||
opts->push_target = optarg;
|
opts->push_target = optarg;
|
||||||
break;
|
break;
|
||||||
case OPT_PREFER_TEXT:
|
case OPT_PREFER_TEXT:
|
||||||
|
if (opts->key_inject_mode != SC_KEY_INJECT_MODE_MIXED) {
|
||||||
|
LOGE("--prefer-text is incompatible with --raw-key-events");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
opts->key_inject_mode = SC_KEY_INJECT_MODE_TEXT;
|
opts->key_inject_mode = SC_KEY_INJECT_MODE_TEXT;
|
||||||
break;
|
break;
|
||||||
|
case OPT_RAW_KEY_EVENTS:
|
||||||
|
if (opts->key_inject_mode != SC_KEY_INJECT_MODE_MIXED) {
|
||||||
|
LOGE("--prefer-text is incompatible with --raw-key-events");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
opts->key_inject_mode = SC_KEY_INJECT_MODE_RAW;
|
||||||
|
break;
|
||||||
case OPT_ROTATION:
|
case OPT_ROTATION:
|
||||||
if (!parse_rotation(optarg, &opts->rotation)) {
|
if (!parse_rotation(optarg, &opts->rotation)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -101,6 +101,55 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod,
|
||||||
{SDLK_SPACE, AKEYCODE_SPACE},
|
{SDLK_SPACE, AKEYCODE_SPACE},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Numbers and punctuation keys.
|
||||||
|
// Used in raw mode only.
|
||||||
|
static const struct sc_intmap_entry numbers_punct_keys[] = {
|
||||||
|
{SDLK_HASH, AKEYCODE_POUND},
|
||||||
|
{SDLK_PERCENT, AKEYCODE_PERIOD},
|
||||||
|
{SDLK_QUOTE, AKEYCODE_APOSTROPHE},
|
||||||
|
{SDLK_ASTERISK, AKEYCODE_STAR},
|
||||||
|
{SDLK_PLUS, AKEYCODE_PLUS},
|
||||||
|
{SDLK_COMMA, AKEYCODE_COMMA},
|
||||||
|
{SDLK_MINUS, AKEYCODE_MINUS},
|
||||||
|
{SDLK_PERIOD, AKEYCODE_PERIOD},
|
||||||
|
{SDLK_SLASH, AKEYCODE_SLASH},
|
||||||
|
{SDLK_0, AKEYCODE_0},
|
||||||
|
{SDLK_1, AKEYCODE_1},
|
||||||
|
{SDLK_2, AKEYCODE_2},
|
||||||
|
{SDLK_3, AKEYCODE_3},
|
||||||
|
{SDLK_4, AKEYCODE_4},
|
||||||
|
{SDLK_5, AKEYCODE_5},
|
||||||
|
{SDLK_6, AKEYCODE_6},
|
||||||
|
{SDLK_7, AKEYCODE_7},
|
||||||
|
{SDLK_8, AKEYCODE_8},
|
||||||
|
{SDLK_9, AKEYCODE_9},
|
||||||
|
{SDLK_SEMICOLON, AKEYCODE_SEMICOLON},
|
||||||
|
{SDLK_EQUALS, AKEYCODE_EQUALS},
|
||||||
|
{SDLK_AT, AKEYCODE_AT},
|
||||||
|
{SDLK_LEFTBRACKET, AKEYCODE_LEFT_BRACKET},
|
||||||
|
{SDLK_BACKSLASH, AKEYCODE_BACKSLASH},
|
||||||
|
{SDLK_RIGHTBRACKET, AKEYCODE_RIGHT_BRACKET},
|
||||||
|
{SDLK_BACKQUOTE, AKEYCODE_GRAVE},
|
||||||
|
{SDLK_KP_1, AKEYCODE_NUMPAD_1},
|
||||||
|
{SDLK_KP_2, AKEYCODE_NUMPAD_2},
|
||||||
|
{SDLK_KP_3, AKEYCODE_NUMPAD_3},
|
||||||
|
{SDLK_KP_4, AKEYCODE_NUMPAD_4},
|
||||||
|
{SDLK_KP_5, AKEYCODE_NUMPAD_5},
|
||||||
|
{SDLK_KP_6, AKEYCODE_NUMPAD_6},
|
||||||
|
{SDLK_KP_7, AKEYCODE_NUMPAD_7},
|
||||||
|
{SDLK_KP_8, AKEYCODE_NUMPAD_8},
|
||||||
|
{SDLK_KP_9, AKEYCODE_NUMPAD_9},
|
||||||
|
{SDLK_KP_0, AKEYCODE_NUMPAD_0},
|
||||||
|
{SDLK_KP_DIVIDE, AKEYCODE_NUMPAD_DIVIDE},
|
||||||
|
{SDLK_KP_MULTIPLY, AKEYCODE_NUMPAD_MULTIPLY},
|
||||||
|
{SDLK_KP_MINUS, AKEYCODE_NUMPAD_SUBTRACT},
|
||||||
|
{SDLK_KP_PLUS, AKEYCODE_NUMPAD_ADD},
|
||||||
|
{SDLK_KP_PERIOD, AKEYCODE_NUMPAD_DOT},
|
||||||
|
{SDLK_KP_EQUALS, AKEYCODE_NUMPAD_EQUALS},
|
||||||
|
{SDLK_KP_LEFTPAREN, AKEYCODE_NUMPAD_LEFT_PAREN},
|
||||||
|
{SDLK_KP_RIGHTPAREN, AKEYCODE_NUMPAD_RIGHT_PAREN},
|
||||||
|
};
|
||||||
|
|
||||||
const struct sc_intmap_entry *entry =
|
const struct sc_intmap_entry *entry =
|
||||||
SC_INTMAP_FIND_ENTRY(special_keys, from);
|
SC_INTMAP_FIND_ENTRY(special_keys, from);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
|
@ -134,6 +183,14 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key_inject_mode == SC_KEY_INJECT_MODE_RAW) {
|
||||||
|
entry = SC_INTMAP_FIND_ENTRY(numbers_punct_keys, from);
|
||||||
|
if (entry) {
|
||||||
|
*to = entry->value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,6 +308,11 @@ sc_key_processor_process_text(struct sc_key_processor *kp,
|
||||||
const SDL_TextInputEvent *event) {
|
const SDL_TextInputEvent *event) {
|
||||||
struct sc_keyboard_inject *ki = DOWNCAST(kp);
|
struct sc_keyboard_inject *ki = DOWNCAST(kp);
|
||||||
|
|
||||||
|
if (ki->key_inject_mode == SC_KEY_INJECT_MODE_RAW) {
|
||||||
|
// Never inject text events
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ki->key_inject_mode == SC_KEY_INJECT_MODE_MIXED) {
|
if (ki->key_inject_mode == SC_KEY_INJECT_MODE_MIXED) {
|
||||||
char c = event->text[0];
|
char c = event->text[0];
|
||||||
if (isalpha(c) || c == ' ') {
|
if (isalpha(c) || c == ' ') {
|
||||||
|
|
|
@ -47,6 +47,9 @@ enum sc_key_inject_mode {
|
||||||
// Inject special keys as key events.
|
// Inject special keys as key events.
|
||||||
// Inject letters and space, numbers and punctuation as text events.
|
// Inject letters and space, numbers and punctuation as text events.
|
||||||
SC_KEY_INJECT_MODE_TEXT,
|
SC_KEY_INJECT_MODE_TEXT,
|
||||||
|
|
||||||
|
// Inject everything as key events.
|
||||||
|
SC_KEY_INJECT_MODE_RAW,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SC_MAX_SHORTCUT_MODS 8
|
#define SC_MAX_SHORTCUT_MODS 8
|
||||||
|
|
Loading…
Reference in a new issue