# linux: Fix spacebar not working with multiple keyboard layouts \(\#34514\) · gitcafe/zed

[View on GitCafe](https://git.cafe/gitcafe/zed/commit/d4110fd2ab680364b265704cba9165d29208c33b)

Repository: [gitcafe/zed](https://git.cafe/gitcafe/zed)

Visibility: public

Requested revision: d4110fd2ab680364b265704cba9165d29208c33b

Requested commit: d4110fd2ab680364b265704cba9165d29208c33b

Commit: d4110fd2ab680364b265704cba9165d29208c33b

Tree: 96d7abba9792107d7f06a78d4d70a42141deea36

Author: Smit Barmase

Committer: GitHub

## Message

```
linux: Fix spacebar not working with multiple keyboard layouts (#34514)

Closes #26468 #16667

This PR fixes the spacebar not working with multiple keyboard layouts on
Linux X11. I have tested this with Czech, Russian, German, German Neo 2,
etc. It seems to work correctly.

`XkbStateNotify` events correctly update XKB state with complete
modifier info (depressed/latched/locked), but `KeyPress/KeyRelease`
events immediately overwrite that state using `update_mask()` with only
raw X11 modifier bits. This breaks xkb state as we reset `latched_mods`
and `locked_mods` to 0, as well as we might not correctly handle cases
where this new xkb state needs to change.

Previous logic is flawed because `KeyPress/KeyRelease` event only gives
you depressed modifiers (`event.state`) and not others, which we try to
fill in from `previous_xkb_state`. This patch was introduced to fix
capitalization issue with Neo 2
(https://github.com/zed-industries/zed/pull/14466) and later to fix
wrong keys with German layout
(https://github.com/zed-industries/zed/pull/31193), both of which I have
tested this PR with.

Now, instead of manually managing XKB state, we use the `update_key`
method, which internally handles modifier states and other cases we
might have missed.
  
From `update_key` docs:

> Update the keyboard state to reflect a given key being pressed or
released.
>
> This entry point is intended for programs which track the keyboard
state explictly (like an evdev client). If the state is serialized to
you by a master process (like a Wayland compositor) using functions like
`xkb_state_serialize_mods()`, you should use `xkb_state_update_mask()`
instead. **_The two functins should not generally be used together._**
>                
> A series of calls to this function should be consistent; that is, a
call with `xkb::KEY_DOWN` for a key should be matched by an
`xkb::KEY_UP`; if a key is pressed twice, it should be released twice;
etc. Otherwise (e.g. due to missed input events), situations like "stuck
modifiers" may occur.
>              
> This function is often used in conjunction with the function
`xkb_state_key_get_syms()` (or `xkb_state_key_get_one_sym()`), for
example, when handling a key event. In this case, you should prefer to
get the keysyms *before* updating the key, such that the keysyms
reported for the key event are not affected by the event itself. This is
the conventional behavior.

  
Release Notes:

- Fix the issue where the spacebar doesn’t work with multiple keyboard
layouts on Linux X11.
```

## Parents

- [3d160a6e263717728d4dc18f554b0b7c19cb4ae8](https://git.cafe/gitcafe/zed/commit/3d160a6e263717728d4dc18f554b0b7c19cb4ae8?format=markdown)

[Source at this commit](https://git.cafe/gitcafe/zed/tree/d4110fd2ab680364b265704cba9165d29208c33b?format=markdown)
