diff --git a/crates/ui-egui/src/shortcuts.rs b/crates/ui-egui/src/shortcuts.rs index 8425456b9..cb66d71c1 100644 --- a/crates/ui-egui/src/shortcuts.rs +++ b/crates/ui-egui/src/shortcuts.rs @@ -731,8 +731,8 @@ fn dispatch(app: &mut VectorcraftApp, ctx: &egui::Context, accept: impl FnMut(&H let mirror = crate::shortcut_editor::current(); let dispatcher = &mut app.dispatcher; ctx.input_mut(|i| { - // Shift+Comma and Shift+Period follow their key positions when no chord for the - // logical press is bound. An explicit shifted logical binding takes precedence. + // An explicit shifted logical binding takes precedence. Otherwise, Shift+Comma and + // Shift+Period follow their key positions when no chord for the press is bound. for e in &mut i.events { let input = craft_keymap::KeyInput::from_egui(e, crate::keymap::platform()); if let egui::Event::Key { key, physical_key: Some(physical), modifiers, pressed: true, .. } = e @@ -749,12 +749,12 @@ fn dispatch(app: &mut VectorcraftApp, ctx: &egui::Context, accept: impl FnMut(&H let mods = craft_keymap::Mods::from_egui(modifiers, crate::keymap::platform()); let logical_chord = craft_keymap::Chord::new(mods, logical); let position_chord = craft_keymap::Chord::new(mods, position); - if !dispatcher.layout().candidates(&input).iter().any(|chord| crate::keymap::lookup(&mirror.keymap, chord).is_some()) { - if crate::keymap::lookup(&mirror.keymap, &logical_chord).is_some() { - *physical = *key; - } else if crate::keymap::lookup(&mirror.keymap, &position_chord).is_some() { - *key = *physical; - } + if crate::keymap::lookup(&mirror.keymap, &logical_chord).is_some() { + *physical = *key; + } else if crate::keymap::lookup(&mirror.keymap, &position_chord).is_some() + && !dispatcher.layout().candidates(&input).iter().any(|chord| crate::keymap::lookup(&mirror.keymap, chord).is_some()) + { + *key = *physical; } } } diff --git a/crates/ui-egui/src/shortcuts/tests.rs b/crates/ui-egui/src/shortcuts/tests.rs index ceb68108c..c5005fba9 100644 --- a/crates/ui-egui/src/shortcuts/tests.rs +++ b/crates/ui-egui/src/shortcuts/tests.rs @@ -1251,6 +1251,27 @@ fn resolved_logical_binding_wins_over_position_alias() { } } +#[test] +fn exact_shifted_logical_binding_wins_over_plain_text_binding() { + let mut app = remembered_paint_app(); + crate::keymap::set_override(&mut app.ui.shortcut_overrides, "view.rulers", ";"); + crate::keymap::set_override(&mut app.ui.shortcut_overrides, "view.grid", "Shift+;"); + let rulers_before = app.ui.view.rulers; + let grid_before = app.ui.view.grid; + let journal_before = app.session.journal.len(); + frame( + &mut app, + vec![ + egui::Event::ModifiersChanged(Modifiers::SHIFT), + egui::Event::Key { key: Key::Semicolon, physical_key: Some(Key::Comma), pressed: true, repeat: false, modifiers: Modifiers::SHIFT }, + egui::Event::Text(";".into()), + ], + ); + assert_eq!(app.ui.view.grid, !grid_before, "Shift+; runs Show Grid"); + assert_eq!(app.ui.view.rulers, rulers_before, "plain ; does not run Show Rulers"); + assert!(app.session.journal.since(journal_before).iter().all(|(command, _)| !command.starts_with("paint.")), "the press runs no paint command"); +} + #[test] fn user_shifted_punctuation_binding_runs_once() { let mut app = remembered_paint_app();