From 0268d71d01f99fa9446152cbef40d9cfceb00ace Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 21 Jan 2018 11:48:16 +0100 Subject: [PATCH] plymouth: keyboard: Add a last_event argument to on_input and on_backspace handlers On machines with a slow CPU (Atom) and a highres screen drawing the diskcrypt dialog may take longer then the keyrepeat speed, this leads to a long delay before showing keypresses when doing the following: 1) Type long password 2) Realize it is wrong, press + hold backspace the key-repeat will now generate backspace key presses faster then we process them as main.c does an update_display for each press 3) Users releases backspace when we've processed input-length backspace key-presses, but since we were drawing slower then key-presses were coming in many more backspace keypresses are in the keyboard buffer 4) User types first character of the right password, this shows up up to a couple of seconds later because first we are still processing all the queued up backspace presses and doing a redraw for each. Note a similar problem happens when typing the diskcrypt password really slow. This commit fixes this by letting the keyboard_input and backspace handlers now if this is the last_event from the buffer, and when it is not then they can skip the redraw. --- src/libply-splash-core/ply-keyboard.c | 27 ++++++++++++++++----------- src/libply-splash-core/ply-keyboard.h | 6 ++++-- src/main.c | 20 ++++++++++++++------ src/plugins/splash/script/plugin.c | 6 ++++-- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/libply-splash-core/ply-keyboard.c b/src/libply-splash-core/ply-keyboard.c index 80f7694..0f90dda 100644 --- a/src/libply-splash-core/ply-keyboard.c +++ b/src/libply-splash-core/ply-keyboard.c @@ -146,7 +146,7 @@ ply_keyboard_new_for_renderer (ply_renderer_t *renderer) } static void -process_backspace (ply_keyboard_t *keyboard) +process_backspace (ply_keyboard_t *keyboard, bool line_erase, bool last_event) { size_t bytes_to_remove; ssize_t previous_character_size; @@ -168,29 +168,33 @@ process_backspace (ply_keyboard_t *keyboard) if (bytes_to_remove <= size) ply_buffer_remove_bytes_at_end (keyboard->line_buffer, bytes_to_remove); + if (line_erase && bytes_to_remove != size) + last_event = false; + for (node = ply_list_get_first_node (keyboard->backspace_handler_list); node; node = ply_list_get_next_node (keyboard->backspace_handler_list, node)) { ply_keyboard_closure_t *closure = ply_list_node_get_data (node); ply_keyboard_backspace_handler_t backspace_handler = (ply_keyboard_backspace_handler_t) closure->function; - backspace_handler (closure->user_data); + backspace_handler (closure->user_data, last_event); } } static void -process_line_erase (ply_keyboard_t *keyboard) +process_line_erase (ply_keyboard_t *keyboard, bool last_event) { size_t size; while ((size = ply_buffer_get_size (keyboard->line_buffer)) > 0) { - process_backspace (keyboard); + process_backspace (keyboard, true, last_event); } } static void process_keyboard_input (ply_keyboard_t *keyboard, const char *keyboard_input, - size_t character_size) + size_t character_size, + bool last_event) { wchar_t key; ply_list_node_t *node; @@ -200,7 +204,7 @@ process_keyboard_input (ply_keyboard_t *keyboard, case KEY_CTRL_U: case KEY_CTRL_W: ply_trace ("erase line!"); - process_line_erase (keyboard); + process_line_erase (keyboard, last_event); return; case KEY_CTRL_V: @@ -223,7 +227,7 @@ process_keyboard_input (ply_keyboard_t *keyboard, case KEY_BACKSPACE: ply_trace ("backspace key!"); - process_backspace (keyboard); + process_backspace (keyboard, false, last_event); return; case KEY_RETURN: @@ -252,7 +256,8 @@ process_keyboard_input (ply_keyboard_t *keyboard, (ply_keyboard_input_handler_t) closure->function; keyboard_input_handler (closure->user_data, - keyboard_input, character_size); + keyboard_input, character_size, + last_event); } } @@ -284,11 +289,11 @@ on_key_event (ply_keyboard_t *keyboard, } keyboard_input = strndup (bytes + i, character_size); - - process_keyboard_input (keyboard, keyboard_input, character_size); - i += character_size; + process_keyboard_input (keyboard, keyboard_input, character_size, + i == size); + free (keyboard_input); } diff --git a/src/libply-splash-core/ply-keyboard.h b/src/libply-splash-core/ply-keyboard.h index 6147cc7..b1c723d 100644 --- a/src/libply-splash-core/ply-keyboard.h +++ b/src/libply-splash-core/ply-keyboard.h @@ -34,9 +34,11 @@ typedef struct _ply_keyboard ply_keyboard_t; typedef void (*ply_keyboard_input_handler_t) (void *user_data, const char *keyboard_input, - size_t character_size); + size_t character_size, + bool last_event); -typedef void (*ply_keyboard_backspace_handler_t) (void *user_data); +typedef void (*ply_keyboard_backspace_handler_t) (void *user_data, + bool last_event); typedef void (*ply_keyboard_escape_handler_t) (void *user_data); diff --git a/src/main.c b/src/main.c index 08c7fe1..7597a91 100644 --- a/src/main.c +++ b/src/main.c @@ -162,8 +162,10 @@ static void on_enter (state_t *state, const char *line); static void on_keyboard_input (state_t *state, const char *keyboard_input, - size_t character_size); -static void on_backspace (state_t *state); + size_t character_size, + bool last_event); +static void on_backspace (state_t *state, + bool last_event); static void on_quit (state_t *state, bool retain_splash, ply_trigger_t *quit_trigger); @@ -1526,7 +1528,8 @@ on_escape_pressed (state_t *state) static void on_keyboard_input (state_t *state, const char *keyboard_input, - size_t character_size) + size_t character_size, + bool last_event) { ply_list_node_t *node; @@ -1541,7 +1544,9 @@ on_keyboard_input (state_t *state, } else { ply_buffer_append_bytes (state->entry_buffer, keyboard_input, character_size); } - update_display (state); + /* Do not update the display if more events are queued */ + if (last_event) + update_display (state); } else { for (node = ply_list_get_first_node (state->keystroke_triggers); node; node = ply_list_get_next_node (state->keystroke_triggers, node)) { @@ -1558,7 +1563,8 @@ on_keyboard_input (state_t *state, } static void -on_backspace (state_t *state) +on_backspace (state_t *state, + bool last_event) { ssize_t bytes_to_remove; ssize_t previous_character_size; @@ -1580,7 +1586,9 @@ on_backspace (state_t *state) } ply_buffer_remove_bytes_at_end (state->entry_buffer, bytes_to_remove); - update_display (state); + /* Do not update the display if more events are queued */ + if (last_event) + update_display (state); } static void diff --git a/src/plugins/splash/script/plugin.c b/src/plugins/splash/script/plugin.c index 6484766..6a5ca4e 100644 --- a/src/plugins/splash/script/plugin.c +++ b/src/plugins/splash/script/plugin.c @@ -103,7 +103,8 @@ static void stop_animation (ply_boot_splash_plugin_t *plugin); ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void); static void on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, - size_t character_size); + size_t character_size, + bool last_event); static void pause_displays (ply_boot_splash_plugin_t *plugin) @@ -360,7 +361,8 @@ detach_from_event_loop (ply_boot_splash_plugin_t *plugin) static void on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, - size_t character_size) + size_t character_size, + bool last_event) { char keyboard_string[character_size + 1]; -- 2.14.3