Skip to content

Commit bd56d81

Browse files
committed
Add --raw-key-events
This option allows to inject all input keys as key events, and ignore text events. Fixes Genymobile#2816 <Genymobile#2816> PR Genymobile#2831 <Genymobile#2831>
1 parent 5e918ac commit bd56d81

File tree

5 files changed

+93
-1
lines changed

5 files changed

+93
-1
lines changed

README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,13 @@ scrcpy --prefer-text
833833

834834
(but this will break keyboard behavior in games)
835835

836-
This option has no effect on HID keyboard (all key events are sent as
836+
On the contrary, you could force to always inject raw key events:
837+
838+
```bash
839+
scrcpy --raw-key-events
840+
```
841+
842+
These options have no effect on HID keyboard (all key events are sent as
837843
scancodes in this mode).
838844

839845
[textevents]: https://blog.rom1v.com/2018/03/introducing-scrcpy/#handle-text-input

app/scrcpy.1

+4
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ Set the target directory for pushing files to the device by drag & drop. It is p
165165

166166
Default is "/sdcard/Download/".
167167

168+
.TP
169+
.B \-\-raw\-key\-events
170+
Inject key events for all input keys, and ignore text events.
171+
168172
.TP
169173
.BI "\-r, \-\-record " file
170174
Record screen to

app/src/cli.c

+17
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#define OPT_TUNNEL_PORT 1031
5252
#define OPT_NO_CLIPBOARD_AUTOSYNC 1032
5353
#define OPT_TCPIP 1033
54+
#define OPT_RAW_KEY_EVENTS 1034
5455

5556
struct sc_option {
5657
char shortopt;
@@ -282,6 +283,11 @@ static const struct sc_option options[] = {
282283
"drag & drop. It is passed as is to \"adb push\".\n"
283284
"Default is \"/sdcard/Download/\".",
284285
},
286+
{
287+
.longopt_id = OPT_RAW_KEY_EVENTS,
288+
.longopt = "raw-key-events",
289+
.text = "Inject key events for all input keys, and ignore text events."
290+
},
285291
{
286292
.shortopt = 'r',
287293
.longopt = "record",
@@ -1350,8 +1356,19 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
13501356
opts->push_target = optarg;
13511357
break;
13521358
case OPT_PREFER_TEXT:
1359+
if (opts->key_inject_mode != SC_KEY_INJECT_MODE_MIXED) {
1360+
LOGE("--prefer-text is incompatible with --raw-key-events");
1361+
return false;
1362+
}
13531363
opts->key_inject_mode = SC_KEY_INJECT_MODE_TEXT;
13541364
break;
1365+
case OPT_RAW_KEY_EVENTS:
1366+
if (opts->key_inject_mode != SC_KEY_INJECT_MODE_MIXED) {
1367+
LOGE("--prefer-text is incompatible with --raw-key-events");
1368+
return false;
1369+
}
1370+
opts->key_inject_mode = SC_KEY_INJECT_MODE_RAW;
1371+
break;
13551372
case OPT_ROTATION:
13561373
if (!parse_rotation(optarg, &opts->rotation)) {
13571374
return false;

app/src/keyboard_inject.c

+62
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,55 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod,
101101
{SDLK_SPACE, AKEYCODE_SPACE},
102102
};
103103

104+
// Numbers and punctuation keys.
105+
// Used in raw mode only.
106+
static const struct sc_intmap_entry numbers_punct_keys[] = {
107+
{SDLK_HASH, AKEYCODE_POUND},
108+
{SDLK_PERCENT, AKEYCODE_PERIOD},
109+
{SDLK_QUOTE, AKEYCODE_APOSTROPHE},
110+
{SDLK_ASTERISK, AKEYCODE_STAR},
111+
{SDLK_PLUS, AKEYCODE_PLUS},
112+
{SDLK_COMMA, AKEYCODE_COMMA},
113+
{SDLK_MINUS, AKEYCODE_MINUS},
114+
{SDLK_PERIOD, AKEYCODE_PERIOD},
115+
{SDLK_SLASH, AKEYCODE_SLASH},
116+
{SDLK_0, AKEYCODE_0},
117+
{SDLK_1, AKEYCODE_1},
118+
{SDLK_2, AKEYCODE_2},
119+
{SDLK_3, AKEYCODE_3},
120+
{SDLK_4, AKEYCODE_4},
121+
{SDLK_5, AKEYCODE_5},
122+
{SDLK_6, AKEYCODE_6},
123+
{SDLK_7, AKEYCODE_7},
124+
{SDLK_8, AKEYCODE_8},
125+
{SDLK_9, AKEYCODE_9},
126+
{SDLK_SEMICOLON, AKEYCODE_SEMICOLON},
127+
{SDLK_EQUALS, AKEYCODE_EQUALS},
128+
{SDLK_AT, AKEYCODE_AT},
129+
{SDLK_LEFTBRACKET, AKEYCODE_LEFT_BRACKET},
130+
{SDLK_BACKSLASH, AKEYCODE_BACKSLASH},
131+
{SDLK_RIGHTBRACKET, AKEYCODE_RIGHT_BRACKET},
132+
{SDLK_BACKQUOTE, AKEYCODE_GRAVE},
133+
{SDLK_KP_1, AKEYCODE_NUMPAD_1},
134+
{SDLK_KP_2, AKEYCODE_NUMPAD_2},
135+
{SDLK_KP_3, AKEYCODE_NUMPAD_3},
136+
{SDLK_KP_4, AKEYCODE_NUMPAD_4},
137+
{SDLK_KP_5, AKEYCODE_NUMPAD_5},
138+
{SDLK_KP_6, AKEYCODE_NUMPAD_6},
139+
{SDLK_KP_7, AKEYCODE_NUMPAD_7},
140+
{SDLK_KP_8, AKEYCODE_NUMPAD_8},
141+
{SDLK_KP_9, AKEYCODE_NUMPAD_9},
142+
{SDLK_KP_0, AKEYCODE_NUMPAD_0},
143+
{SDLK_KP_DIVIDE, AKEYCODE_NUMPAD_DIVIDE},
144+
{SDLK_KP_MULTIPLY, AKEYCODE_NUMPAD_MULTIPLY},
145+
{SDLK_KP_MINUS, AKEYCODE_NUMPAD_SUBTRACT},
146+
{SDLK_KP_PLUS, AKEYCODE_NUMPAD_ADD},
147+
{SDLK_KP_PERIOD, AKEYCODE_NUMPAD_DOT},
148+
{SDLK_KP_EQUALS, AKEYCODE_NUMPAD_EQUALS},
149+
{SDLK_KP_LEFTPAREN, AKEYCODE_NUMPAD_LEFT_PAREN},
150+
{SDLK_KP_RIGHTPAREN, AKEYCODE_NUMPAD_RIGHT_PAREN},
151+
};
152+
104153
const struct sc_intmap_entry *entry =
105154
SC_INTMAP_FIND_ENTRY(special_keys, from);
106155
if (entry) {
@@ -134,6 +183,14 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod,
134183
return true;
135184
}
136185

186+
if (key_inject_mode == SC_KEY_INJECT_MODE_RAW) {
187+
entry = SC_INTMAP_FIND_ENTRY(numbers_punct_keys, from);
188+
if (entry) {
189+
*to = entry->value;
190+
return true;
191+
}
192+
}
193+
137194
return false;
138195
}
139196

@@ -251,6 +308,11 @@ sc_key_processor_process_text(struct sc_key_processor *kp,
251308
const SDL_TextInputEvent *event) {
252309
struct sc_keyboard_inject *ki = DOWNCAST(kp);
253310

311+
if (ki->key_inject_mode == SC_KEY_INJECT_MODE_RAW) {
312+
// Never inject text events
313+
return;
314+
}
315+
254316
if (ki->key_inject_mode == SC_KEY_INJECT_MODE_MIXED) {
255317
char c = event->text[0];
256318
if (isalpha(c) || c == ' ') {

app/src/options.h

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ enum sc_key_inject_mode {
4747
// Inject special keys as key events.
4848
// Inject letters and space, numbers and punctuation as text events.
4949
SC_KEY_INJECT_MODE_TEXT,
50+
51+
// Inject everything as key events.
52+
SC_KEY_INJECT_MODE_RAW,
5053
};
5154

5255
#define SC_MAX_SHORTCUT_MODS 8

0 commit comments

Comments
 (0)