linux: Fix caps lock not working consistently for certain X11 systems (#35361)

Smit Barmase created

Closes #35316

Bug in https://github.com/zed-industries/zed/pull/34514

Turns out you are not supposed to call `update_key` for modifiers on
`KeyPress`/`KeyRelease`, as modifiers are already updated in
`XkbStateNotify` events. Not sure why this only causes issues on a few
systems and works on others.

Tested on Ubuntu 24.04.2 LTS (initial bug) and Kubuntu 25.04 (worked
fine before too).

Release Notes:

- Fixed an issue where caps lock stopped working consistently on some
Linux X11 systems.

Change summary

crates/gpui/src/platform/linux/x11/client.rs | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

Detailed changes

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

@@ -1004,12 +1004,13 @@ impl X11Client {
                     let mut keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code);
                     let keysym = state.xkb.key_get_one_sym(code);
 
-                    // should be called after key_get_one_sym
-                    state.xkb.update_key(code, xkbc::KeyDirection::Down);
-
                     if keysym.is_modifier_key() {
                         return Some(());
                     }
+
+                    // should be called after key_get_one_sym
+                    state.xkb.update_key(code, xkbc::KeyDirection::Down);
+
                     if let Some(mut compose_state) = state.compose_state.take() {
                         compose_state.feed(keysym);
                         match compose_state.status() {
@@ -1067,12 +1068,13 @@ impl X11Client {
                     let keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code);
                     let keysym = state.xkb.key_get_one_sym(code);
 
-                    // should be called after key_get_one_sym
-                    state.xkb.update_key(code, xkbc::KeyDirection::Up);
-
                     if keysym.is_modifier_key() {
                         return Some(());
                     }
+
+                    // should be called after key_get_one_sym
+                    state.xkb.update_key(code, xkbc::KeyDirection::Up);
+
                     keystroke
                 };
                 drop(state);