From 3798d85bd1ff117608aaa4e333182ec38a777b22 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 23 Jun 2020 23:57:43 -0700 Subject: [PATCH] GUACAMOLE-518: Count client-side pressed keys independently of server-side keys. --- src/protocols/rdp/keyboard.c | 50 ++++++++++++++++++++---------------- src/protocols/rdp/keyboard.h | 6 +++++ 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/protocols/rdp/keyboard.c b/src/protocols/rdp/keyboard.c index 0f1a49ba..52c125b2 100644 --- a/src/protocols/rdp/keyboard.c +++ b/src/protocols/rdp/keyboard.c @@ -645,9 +645,35 @@ int guac_rdp_keyboard_update_keysym(guac_rdp_keyboard* keyboard, } - /* If key is known, ignoring the key event entirely if state is not - * actually changing */ guac_rdp_key* key = guac_rdp_keyboard_get_key(keyboard, keysym); + + /* Update tracking of client-side keyboard state but only for keys which + * are tracked server-side, as well (to ensure that the key count remains + * correct, even if a user sends extra unbalanced or excessive press and + * release events) */ + if (key != NULL && source == GUAC_RDP_KEY_SOURCE_CLIENT) { + + if (pressed && !key->user_pressed) { + keyboard->user_pressed_keys++; + key->user_pressed = 1; + } + else if (!pressed && key->user_pressed) { + + keyboard->user_pressed_keys--; + key->user_pressed = 0; + + /* Reset RDP server keyboard state (releasing any automatically + * pressed keys) once all keys have been released on the client + * side */ + if (keyboard->user_pressed_keys == 0) + guac_rdp_keyboard_reset(keyboard); + + } + + } + + /* If key is known, ignore the key event entirely if state is not actually + * changing */ if (key != NULL) { if ((!pressed && key->pressed == NULL) || (pressed && key->pressed != NULL)) return 0; @@ -672,26 +698,6 @@ int guac_rdp_keyboard_update_keysym(guac_rdp_keyboard* keyboard, guac_rdp_keyboard_send_missing_key(keyboard, keysym); } - if (source == GUAC_RDP_KEY_SOURCE_CLIENT) { - - /* Update tracking of client-side keyboard state but only for keys - * which are tracked server-side, as well (to ensure that the key count - * remains correct, even if a user sends extra unbalanced or excessive - * press and release events) */ - if (key != NULL) { - if (pressed) - keyboard->user_pressed_keys++; - else - keyboard->user_pressed_keys--; - } - - /* Reset RDP server keyboard state (releasing any automatically pressed - * keys) once all keys have been released on the client side */ - if (keyboard->user_pressed_keys == 0) - guac_rdp_keyboard_reset(keyboard); - - } - return 0; } diff --git a/src/protocols/rdp/keyboard.h b/src/protocols/rdp/keyboard.h index 300cb252..44871ca7 100644 --- a/src/protocols/rdp/keyboard.h +++ b/src/protocols/rdp/keyboard.h @@ -84,6 +84,12 @@ typedef struct guac_rdp_key { */ const guac_rdp_keysym_desc* pressed; + /** + * Whether this key is currently pressed by the user, and is included among + * the total tracked by user_pressed_keys within guac_rdp_keyboard. + */ + int user_pressed; + } guac_rdp_key; /**