diff --git a/crates/gpui/src/platform/linux/keyboard.rs b/crates/gpui/src/platform/linux/keyboard.rs index 81f362b306d411586a77b98040587a7cc4521512..6b72288b768a547314475c97ae2907c57b1e5b7d 100644 --- a/crates/gpui/src/platform/linux/keyboard.rs +++ b/crates/gpui/src/platform/linux/keyboard.rs @@ -30,6 +30,7 @@ impl LinuxKeyboardLayout { #[cfg(any(feature = "wayland", feature = "x11"))] pub(crate) struct LinuxKeyboardMapper { + letters: HashMap, code_to_key: HashMap, code_to_shifted_key: HashMap, } @@ -37,9 +38,10 @@ pub(crate) struct LinuxKeyboardMapper { #[cfg(any(feature = "wayland", feature = "x11"))] impl LinuxKeyboardMapper { pub(crate) fn new(xkb_state: &xkbcommon::xkb::State) -> Self { + let mut letters = HashMap::default(); let mut code_to_key = HashMap::default(); let mut code_to_shifted_key = HashMap::default(); - let mut inserted = HashSet::default(); + let mut inserted_letters = HashSet::default(); let keymap = xkb_state.get_keymap(); let mut shifted_state = xkbcommon::xkb::State::new(&keymap); @@ -52,14 +54,18 @@ impl LinuxKeyboardMapper { let key = xkb_state.key_get_utf8(keycode); if !key.is_empty() { - code_to_key.insert(keycode, key.clone()); - inserted.insert(key); + if key_is_a_letter(&key) { + letters.insert(keycode, key.clone()); + } else { + code_to_key.insert(keycode, key.clone()); + } + inserted_letters.insert(key); } else { // keycode might be a dead key let keysym = xkb_state.key_get_one_sym(keycode); if let Some(key) = underlying_dead_key(keysym) { code_to_key.insert(keycode, key.clone()); - inserted.insert(key); + inserted_letters.insert(key); } } @@ -74,9 +80,10 @@ impl LinuxKeyboardMapper { } } } - insert_letters_if_missing(&inserted, &mut code_to_key); + insert_letters_if_missing(&inserted_letters, &mut letters); Self { + letters, code_to_key, code_to_shifted_key, } @@ -96,6 +103,38 @@ impl LinuxKeyboardMapper { } } +#[cfg(any(feature = "wayland", feature = "x11"))] +fn key_is_a_letter(key: &str) -> bool { + matches!( + key, + "a" | "b" + | "c" + | "d" + | "e" + | "f" + | "g" + | "h" + | "i" + | "j" + | "k" + | "l" + | "m" + | "n" + | "o" + | "p" + | "q" + | "r" + | "s" + | "t" + | "u" + | "v" + | "w" + | "x" + | "y" + | "z" + ) +} + #[cfg(any(feature = "wayland", feature = "x11"))] fn is_alphabetic_key(keycode: Keycode) -> bool { matches!( @@ -190,15 +229,12 @@ pub(crate) fn underlying_dead_key(keysym: Keysym) -> Option { } #[cfg(any(feature = "wayland", feature = "x11"))] -fn insert_letters_if_missing( - inserted: &HashSet, - code_to_key: &mut HashMap, -) { +fn insert_letters_if_missing(inserted: &HashSet, letters: &mut HashMap) { for scan_code in LinuxScanCodes::LETTERS.iter() { let keycode = Keycode::new(*scan_code as u32); let key = scan_code.to_str(); if !inserted.contains(key) { - code_to_key.insert(keycode, key.to_owned()); + letters.insert(keycode, key.to_owned()); } } }