You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
X11: Rewrite input handling in terms of XInput and XKB
This patch completes the port of the X11 backend from core input handling to
XInput/XKB input handling. In this context the word 'core' refers to the core
X11 protocol in contrast to protocol extensions such as XInput and XKB.
XInput and XKB are very large protocols that extend X11 with features expected
from modern desktop environments such as
- Support for a rich set of input devices such as touchpads.
- Support for multiple attached keyboards, mice, touchpads, tablets, etc.
- Support for rich and interactive keyboard layouts.
# Breaking Changes
- This patch removes all processing of core input events in favor of XInput
events. The legacy XIM input method protocol is based on filtering and
injecting core input events. Therefore, this patch also removes support for
XIM input methods. Applications are encouraged to switch to more modern IM
protocols such as [IBus]. These protocols can be implemented in application
space outside of winit. Note that modern toolskits such as QT5 and chromium
do not support XIM.
[IBus]: https://en.wikipedia.org/wiki/Intelligent_Input_Bus
- This patch removes support for synthetic keyboard events. This feature
cannot be implemented correctly:
- XKB is a complex state machine where key presses and releases can perform
a rich set of actions. For example:
- Switching modifiers on and off.
- Switching between keyboard layouts.
- Moving the mouse cursor.
These actions depend on the order the key are pressed and released.
For example, if a key that switches layouts is released before a
regular key, then the release of the regular key will produce
different events than it would otherwise.
- The winit API does not permit synthetic `ModifierChanged` events. As such,
an application cannot distinguish between the user deliberately changing
the active modifiers and synthetic changes. For example, consider an
application that performs a drag-and-drop operation as long as the Shift
modifier is active.
Applications are encouraged to track the state of keys manually in a way
that is suitable for their application.
# New and Changed Features
- Winit no longer tracks keyboard events if no winit window has the focus except
that:
- Raw keyboard events are still being tracked. A future patch might make this
behavior optional. See rust-windowing#1634.
- Changes to the keyboard layout are being tracked at all times.
- The backend now has complete support for multiple seats. For each seat it
tracks the modifier state and the focused window. In the case of
`KeyboardInput` events, applications can distinguish multiple seats by
tracking the value of the `device_id` field. In the case of
`ModifierChanged` events, applications cannot distinguish different seats. A
future patch might add a `device_id` field to `ModifierChanged` events.
The following sequence of events is possible:
1. Key Press: Seat 1, Left Shift
2. Modifiers Changed: Shift
3. Key Press: Seat 2, Left Ctrl
4. Modifiers Changed: Ctrl
5. Key Press: Seat 1, KeyA, Text: "A" (due to active Shift)
6. Key Release: Seat 1, Left Shift
7. Modifiers Changed: None
8. Key Release: Seat 2, Left Ctrl
9. Modifiers Changed: None
- Keyboard state and window events are now completely independent of device
events. Applications can disable device events by modifying the winit
source code (or in the future with a supported toggle) without incurring
regressions in other areas.
- Key release events no longer contain a value in the `text` and
`text_with_all_modifiers` fields.
- Key presses that are part of a compose sequence no longer contain a value in
the `text` and `text_with_all_modifiers`. Applications that simply want to
handle text input can therefore listen for key events and append the values
of the `text` field to the input buffer without having to track any state.
- The `logical_key` field of key events is no longer affected by compose
sequences. This is in line with how browsers handle compose sequences.
- Aborted compose sequences no longer produce any `text`. An aborted compose
sequence is a sequence that was not completed correctly. For example,
consider the following sequence of keysyms:
1. Multi_key
2. (
3. c
4. (
`(` is not a valid continuation of the compose sequence starting with
`[Multi_key, (, c]`. Therefore it aborts the sequence and no `text` is
produced (not even for the final `(`). This is in line with existing
practice on linux.
- The `Dead` `Key` is now used exclusively for those keysyms that have
`_dead_` in their name. This appears to be in line with how browsers handle
dead keys.
- The value of a `Dead` `Key` is in one of three categories:
- If the dead key does not correspond to any particular diacritical mark,
the value is `None`. For example, `dead_greek` (used to input Greek
characters on a Latin keyboard).
- If the dead key has a freestanding variant in unicode, the value is
`Some(c)` with `c` being the freestanding character. For example,
`dead_circumflex` has the value `Some('^')`.
- Otherwise the value is `None`. For example, `dead_belowdot`.
- `key_without_modifiers` now respects the effective XKB group. It only
discards the state of modifiers. This is essential to correctly handle
keyboard layouts in the GNOME desktop environment which uses XKB groups to
switch between layouts.
# Implementation Details
- `EventProcessor` no longer uses any interior mutability. In cases where
there were conflicting borrows, the code has been rewritten to use
freestanding functions.
- Keyboard state is now tracked exclusively by xkbcommon. The code that
manually tracked some of this state has been removed.
- The `xkb_state` module has been significantly simplified. The
`process_key_event` function now computes all effects produced by a key
press/release ahead of time.
- Almost all XInput events also carry the current XKB state of its seat. We
use this to track the state of modifiers eagerly and independently of
keyboard events.
0 commit comments