bevy/crates
Alix Bott b054d116a6
Replace winit's synthetic events by our own key tracking (#14379)
# Objective

Defocusing a window while a key is held (such as when Alt+tabbing), will
currently send a key release on X11 and Windows. This is likely the
behavior that most people expect.
However it's synthetic events from winit are unimplemented for WASM and
some other platforms. (See
https://github.com/rust-windowing/winit/issues/1272).
While we can implement it upstream, there is also some doubt about the
synthetic events API as a whole
(https://github.com/rust-windowing/winit/issues/3543), so I propose to
do it in bevy directly for now.

## Solution

This PR implements key tracking in bevy directly so we can synthesize
our own key release events across all platforms.

Note regarding X11 specifically:
- On `main`, pressing a keyboard shortcut to unfocus the window (`Ctrl +
Super + ArrowRight` in my case) will yield the following events:
```
Pressed Control
Pressed Super
Released Control
Released ArrowRight
Released Super
```
- On this branch, it will yield the following sequence:
```
Pressed Control
Pressed Super
Released Control
Released Super
```
To me the behavior of this branch is more expected than `main`, because
`main` produces an `ArrowRight` release without producing a press first.

## Testing

Tested in WASM and X11 with
```rust
App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Update, |mut keys: EventReader<KeyboardInput>| {
            for ev in keys.read() {
                error!("received {ev:?}");
            }
        })
        .run();
```
2025-03-10 21:11:29 +00:00
..
bevy_a11y
bevy_animation
bevy_app
bevy_asset
bevy_audio
bevy_color
bevy_core_pipeline
bevy_derive
bevy_dev_tools
bevy_diagnostic
bevy_dylib
bevy_ecs
bevy_encase_derive
bevy_gilrs
bevy_gizmos
bevy_gltf
bevy_image
bevy_input
bevy_input_focus
bevy_internal
bevy_log
bevy_macro_utils
bevy_math
bevy_mesh
bevy_mikktspace
bevy_pbr
bevy_picking
bevy_platform_support
bevy_ptr
bevy_reflect
bevy_remote
bevy_render
bevy_scene
bevy_sprite
bevy_state
bevy_tasks
bevy_text
bevy_time
bevy_transform
bevy_ui
bevy_utils
bevy_window
bevy_winit Replace winit's synthetic events by our own key tracking (#14379) 2025-03-10 21:11:29 +00:00