From d275a4ed324c878ed776de2acc3cae0ee9c9724d Mon Sep 17 00:00:00 2001 From: Zak Date: Mon, 9 Nov 2020 12:00:40 +0000 Subject: [PATCH 1/2] This PR fixes a bug with select all (CMD + A on MacOS) when using a text_input. Previous behaviour: when selecting all (CMD + A) would delete the current text inside the input and replace the content with just the letter 'a'. Now we check if the logo key (modifier key) has been pressed before checking any other key and save it to the state level. This way we can prevent any text being deleted when using the select all shortcut or text being entered at all when a modifier key is pressed (this behaviour matches other text input behaviour i.e text inputs in the browser etc...). --- native/src/widget/text_input.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index c067de77..20295e9f 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -382,6 +382,7 @@ where Event::Keyboard(keyboard::Event::CharacterReceived(c)) if self.state.is_focused && self.state.is_pasting.is_none() + && !self.state.is_logo_pressed && !c.is_control() => { let mut editor = @@ -398,6 +399,10 @@ where key_code, modifiers, }) if self.state.is_focused => { + if platform::is_copy_paste_modifier_pressed(modifiers) { + self.state.is_logo_pressed = true; + } + match key_code { keyboard::KeyCode::Enter => { if let Some(on_submit) = self.on_submit.clone() { @@ -523,7 +528,7 @@ where } } keyboard::KeyCode::V => { - if platform::is_copy_paste_modifier_pressed(modifiers) { + if self.state.is_logo_pressed { if let Some(clipboard) = clipboard { let content = match self.state.is_pasting.take() { @@ -558,13 +563,14 @@ where } } keyboard::KeyCode::A => { - if platform::is_copy_paste_modifier_pressed(modifiers) { + if self.state.is_logo_pressed { self.state.cursor.select_all(&self.value); } } keyboard::KeyCode::Escape => { self.state.is_focused = false; self.state.is_dragging = false; + self.state.is_logo_pressed = false; self.state.is_pasting = None; } _ => {} @@ -579,7 +585,9 @@ where keyboard::KeyCode::V => { self.state.is_pasting = None; } - _ => {} + _ => { + self.state.is_logo_pressed = false; + } } return event::Status::Captured; @@ -721,6 +729,7 @@ where pub struct State { is_focused: bool, is_dragging: bool, + is_logo_pressed: bool, is_pasting: Option, last_click: Option, cursor: Cursor, @@ -742,6 +751,7 @@ impl State { Self { is_focused: true, is_dragging: false, + is_logo_pressed: false, is_pasting: None, last_click: None, cursor: Cursor::default(), From 1d23db1866ee8cf109c3ba10a30ae6324bb9131e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 25 Nov 2020 04:10:23 +0100 Subject: [PATCH 2/2] Track keyboard modifiers in `text_input` --- native/src/widget/text_input.rs | 40 +++++++++++++-------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 20295e9f..a302e483 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -382,7 +382,7 @@ where Event::Keyboard(keyboard::Event::CharacterReceived(c)) if self.state.is_focused && self.state.is_pasting.is_none() - && !self.state.is_logo_pressed + && !self.state.keyboard_modifiers.is_command_pressed() && !c.is_control() => { let mut editor = @@ -396,12 +396,9 @@ where return event::Status::Captured; } Event::Keyboard(keyboard::Event::KeyPressed { - key_code, - modifiers, + key_code, .. }) if self.state.is_focused => { - if platform::is_copy_paste_modifier_pressed(modifiers) { - self.state.is_logo_pressed = true; - } + let modifiers = self.state.keyboard_modifiers; match key_code { keyboard::KeyCode::Enter => { @@ -528,7 +525,7 @@ where } } keyboard::KeyCode::V => { - if self.state.is_logo_pressed { + if self.state.keyboard_modifiers.is_command_pressed() { if let Some(clipboard) = clipboard { let content = match self.state.is_pasting.take() { @@ -563,15 +560,17 @@ where } } keyboard::KeyCode::A => { - if self.state.is_logo_pressed { + if self.state.keyboard_modifiers.is_command_pressed() { self.state.cursor.select_all(&self.value); } } keyboard::KeyCode::Escape => { self.state.is_focused = false; self.state.is_dragging = false; - self.state.is_logo_pressed = false; self.state.is_pasting = None; + + self.state.keyboard_modifiers = + keyboard::ModifiersState::default(); } _ => {} } @@ -585,13 +584,16 @@ where keyboard::KeyCode::V => { self.state.is_pasting = None; } - _ => { - self.state.is_logo_pressed = false; - } + _ => {} } return event::Status::Captured; } + Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) + if self.state.is_focused => + { + self.state.keyboard_modifiers = modifiers; + } _ => {} } @@ -729,10 +731,10 @@ where pub struct State { is_focused: bool, is_dragging: bool, - is_logo_pressed: bool, is_pasting: Option, last_click: Option, cursor: Cursor, + keyboard_modifiers: keyboard::ModifiersState, // TODO: Add stateful horizontal scrolling offset } @@ -751,10 +753,10 @@ impl State { Self { is_focused: true, is_dragging: false, - is_logo_pressed: false, is_pasting: None, last_click: None, cursor: Cursor::default(), + keyboard_modifiers: keyboard::ModifiersState::default(), } } @@ -880,14 +882,4 @@ mod platform { modifiers.control } } - - pub fn is_copy_paste_modifier_pressed( - modifiers: keyboard::ModifiersState, - ) -> bool { - if cfg!(target_os = "macos") { - modifiers.logo - } else { - modifiers.control - } - } }