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.
This commit is contained in:
Kamil Jarosz 2024-05-07 17:03:11 +02:00 committed by Nathan Adams
parent fb2d8222eb
commit ed037214b1
1 changed files with 21 additions and 21 deletions

View File

@ -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);
});