Don't insert input in editor when control keys are pressed

Nathan Sobo created

Change summary

crates/editor/src/element.rs           | 19 ++++----------
crates/gpui/src/platform/event.rs      |  2 
crates/gpui/src/platform/mac/event.rs  | 35 +++++++++++++++++----------
crates/gpui/src/platform/mac/window.rs | 10 ++++----
4 files changed, 34 insertions(+), 32 deletions(-)

Detailed changes

crates/editor/src/element.rs 🔗

@@ -16,7 +16,6 @@ use gpui::{
         PathBuilder,
     },
     json::{self, ToJson},
-    keymap::Keystroke,
     text_layout::{self, RunStyle, TextLayoutCache},
     AppContext, Axis, Border, Element, ElementBox, Event, EventContext, LayoutContext,
     MutableAppContext, PaintContext, Quad, Scene, SizeConstraint, ViewContext, WeakViewHandle,
@@ -156,19 +155,15 @@ impl EditorElement {
         }
     }
 
-    fn key_down(&self, chars: &str, keystroke: &Keystroke, cx: &mut EventContext) -> bool {
+    fn key_down(&self, input: Option<&str>, cx: &mut EventContext) -> bool {
         let view = self.view.upgrade(cx.app).unwrap();
 
         if view.is_focused(cx.app) {
-            if chars.is_empty() {
-                false
+            if let Some(input) = input {
+                cx.dispatch_action(Input(input.to_string()));
+                true
             } else {
-                if chars.chars().any(|c| c.is_control()) || keystroke.cmd || keystroke.ctrl {
-                    false
-                } else {
-                    cx.dispatch_action(Input(chars.to_string()));
-                    true
-                }
+                false
             }
         } else {
             false
@@ -1105,9 +1100,7 @@ impl Element for EditorElement {
                 delta,
                 precise,
             } => self.scroll(*position, *delta, *precise, layout, paint, cx),
-            Event::KeyDown {
-                chars, keystroke, ..
-            } => self.key_down(chars, keystroke, cx),
+            Event::KeyDown { input, .. } => self.key_down(input.as_deref(), cx),
             _ => false,
         }
     }

crates/gpui/src/platform/event.rs 🔗

@@ -4,7 +4,7 @@ use crate::{geometry::vector::Vector2F, keymap::Keystroke};
 pub enum Event {
     KeyDown {
         keystroke: Keystroke,
-        chars: String,
+        input: Option<String>,
         is_held: bool,
     },
     ScrollWheel {

crates/gpui/src/platform/mac/event.rs 🔗

@@ -21,11 +21,13 @@ impl Event {
 
         match event_type {
             NSEventType::NSKeyDown => {
+                let mut input = None;
                 let modifiers = native_event.modifierFlags();
-                let unmodified_chars = native_event.charactersIgnoringModifiers();
-                let unmodified_chars = CStr::from_ptr(unmodified_chars.UTF8String() as *mut c_char)
-                    .to_str()
-                    .unwrap();
+                let unmodified_chars = CStr::from_ptr(
+                    native_event.charactersIgnoringModifiers().UTF8String() as *mut c_char,
+                )
+                .to_str()
+                .unwrap();
 
                 let unmodified_chars = if let Some(first_char) = unmodified_chars.chars().next() {
                     use cocoa::appkit::*;
@@ -38,7 +40,10 @@ impl Event {
 
                     #[allow(non_upper_case_globals)]
                     match first_char as u16 {
-                        SPACE_KEY => "space",
+                        SPACE_KEY => {
+                            input = Some(" ".to_string());
+                            "space"
+                        }
                         BACKSPACE_KEY => "backspace",
                         ENTER_KEY => "enter",
                         ESCAPE_KEY => "escape",
@@ -65,18 +70,22 @@ impl Event {
                         NSF11FunctionKey => "f11",
                         NSF12FunctionKey => "f12",
 
-                        _ => unmodified_chars,
+                        _ => {
+                            input = Some(
+                                CStr::from_ptr(
+                                    native_event.characters().UTF8String() as *mut c_char
+                                )
+                                .to_str()
+                                .unwrap()
+                                .into(),
+                            );
+                            unmodified_chars
+                        }
                     }
                 } else {
                     return None;
                 };
 
-                let chars = native_event.characters();
-                let chars = CStr::from_ptr(chars.UTF8String() as *mut c_char)
-                    .to_str()
-                    .unwrap()
-                    .into();
-
                 Some(Self::KeyDown {
                     keystroke: Keystroke {
                         ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask),
@@ -85,7 +94,7 @@ impl Event {
                         cmd: modifiers.contains(NSEventModifierFlags::NSCommandKeyMask),
                         key: unmodified_chars.into(),
                     },
-                    chars,
+                    input,
                     is_held: native_event.isARepeat() == YES,
                 })
             }

crates/gpui/src/platform/mac/window.rs 🔗

@@ -148,7 +148,7 @@ struct WindowState {
     scene_to_render: Option<Scene>,
     renderer: Renderer,
     command_queue: metal::CommandQueue,
-    last_fresh_keydown: Option<(Keystroke, String)>,
+    last_fresh_keydown: Option<(Keystroke, Option<String>)>,
     layer: id,
     traffic_light_position: Option<Vector2F>,
 }
@@ -517,11 +517,11 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
             // Ignore events from held-down keys after some of the initially-pressed keys
             // were released.
             Event::KeyDown {
-                chars,
+                input,
                 keystroke,
                 is_held,
             } => {
-                let keydown = (keystroke.clone(), chars.clone());
+                let keydown = (keystroke.clone(), input.clone());
                 if *is_held {
                     if window_state_borrow.last_fresh_keydown.as_ref() != Some(&keydown) {
                         return;
@@ -558,11 +558,11 @@ extern "C" fn cancel_operation(this: &Object, _sel: Sel, _sender: id) {
     };
     let event = Event::KeyDown {
         keystroke: keystroke.clone(),
-        chars: chars.clone(),
+        input: Some(chars.clone()),
         is_held: false,
     };
 
-    window_state_borrow.last_fresh_keydown = Some((keystroke, chars));
+    window_state_borrow.last_fresh_keydown = Some((keystroke, Some(chars)));
     if let Some(mut callback) = window_state_borrow.event_callback.take() {
         drop(window_state_borrow);
         callback(event);