diff --git a/crates/ui-egui/src/shortcuts.rs b/crates/ui-egui/src/shortcuts.rs index 8b8355b07..8425456b9 100644 --- a/crates/ui-egui/src/shortcuts.rs +++ b/crates/ui-egui/src/shortcuts.rs @@ -731,9 +731,10 @@ 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 the logical character - // differs. An explicitly bound logical shifted chord takes precedence. + // 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. 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 && modifiers.shift && !modifiers.command @@ -743,14 +744,17 @@ fn dispatch(app: &mut VectorcraftApp, ctx: &egui::Context, accept: impl FnMut(&H && matches!(*physical, Key::Comma | Key::Period) && *key != *physical && let (Some(logical), Some(position)) = (craft_keymap::Key::from_egui(*key), craft_keymap::Key::from_egui(*physical)) + && let Some(input) = input { 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 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 !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; + } } } } diff --git a/crates/ui-egui/src/shortcuts/tests.rs b/crates/ui-egui/src/shortcuts/tests.rs index 56e552b31..ceb68108c 100644 --- a/crates/ui-egui/src/shortcuts/tests.rs +++ b/crates/ui-egui/src/shortcuts/tests.rs @@ -1232,6 +1232,25 @@ fn explicit_logical_shifted_binding_wins_over_position_alias() { assert_eq!(app.session.active().unwrap().history.undo.len(), before + 1); } +#[test] +fn resolved_logical_binding_wins_over_position_alias() { + for chord in [":", "Shift+;"] { + let mut app = remembered_paint_app(); + crate::keymap::set_override(&mut app.ui.shortcut_overrides, "view.grid", chord); + let journal_before = app.session.journal.len(); + frame( + &mut app, + vec![ + egui::Event::ModifiersChanged(Modifiers::SHIFT), + egui::Event::Key { key: Key::Colon, physical_key: Some(Key::Period), pressed: true, repeat: false, modifiers: Modifiers::SHIFT }, + egui::Event::Text(":".into()), + ], + ); + assert!(app.ui.view.grid, "{chord} runs Show Grid"); + assert!(app.session.journal.since(journal_before).iter().all(|(command, _)| !command.starts_with("paint.")), "{chord} runs no paint command"); + } +} + #[test] fn user_shifted_punctuation_binding_runs_once() { let mut app = remembered_paint_app();