1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! KBVM is an implementation of the XKB specification and associated protocols.
//!
//! At its core, KBVM provides two types:
//!
//! - [`StateMachine`](state_machine::StateMachine), a compositor-side keyboard state
//! machine.
//! - [`LookupTable`](lookup::LookupTable), a client-side lookup table that can be used
//! to look up keysyms.
//!
//! These types can be created from XKB keymaps or RMLVO names by using an
//! [`xkb::Context`].
//!
//! Additionally, KBVM provides other tools from the XKB ecosystem:
//!
//! - [`ComposeTables`](xkb::compose::ComposeTable) can be created from XCompose files as
//! a simple input method.
//! - XKB keymaps can be loaded from X11 connections via
//! [integration](xkb::x11::KbvmX11Ext) with the x11rb crate.
//! - The RMLVO [registry](xkb::registry::Registry) can be loaded to display the available
//! RMLVO names to users.
//!
//! While XKB keymaps can be used to create `StateMachines` and `LookupTables`, it is also
//! possible to created these objects manually with the [`Builder`](builder::Builder)
//! type. To retain compatibility with XKB, any `LookupTable` can be
//! [turned](lookup::LookupTable::to_xkb_keymap) into an XKB keymap.
//!
//! Manually created `StateMachines` allow you to run arbitrary logic when keys are
//! pressed and released. For example, you can use this logic to implement sticky keys,
//! radio groups, locked keys, key redirection, latching keys, etc.
//!
//! # The common compositor pattern
//!
//! If you are developing a wayland compositor, you might use this crate as follows:
//!
//! 1. For each seat, the user configures either an XKB map directly or a set of RMLVO
//! names from which you have to create an XKB map.
//! 2. Either way, you use an [`xkb::Context`] and either
//! [`keymap_from_bytes`](xkb::Context::keymap_from_bytes) or
//! [`keymap_from_names`](xkb::Context::keymap_from_names) to create an
//! [`xkb::Keymap`].
//! 3. You can format this keymap as a string by using
//! [`Keymap::format`](xkb::Keymap::format). You send this keymap to clients via the
//! `wl_keyboard.keymap` event.
//! 4. You then use [`Keymap::to_builder`](xkb::Keymap::to_builder) followed by
//! [`Builder::build_state_machine`](builder::Builder::build_state_machine) to create
//! a [`StateMachine`](state_machine::StateMachine).
//! 5. Whenever you receive a libinput key event, you feed it into the `StateMachine` with
//! [`StateMachine::handle_key`](state_machine::StateMachine::handle_key). This in turn
//! produces a number of [`Events`](state_machine::Event) that you forward to clients.
//!
//! The `handle_key` documentation contains an example showing how to do this
//! correctly.
//!
//! If you are also handling keyboard shortcuts in your compositor, you will likely also
//! want to create a `LookupTable` as described in the next section.
//!
//! # The common client pattern
//!
//! If you are developing a wayland client, you might use this crate as follows:
//!
//! 1. For each seat, you receive a keymap via the `wl_keyboard.keymap` event.
//! 2. You use an [`xkb::Context`] and
//! [`keymap_from_bytes`](xkb::Context::keymap_from_bytes) to create an [`xkb::Keymap`]
//! from the buffer from the event.
//! 3. You then use [`Keymap::to_builder`](xkb::Keymap::to_builder) followed by
//! [`Builder::build_lookup_table`](builder::Builder::build_lookup_table) to create
//! a [`LookupTable`](lookup::LookupTable).
//! 4. You create a [`Components`] object to store the active modifiers and group of the
//! keyboard.
//! 5. Whenever you receive a `wl_keyboard.modifiers` event, you update the [`Components`]
//! as shown in [`Components::update_effective`].
//! 6. Whenever you receive a `wl_keyboard.key` event for a key press, you use
//! [`LookupTable::lookup`](lookup::LookupTable::lookup) to look up the keysyms
//! produced by this event, using the effective modifiers and group from your
//! [`Components`].
pub use ;