Shortcuts: a modifier key press is never the key that typed a text

In the web build, pressing Shift and then a letter in one frame sends the Shift press, the
letter's text and then the letter's key press. The text paired with the Shift press as the press
before it, so a key-position shortcut looked up Shift instead of the letter, and a held Shift's
repeated presses dropped the text as a repeat. Modifier key presses now never pair with a text.
This commit is contained in:
dotCooCoo
2026-10-31 18:44:50 +07:00
committed by bflatastic
parent 0127739597
commit d3ea958f8f
2 changed files with 5 additions and 2 deletions
+3 -2
View File
@@ -848,12 +848,13 @@ fn latin(text: &str, physical: Option<Key>) -> String {
/// For each event, the index of the key press that typed it when it is text: the press right
/// before it (egui-winit) unless an earlier text took that press, or else the press right after it
/// (eframe's web build with no text field focused). Each press types at most one text. A text
/// (eframe's web build with no text field focused). Modifier key presses type no text. Each press
/// types at most one text. A text
/// takes the press after it only when every later text in the same run of alternating texts and
/// presses has a press after it too; otherwise the text after that press takes it as the press
/// before it, and this text has none.
fn typing_presses(events: &[egui::Event]) -> Vec<Option<usize>> {
let is_press = |k: usize| matches!(events.get(k), Some(egui::Event::Key { pressed: true, .. }));
let is_press = |k: usize| matches!(events.get(k), Some(egui::Event::Key { key, pressed: true, .. }) if !is_modifier(*key));
let is_text = |k: usize| matches!(events.get(k), Some(egui::Event::Text(_)));
// Whether the run of alternating texts and presses that starts with the text at `j` ends
// with a press.
+2
View File
@@ -1491,6 +1491,8 @@ fn one_key_shortcuts_use_the_key_of_the_same_keystroke_in_either_order() {
assert_eq!(typing_presses(&[text("p"), press(Key::V), text("м")]), [None, None, Some(1)]);
frame(&mut app, vec![text("p"), press(Key::V), text("м")]);
assert_eq!(app.session.tool_id(), "selection", "the text after the key uses it");
// A modifier key press does not type text, so the web text after Shift uses the key after it.
assert_eq!(typing_presses(&[press(Key::ShiftLeft), text("З"), press(Key::P)]), [None, Some(2), None]);
let names = |events: &[egui::Event]| -> Vec<String> {
shortcut_presses(events, Modifiers::NONE).into_iter().filter_map(|(n, _)| n.into_iter().next()).collect()
};