fix all

Junkui Zhang created

Change summary

crates/gpui/src/platform/linux/keyboard.rs | 47 +++++++++++++++++++++--
crates/gpui/src/platform/linux/platform.rs | 35 ++++++++++++-----
2 files changed, 68 insertions(+), 14 deletions(-)

Detailed changes

crates/gpui/src/platform/linux/keyboard.rs 🔗

@@ -1,3 +1,4 @@
+#[cfg(any(feature = "wayland", feature = "x11"))]
 use collections::HashMap;
 #[cfg(any(feature = "wayland", feature = "x11"))]
 use xkbcommon::xkb::Keycode;
@@ -58,15 +59,53 @@ impl LinuxKeyboardMapper {
         }
     }
 
-    pub(crate) fn get_key(&self, keycode: Keycode, shift: bool) -> Option<String> {
-        if shift {
-            self.code_to_shifted_key.get(&keycode).cloned()
-        } else {
+    pub(crate) fn get_key(
+        &self,
+        keycode: Keycode,
+        modifiers: &mut crate::Modifiers,
+    ) -> Option<String> {
+        if is_alphabetic_key(keycode) || !modifiers.shift {
             self.code_to_key.get(&keycode).cloned()
+        } else {
+            modifiers.shift = false;
+            self.code_to_shifted_key.get(&keycode).cloned()
         }
     }
 }
 
+#[cfg(any(feature = "wayland", feature = "x11"))]
+fn is_alphabetic_key(keycode: Keycode) -> bool {
+    matches!(
+        keycode.raw(),
+        0x0026 // a
+        | 0x0038 // b
+        | 0x0036 // c
+        | 0x0028 // d
+        | 0x001a // e
+        | 0x0029 // f
+        | 0x002a // g
+        | 0x002b // h
+        | 0x001f // i
+        | 0x002c // j
+        | 0x002d // k
+        | 0x002e // l
+        | 0x003a // m
+        | 0x0039 // n
+        | 0x0020 // o
+        | 0x0021 // p
+        | 0x0018 // q
+        | 0x001b // r
+        | 0x0027 // s
+        | 0x001c // t
+        | 0x001e // u
+        | 0x0037 // v
+        | 0x0019 // w
+        | 0x0035 // x
+        | 0x001d // y
+        | 0x0034 // z
+    )
+}
+
 // All typeable scan codes for the standard US keyboard layout, ANSI104
 #[cfg(any(feature = "wayland", feature = "x11"))]
 const TYPEABLE_CODES: &[u32] = &[

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

@@ -759,9 +759,33 @@ impl crate::Keystroke {
             Keysym::XF86_New => "new".to_owned(),
             Keysym::XF86_Open => "open".to_owned(),
             Keysym::XF86_Save => "save".to_owned(),
+            Keysym::F1 => "f1".to_owned(),
+            Keysym::F2 => "f2".to_owned(),
+            Keysym::F3 => "f3".to_owned(),
+            Keysym::F4 => "f4".to_owned(),
+            Keysym::F5 => "f5".to_owned(),
+            Keysym::F6 => "f6".to_owned(),
+            Keysym::F7 => "f7".to_owned(),
+            Keysym::F8 => "f8".to_owned(),
+            Keysym::F9 => "f9".to_owned(),
+            Keysym::F10 => "f10".to_owned(),
+            Keysym::F11 => "f11".to_owned(),
+            Keysym::F12 => "f12".to_owned(),
+            Keysym::F13 => "f13".to_owned(),
+            Keysym::F14 => "f14".to_owned(),
+            Keysym::F15 => "f15".to_owned(),
+            Keysym::F16 => "f16".to_owned(),
+            Keysym::F17 => "f17".to_owned(),
+            Keysym::F18 => "f18".to_owned(),
+            Keysym::F19 => "f19".to_owned(),
+            Keysym::F20 => "f20".to_owned(),
+            Keysym::F21 => "f21".to_owned(),
+            Keysym::F22 => "f22".to_owned(),
+            Keysym::F23 => "f23".to_owned(),
+            Keysym::F24 => "f24".to_owned(),
             _ => keyboard_state
                 .mapper
-                .get_key(keycode, modifiers.shift)
+                .get_key(keycode, &mut modifiers)
                 .unwrap_or_else(|| {
                     let name = xkb::keysym_get_name(key_sym).to_lowercase();
                     if key_sym.is_keypad_key() {
@@ -772,15 +796,6 @@ impl crate::Keystroke {
                 }),
         };
 
-        if modifiers.shift {
-            // we only include the shift for upper-case letters by convention,
-            // so don't include for numbers and symbols, but do include for
-            // tab/enter, etc.
-            if key.chars().count() == 1 && key.to_lowercase() == key.to_uppercase() {
-                modifiers.shift = false;
-            }
-        }
-
         // Ignore control characters (and DEL) for the purposes of key_char
         let key_char = (!key_utf8.is_empty() && !key_utf8.chars().next().unwrap().is_control())
             .then_some(key_utf8);