x11: Fix handling of shift key (#13485)

Conrad Irwin created

Fixes: #13306

Release Notes:

- N/A

Change summary

crates/gpui/src/platform/linux/platform.rs | 36 ++++++-----------------
1 file changed, 10 insertions(+), 26 deletions(-)

Detailed changes

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

@@ -583,19 +583,11 @@ impl Keystroke {
         let key_utf8 = state.key_get_utf8(keycode);
         let key_sym = state.key_get_one_sym(keycode);
 
-        // The logic here tries to replicate the logic in `../mac/events.rs`
-        // "Consumed" modifiers are modifiers that have been used to translate a key, for example
-        // pressing "shift" and "1" on US layout produces the key `!` but "consumes" the shift.
-        // Notes:
-        //  - macOS gets the key character directly ("."), xkb gives us the key name ("period")
-        //  - macOS logic removes consumed shift modifier for symbols: "{", not "shift-{"
-        //  - macOS logic keeps consumed shift modifiers for letters: "shift-a", not "a" or "A"
-
-        let mut handle_consumed_modifiers = true;
         let key = match key_sym {
             Keysym::Return => "enter".to_owned(),
             Keysym::Prior => "pageup".to_owned(),
             Keysym::Next => "pagedown".to_owned(),
+            Keysym::ISO_Left_Tab => "tab".to_owned(),
 
             Keysym::comma => ",".to_owned(),
             Keysym::period => ".".to_owned(),
@@ -633,30 +625,22 @@ impl Keystroke {
             Keysym::equal => "=".to_owned(),
             Keysym::plus => "+".to_owned(),
 
-            Keysym::ISO_Left_Tab => {
-                handle_consumed_modifiers = false;
-                "tab".to_owned()
-            }
+            _ => xkb::keysym_get_name(key_sym).to_lowercase(),
+        };
 
-            _ => {
-                handle_consumed_modifiers = false;
-                xkb::keysym_get_name(key_sym).to_lowercase()
+        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_utf8 == key {
+                modifiers.shift = false;
             }
-        };
+        }
 
         // Ignore control characters (and DEL) for the purposes of ime_key
         let ime_key =
             (key_utf32 >= 32 && key_utf32 != 127 && !key_utf8.is_empty()).then_some(key_utf8);
 
-        if handle_consumed_modifiers {
-            let mod_shift_index = state.get_keymap().mod_get_index(xkb::MOD_NAME_SHIFT);
-            let is_shift_consumed = state.mod_index_is_consumed(keycode, mod_shift_index);
-
-            if modifiers.shift && is_shift_consumed {
-                modifiers.shift = false;
-            }
-        }
-
         Keystroke {
             modifiers,
             key,