bevy/examples/input
Winds 6ca1e756dc
Expose text field from winit in KeyboardInput (#16864)
# Objective

Allow handling of dead keys on some keyboard layouts.

In some cases, dead keys were impossible to get using the
`KeyboardInput` event. This information is already present in the
underlying winit `KeyEvent`, but it wasn't exposed.

## Solution

Expose the `text` field from winit's `KeyEvent` in `KeyboardInput`.

This logic is inspired egui's implementation here:
adfc0bebfc/crates/egui-winit/src/lib.rs (L790-L807)

## Testing

This is a new field, so it shouldn't break any existing functionality. I
tested that this change works by running the modified `text_input`
example on different keyboard layouts.

## Example

Using a Portuguese/ABNT2 keyboard layout on windows and pressing
<kbd>\~</kbd> followed by
<kbd>a</kbd>/<kbd>Space</kbd>/<kbd>d</kbd>/<kbd>\~</kbd> now generates
the following events:
```
KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: None, repeat: false, window: 0v1#4294967296 }
KeyboardInput { key_code: KeyA, logical_key: Character("ã"), state: Pressed, text: Some("ã"), repeat: false, window: 0v1#4294967296 }

KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: None, repeat: false, window: 0v1#4294967296 }
KeyboardInput { key_code: Space, logical_key: Space, state: Pressed, text: Some("~"), repeat: false, window: 0v1#4294967296 }

KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: None, repeat: false, window: 0v1#4294967296 }
KeyboardInput { key_code: KeyD, logical_key: Character("d"), state: Pressed, text: Some("~d"), repeat: false, window: 0v1#4294967296 }

KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: None, repeat: false, window: 0v1#4294967296 }
KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: Some("~~"), repeat: false, window: 0v1#4294967296 }
```

The logic for getting an input is pretty simple: check if `text` is
`Some`. If it is, this is actual input text, otherwise it isn't.

There's a small caveat: certain keys generate control characters in the
input text, which needs to be filtered out:
```
KeyboardInput { key_code: Escape, logical_key: Escape, state: Pressed, text: Some("\u{1b}"), repeat: false, window: 0v1#4294967296 }
```

I've updated the text_input example to include egui's solution to this,
which works well.

## Migration Guide

The `KeyboardInput` event now has a new `text` field.
2024-12-17 22:42:54 +00:00
..
char_input_events.rs Fix inconsistency in KeyboardInput examples to match migration guide (#14185) 2024-07-15 15:03:48 +00:00
gamepad_input_events.rs Implement gamepads as entities (#12770) 2024-09-27 20:07:20 +00:00
gamepad_input.rs Revert most of #16222 and add gamepad accessors (#16425) 2024-11-19 00:00:16 +00:00
gamepad_rumble.rs Revert most of #16222 and add gamepad accessors (#16425) 2024-11-19 00:00:16 +00:00
keyboard_input_events.rs Refactor EventReader::iter to read (#9631) 2023-08-30 14:20:03 +00:00
keyboard_input.rs Update winit dependency to 0.29 (#10702) 2023-12-21 07:40:47 +00:00
keyboard_modifiers.rs Update winit dependency to 0.29 (#10702) 2023-12-21 07:40:47 +00:00
mouse_grab.rs Migrate from Query::single and friends to Single (#15872) 2024-10-13 20:32:06 +00:00
mouse_input_events.rs rename touchpad to gesture, and add new gestures (#13660) 2024-06-04 12:44:25 +00:00
mouse_input.rs Mouse input accumulation (#14044) 2024-07-01 14:27:21 +00:00
text_input.rs Expose text field from winit in KeyboardInput (#16864) 2024-12-17 22:42:54 +00:00
touch_input_events.rs Refactor EventReader::iter to read (#9631) 2023-08-30 14:20:03 +00:00
touch_input.rs Non-breaking change* from UK spellings to US (#8291) 2023-04-08 16:22:46 +00:00