Handle repeating keycodes
Initialize "repeat" count on key events. PR #1519 <https://github.com/Genymobile/scrcpy/pull/1519> Refs #1013 <https://github.com/Genymobile/scrcpy/pull/1013> Signed-off-by: Romain Vimont <rom@rom1v.com>
This commit is contained in:
committed by
Romain Vimont
parent
0ba74fbd9a
commit
3c1ed5d86c
@@ -42,8 +42,9 @@ control_msg_serialize(const struct control_msg *msg, unsigned char *buf) {
|
||||
case CONTROL_MSG_TYPE_INJECT_KEYCODE:
|
||||
buf[1] = msg->inject_keycode.action;
|
||||
buffer_write32be(&buf[2], msg->inject_keycode.keycode);
|
||||
buffer_write32be(&buf[6], msg->inject_keycode.metastate);
|
||||
return 10;
|
||||
buffer_write32be(&buf[6], msg->inject_keycode.repeat);
|
||||
buffer_write32be(&buf[10], msg->inject_keycode.metastate);
|
||||
return 14;
|
||||
case CONTROL_MSG_TYPE_INJECT_TEXT: {
|
||||
size_t len =
|
||||
write_string(msg->inject_text.text,
|
||||
|
||||
@@ -44,6 +44,7 @@ struct control_msg {
|
||||
struct {
|
||||
enum android_keyevent_action action;
|
||||
enum android_keycode keycode;
|
||||
uint32_t repeat;
|
||||
enum android_metastate metastate;
|
||||
} inject_keycode;
|
||||
struct {
|
||||
|
||||
@@ -234,7 +234,7 @@ input_manager_process_text_input(struct input_manager *im,
|
||||
|
||||
static bool
|
||||
convert_input_key(const SDL_KeyboardEvent *from, struct control_msg *to,
|
||||
bool prefer_text) {
|
||||
bool prefer_text, uint32_t repeat) {
|
||||
to->type = CONTROL_MSG_TYPE_INJECT_KEYCODE;
|
||||
|
||||
if (!convert_keycode_action(from->type, &to->inject_keycode.action)) {
|
||||
@@ -247,6 +247,7 @@ convert_input_key(const SDL_KeyboardEvent *from, struct control_msg *to,
|
||||
return false;
|
||||
}
|
||||
|
||||
to->inject_keycode.repeat = repeat;
|
||||
to->inject_keycode.metastate = convert_meta_state(mod);
|
||||
|
||||
return true;
|
||||
@@ -411,8 +412,14 @@ input_manager_process_key(struct input_manager *im,
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->repeat) {
|
||||
++im->repeat;
|
||||
} else {
|
||||
im->repeat = 0;
|
||||
}
|
||||
|
||||
struct control_msg msg;
|
||||
if (convert_input_key(event, &msg, im->prefer_text)) {
|
||||
if (convert_input_key(event, &msg, im->prefer_text, im->repeat)) {
|
||||
if (!controller_push_msg(controller, &msg)) {
|
||||
LOGW("Could not request 'inject keycode'");
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@ struct input_manager {
|
||||
struct controller *controller;
|
||||
struct video_buffer *video_buffer;
|
||||
struct screen *screen;
|
||||
|
||||
// SDL reports repeated events as a boolean, but Android expects the actual
|
||||
// number of repetitions. This variable keeps track of the count.
|
||||
unsigned repeat;
|
||||
|
||||
bool prefer_text;
|
||||
};
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ static struct input_manager input_manager = {
|
||||
.controller = &controller,
|
||||
.video_buffer = &video_buffer,
|
||||
.screen = &screen,
|
||||
.repeat = 0,
|
||||
.prefer_text = false, // initialized later
|
||||
};
|
||||
|
||||
|
||||
@@ -9,18 +9,20 @@ static void test_serialize_inject_keycode(void) {
|
||||
.inject_keycode = {
|
||||
.action = AKEY_EVENT_ACTION_UP,
|
||||
.keycode = AKEYCODE_ENTER,
|
||||
.repeat = 5,
|
||||
.metastate = AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON,
|
||||
},
|
||||
};
|
||||
|
||||
unsigned char buf[CONTROL_MSG_MAX_SIZE];
|
||||
int size = control_msg_serialize(&msg, buf);
|
||||
assert(size == 10);
|
||||
assert(size == 14);
|
||||
|
||||
const unsigned char expected[] = {
|
||||
CONTROL_MSG_TYPE_INJECT_KEYCODE,
|
||||
0x01, // AKEY_EVENT_ACTION_UP
|
||||
0x00, 0x00, 0x00, 0x42, // AKEYCODE_ENTER
|
||||
0x00, 0x00, 0x00, 0X05, // repeat
|
||||
0x00, 0x00, 0x00, 0x41, // AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON
|
||||
};
|
||||
assert(!memcmp(buf, expected, sizeof(expected)));
|
||||
|
||||
Reference in New Issue
Block a user