diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 607628da..982b95b0 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -1142,8 +1142,14 @@ pub enum Binding { /// A key press. #[derive(Debug, Clone, PartialEq, Eq)] pub struct KeyPress { - /// The key pressed. + /// The original key pressed without modifiers applied to it. + /// + /// You should use this key for combinations (e.g. Ctrl+C). pub key: keyboard::Key, + /// The key pressed with modifiers applied to it. + /// + /// You should use this key for any single key bindings (e.g. motions). + pub modified_key: keyboard::Key, /// The state of the keyboard modifiers. pub modifiers: keyboard::Modifiers, /// The text produced by the key press. @@ -1157,6 +1163,7 @@ impl Binding { pub fn from_key_press(event: KeyPress) -> Option { let KeyPress { key, + modified_key, modifiers, text, status, @@ -1166,20 +1173,7 @@ impl Binding { return None; } - #[cfg(target_os = "macos")] - let key = convert_macos_shortcut(&key, modifiers); - - match key.as_ref() { - keyboard::Key::Named(key::Named::Enter) => Some(Self::Enter), - keyboard::Key::Named(key::Named::Backspace) => { - Some(Self::Backspace) - } - keyboard::Key::Named(key::Named::Delete) - if text.is_none() || text.as_deref() == Some("\u{7f}") => - { - Some(Self::Delete) - } - keyboard::Key::Named(key::Named::Escape) => Some(Self::Unfocus), + let combination = match key.as_ref() { keyboard::Key::Character("c") if modifiers.command() => { Some(Self::Copy) } @@ -1194,6 +1188,28 @@ impl Binding { keyboard::Key::Character("a") if modifiers.command() => { Some(Self::SelectAll) } + _ => None, + }; + + if let Some(binding) = combination { + return Some(binding); + } + + #[cfg(target_os = "macos")] + let modified_key = + convert_macos_shortcut(&key, modifiers).unwrap_or(modified_key); + + match modified_key.as_ref() { + keyboard::Key::Named(key::Named::Enter) => Some(Self::Enter), + keyboard::Key::Named(key::Named::Backspace) => { + Some(Self::Backspace) + } + keyboard::Key::Named(key::Named::Delete) + if text.is_none() || text.as_deref() == Some("\u{7f}") => + { + Some(Self::Delete) + } + keyboard::Key::Named(key::Named::Escape) => Some(Self::Unfocus), _ => { if let Some(text) = text { let c = text.chars().find(|c| !c.is_control())?; @@ -1332,6 +1348,7 @@ impl Update { }, Event::Keyboard(keyboard::Event::KeyPressed { key, + modified_key, modifiers, text, .. @@ -1346,6 +1363,7 @@ impl Update { let key_press = KeyPress { key: key.clone(), + modified_key: modified_key.clone(), modifiers: *modifiers, text: text.clone(), status, @@ -1480,28 +1498,20 @@ pub fn default(theme: &Theme, status: Status) -> Style { pub(crate) fn convert_macos_shortcut( key: &keyboard::Key, modifiers: keyboard::Modifiers, -) -> &keyboard::Key { +) -> Option { if modifiers != keyboard::Modifiers::CTRL { - return key; + return None; } - match key.as_ref() { - keyboard::Key::Character("b") => { - &keyboard::Key::Named(key::Named::ArrowLeft) - } - keyboard::Key::Character("f") => { - &keyboard::Key::Named(key::Named::ArrowRight) - } - keyboard::Key::Character("a") => { - &keyboard::Key::Named(key::Named::Home) - } - keyboard::Key::Character("e") => &keyboard::Key::Named(key::Named::End), - keyboard::Key::Character("h") => { - &keyboard::Key::Named(key::Named::Backspace) - } - keyboard::Key::Character("d") => { - &keyboard::Key::Named(key::Named::Delete) - } - _ => key, - } + let key = match key.as_ref() { + keyboard::Key::Character("b") => key::Named::ArrowLeft, + keyboard::Key::Character("f") => key::Named::ArrowRight, + keyboard::Key::Character("a") => key::Named::Home, + keyboard::Key::Character("e") => key::Named::End, + keyboard::Key::Character("h") => key::Named::Backspace, + keyboard::Key::Character("d") => key::Named::Delete, + _ => return None, + }; + + Some(keyboard::Key::Named(key)) } diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 6832d789..39880cc8 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -899,7 +899,10 @@ where } } Event::Keyboard(keyboard::Event::KeyPressed { - key, text, .. + key, + text, + modified_key, + .. }) => { let state = state::(tree); @@ -1036,11 +1039,16 @@ where } #[cfg(target_os = "macos")] - let key = crate::text_editor::convert_macos_shortcut( - key, modifiers, - ); + let macos_shortcut = + crate::text_editor::convert_macos_shortcut( + key, modifiers, + ); - match key.as_ref() { + #[cfg(target_os = "macos")] + let modified_key = + macos_shortcut.as_ref().unwrap_or(modified_key); + + match modified_key.as_ref() { keyboard::Key::Named(key::Named::Enter) => { if let Some(on_submit) = self.on_submit.clone() { shell.publish(on_submit);