From ed037214b13a8a09a7c99e0a847a31448ba68205 Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Tue, 7 May 2024 17:03:11 +0200 Subject: [PATCH] core: Always fire KeyPress after KeyDown for buttons Button events are actually handled twofold: 1. KeyPress for printable characters is handled on TextInput, 2. KeyPress for special characters (e.g. enter, arrows) is handled on KeyDown. Before this patch, KeyPress was fired too early, so that for special characters (2) it fired BEFORE KeyDown. This was not a problem for printable characters, as they fired on TextInput, which always fired separately after KeyDown. This patch ensures that KeyPress is fired always in the proper order. --- core/src/player.rs | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/core/src/player.rs b/core/src/player.rs index 8ac4f03a9..7c347a948 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -974,7 +974,6 @@ impl Player { } self.mutate_with_update_context(|context| { - // Propagate button events. let button_event = match event { // ASCII characters convert directly to keyPress button events. PlayerEvent::TextInput { codepoint } @@ -996,12 +995,6 @@ impl Player { _ => None, }; - let key_press_handled = if let Some(button_event) = button_event { - context.stage.handle_clip_event(context, button_event) == ClipEventResult::Handled - } else { - false - }; - if let PlayerEvent::KeyDown { key_code, key_char } | PlayerEvent::KeyUp { key_code, key_char } = event { @@ -1058,20 +1051,6 @@ impl Player { } } - // keyPress events take precedence over text input. - if !key_press_handled { - if let PlayerEvent::TextInput { codepoint } = event { - if let Some(text) = context.focus_tracker.get_as_edit_text() { - text.text_input(codepoint, context); - } - } - if let PlayerEvent::TextControl { code } = event { - if let Some(text) = context.focus_tracker.get_as_edit_text() { - text.text_control_input(code, context); - } - } - } - // Propagate clip events. let (clip_event, listener) = match event { PlayerEvent::KeyDown { .. } => { @@ -1125,6 +1104,27 @@ impl Player { } } + // Propagate button events. + // It has to be done after propagating the clip event, + // so that KeyPress is always fired after KeyDown. + let key_press_handled = if let Some(button_event) = button_event { + context.stage.handle_clip_event(context, button_event) == ClipEventResult::Handled + } else { + false + }; + + // KeyPress events take precedence over text input. + if !key_press_handled { + if let Some(text) = context.focus_tracker.get_as_edit_text() { + if let PlayerEvent::TextInput { codepoint } = event { + text.text_input(codepoint, context); + } + if let PlayerEvent::TextControl { code } = event { + text.text_control_input(code, context); + } + } + } + Self::run_actions(context); });