gpui/platform/keyboard.rs
1use collections::HashMap;
2
3use crate::{KeybindingKeystroke, Keystroke};
4
5/// The keyboard layout that is currently active on a platform.
6///
7/// Each platform implements this to describe its active keyboard layout. The identifier and name
8/// are whatever the platform reports.
9pub trait PlatformKeyboardLayout {
10 /// Returns the layout's identifier. It is unique to the layout, so compare identifiers to
11 /// detect a change.
12 fn id(&self) -> &str;
13 /// Returns the layout's name for display, such as `U.S.`.
14 fn name(&self) -> &str;
15}
16
17/// Maps keystrokes in keybindings to the keys the platform reports.
18///
19/// The platform implements this to handle keyboard layouts where a binding's key is typed
20/// through another key. See [`KeyBinding::load`](crate::KeyBinding::load).
21pub trait PlatformKeyboardMapper {
22 /// Maps `keystroke` from a keybinding to the form the platform matches against.
23 ///
24 /// `use_key_equivalents` asks for the mapping that depends on the current layout. The
25 /// implementation decides what that means. The mapping is applied to keybindings loaded with
26 /// [`KeyBinding::load`](crate::KeyBinding::load).
27 fn map_key_equivalent(
28 &self,
29 keystroke: Keystroke,
30 use_key_equivalents: bool,
31 ) -> KeybindingKeystroke;
32 /// Returns the key equivalents for the current layout, mapping each character to the one
33 /// that the layout types in its place. Returns `None` where the platform has no such table.
34 ///
35 /// macOS returns one for the layouts it has a table for. Windows returns `None`.
36 fn get_key_equivalents(&self) -> Option<&HashMap<char, char>>;
37}
38
39/// A [`PlatformKeyboardMapper`] that changes nothing.
40///
41/// [`KeyBinding::new`](crate::KeyBinding::new) uses it, so bindings created in code always use
42/// the keys as written.
43pub struct DummyKeyboardMapper;
44
45impl PlatformKeyboardMapper for DummyKeyboardMapper {
46 fn map_key_equivalent(
47 &self,
48 keystroke: Keystroke,
49 _use_key_equivalents: bool,
50 ) -> KeybindingKeystroke {
51 KeybindingKeystroke::from_keystroke(keystroke)
52 }
53
54 fn get_key_equivalents(&self) -> Option<&HashMap<char, char>> {
55 None
56 }
57}