Skip to content

Commit

Permalink
Add --prefer-text option
Browse files Browse the repository at this point in the history
Expose an option to configure how key/text events are forwarded to the
Android device.

Enabling the option avoids issues when combining multiple keys to enter
special characters, but breaks the expected behavior of alpha keys in
games (typically WASD).

Fixes <#650>
  • Loading branch information
rom1v committed Nov 7, 2019
1 parent ff061b4 commit c916af0
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 10 deletions.
7 changes: 7 additions & 0 deletions app/scrcpy.1
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ Set the TCP port the client listens on.

Default is 27183.

.TP
.B \-\-prefer\-text
Inject alpha characters and space as text events instead of key events.

This avoids issues when combining multiple keys to enter special characters,
but breaks the expected behavior of alpha keys in games (typically WASD).

.TP
.BI "\-\-push\-target " path
Set the target directory for pushing files to the device by drag & drop. It is passed as\-is to "adb push".
Expand Down
9 changes: 8 additions & 1 deletion app/src/event_converter.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ convert_meta_state(SDL_Keymod mod) {
}

bool
convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod) {
convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod,
bool prefer_text) {
switch (from) {
MAP(SDLK_RETURN, AKEYCODE_ENTER);
MAP(SDLK_KP_ENTER, AKEYCODE_NUMPAD_ENTER);
Expand All @@ -92,6 +93,12 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod) {
MAP(SDLK_DOWN, AKEYCODE_DPAD_DOWN);
MAP(SDLK_UP, AKEYCODE_DPAD_UP);
}

if (prefer_text) {
// do not forward alpha and space key events
return false;
}

if (mod & (KMOD_LALT | KMOD_RALT | KMOD_LGUI | KMOD_RGUI)) {
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion app/src/event_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ enum android_metastate
convert_meta_state(SDL_Keymod mod);

bool
convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod);
convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod,
bool prefer_text);

enum android_motionevent_buttons
convert_mouse_buttons(uint32_t state);
Expand Down
21 changes: 13 additions & 8 deletions app/src/input_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,15 @@ clipboard_paste(struct controller *controller) {
void
input_manager_process_text_input(struct input_manager *im,
const SDL_TextInputEvent *event) {
char c = event->text[0];
if (isalpha(c) || c == ' ') {
SDL_assert(event->text[1] == '\0');
// letters and space are handled as raw key event
return;
if (!im->prefer_text) {
char c = event->text[0];
if (isalpha(c) || c == ' ') {
SDL_assert(event->text[1] == '\0');
// letters and space are handled as raw key event
return;
}
}

struct control_msg msg;
msg.type = CONTROL_MSG_TYPE_INJECT_TEXT;
msg.inject_text.text = SDL_strdup(event->text);
Expand All @@ -234,15 +237,17 @@ input_manager_process_text_input(struct input_manager *im,
}

static bool
convert_input_key(const SDL_KeyboardEvent *from, struct control_msg *to) {
convert_input_key(const SDL_KeyboardEvent *from, struct control_msg *to,
bool prefer_text) {
to->type = CONTROL_MSG_TYPE_INJECT_KEYCODE;

if (!convert_keycode_action(from->type, &to->inject_keycode.action)) {
return false;
}

uint16_t mod = from->keysym.mod;
if (!convert_keycode(from->keysym.sym, &to->inject_keycode.keycode, mod)) {
if (!convert_keycode(from->keysym.sym, &to->inject_keycode.keycode, mod,
prefer_text)) {
return false;
}

Expand Down Expand Up @@ -393,7 +398,7 @@ input_manager_process_key(struct input_manager *im,
}

struct control_msg msg;
if (convert_input_key(event, &msg)) {
if (convert_input_key(event, &msg, im->prefer_text)) {
if (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'inject keycode'");
}
Expand Down
1 change: 1 addition & 0 deletions app/src/input_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct input_manager {
struct controller *controller;
struct video_buffer *video_buffer;
struct screen *screen;
bool prefer_text;
};

void
Expand Down
12 changes: 12 additions & 0 deletions app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ static void usage(const char *arg0) {
" Set the TCP port the client listens on.\n"
" Default is %d.\n"
"\n"
" --prefer-text\n"
" Inject alpha characters and space as text events instead of\n"
" key events.\n"
" This avoids issues when combining multiple keys to enter a\n"
" special character, but breaks the expected behavior of alpha\n"
" keys in games (typically WASD).\n"
"\n"
" --push-target path\n"
" Set the target directory for pushing files to the device by\n"
" drag & drop. It is passed as-is to \"adb push\".\n"
Expand Down Expand Up @@ -300,6 +307,7 @@ guess_record_format(const char *filename) {
#define OPT_ALWAYS_ON_TOP 1003
#define OPT_CROP 1004
#define OPT_RECORD_FORMAT 1005
#define OPT_PREFER_TEXT 1006

static bool
parse_args(struct args *args, int argc, char *argv[]) {
Expand All @@ -321,6 +329,7 @@ parse_args(struct args *args, int argc, char *argv[]) {
{"serial", required_argument, NULL, 's'},
{"show-touches", no_argument, NULL, 't'},
{"turn-screen-off", no_argument, NULL, 'S'},
{"prefer-text", no_argument, NULL, OPT_PREFER_TEXT},
{"version", no_argument, NULL, 'v'},
{"window-title", required_argument, NULL,
OPT_WINDOW_TITLE},
Expand Down Expand Up @@ -404,6 +413,9 @@ parse_args(struct args *args, int argc, char *argv[]) {
case OPT_PUSH_TARGET:
opts->push_target = optarg;
break;
case OPT_PREFER_TEXT:
opts->prefer_text = true;
break;
default:
// getopt prints the error message on stderr
return false;
Expand Down
3 changes: 3 additions & 0 deletions app/src/scrcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ static struct input_manager input_manager = {
.controller = &controller,
.video_buffer = &video_buffer,
.screen = &screen,
.prefer_text = false, // initialized later
};

// init SDL and set appropriate hints
Expand Down Expand Up @@ -414,6 +415,8 @@ scrcpy(const struct scrcpy_options *options) {
show_touches_waited = true;
}

input_manager.prefer_text = options->prefer_text;

ret = event_loop(options->display, options->control);
LOGD("quit...");

Expand Down
3 changes: 3 additions & 0 deletions app/src/scrcpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <stdint.h>

#include "config.h"
#include "input_manager.h"
#include "recorder.h"

struct scrcpy_options {
Expand All @@ -24,6 +25,7 @@ struct scrcpy_options {
bool display;
bool turn_screen_off;
bool render_expired_frames;
bool prefer_text;
};

#define SCRCPY_OPTIONS_DEFAULT { \
Expand All @@ -43,6 +45,7 @@ struct scrcpy_options {
.display = true, \
.turn_screen_off = false, \
.render_expired_frames = false, \
.prefer_text = false, \
}

bool
Expand Down

0 comments on commit c916af0

Please sign in to comment.