From 4ba180319a560be16026852f9f3ec1b96c387a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 29 Nov 2025 09:15:19 +0100 Subject: [PATCH 1/2] Use `modified_key` for single key bindings in `text_input` and `text_editor` Co-authored-by: Basti Widua --- widget/src/text_editor.rs | 41 +++++++++++++++++++++++++++------------ widget/src/text_input.rs | 7 +++++-- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 607628da..b50ad312 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, @@ -1169,17 +1176,7 @@ impl Binding { #[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 +1191,24 @@ impl Binding { keyboard::Key::Character("a") if modifiers.command() => { Some(Self::SelectAll) } + _ => None, + }; + + if let Some(binding) = combination { + return Some(binding); + } + + 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 +1347,7 @@ impl Update { }, Event::Keyboard(keyboard::Event::KeyPressed { key, + modified_key, modifiers, text, .. @@ -1346,6 +1362,7 @@ impl Update { let key_press = KeyPress { key: key.clone(), + modified_key: modified_key.clone(), modifiers: *modifiers, text: text.clone(), status, diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 6832d789..d1db294b 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); @@ -1040,7 +1043,7 @@ where key, modifiers, ); - match key.as_ref() { + match modified_key.as_ref() { keyboard::Key::Named(key::Named::Enter) => { if let Some(on_submit) = self.on_submit.clone() { shell.publish(on_submit); From d66cf51ad217731f34096e1033c8bc7d788444ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 29 Nov 2025 09:24:03 +0100 Subject: [PATCH 2/2] Fix macOS shortcut handling in `text_input` and `text_editor` --- widget/src/text_editor.rs | 41 ++++++++++++++++----------------------- widget/src/text_input.rs | 11 ++++++++--- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index b50ad312..982b95b0 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -1173,9 +1173,6 @@ impl Binding { return None; } - #[cfg(target_os = "macos")] - let key = convert_macos_shortcut(&key, modifiers); - let combination = match key.as_ref() { keyboard::Key::Character("c") if modifiers.command() => { Some(Self::Copy) @@ -1198,6 +1195,10 @@ impl Binding { 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) => { @@ -1497,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 d1db294b..39880cc8 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -1039,9 +1039,14 @@ 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, + ); + + #[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) => {