pub struct Keyboard { /* private fields */ }xkb only.Expand description
A keymap and the state of the keys pressed against it.
One per seat, not one per device: a user typing on two keyboards is holding Shift on one and pressing a letter on the other, and xkb has to see both.
Implementations§
Source§impl Keyboard
impl Keyboard
Sourcepub fn from_names(names: &KeymapNames) -> Result<Self, InputError>
pub fn from_names(names: &KeymapNames) -> Result<Self, InputError>
Compile a keymap from RMLVO names.
§Errors
InputError::Keymap if the names do not compile – a layout that is
not installed, an option that does not exist.
Examples found in repository?
28fn main() {
29 let mut seat = match Seat::open(&SeatOptions::default()) {
30 Ok(seat) => seat,
31 Err(error) => {
32 eprintln!("{error}");
33 std::process::exit(1);
34 }
35 };
36 let mut keyboard = Keyboard::from_names(&KeymapNames::default()).expect("keymap");
37 let mut repeater = KeyRepeater::new(RepeatConfig::default()).expect("timer");
38
39 let started = Instant::now();
40 let mut events = Vec::new();
41 let mut repeats: Vec<KeyEvent> = Vec::new();
42 let mut leds = keyboard.leds();
43
44 loop {
45 {
46 let seat_fd = seat.as_fd();
47 let timer_fd = repeater.fd();
48 let mut fds = [
49 PollFd::new(&seat_fd, PollFlags::IN),
50 PollFd::new(&timer_fd, PollFlags::IN),
51 ];
52 let timeout = Duration::from_secs(30).try_into().expect("timeout");
53 if poll(&mut fds, Some(&timeout)).expect("poll") == 0 {
54 println!("nothing for thirty seconds");
55 return;
56 }
57 }
58
59 let now = u32::try_from(started.elapsed().as_millis()).unwrap_or(u32::MAX);
60
61 events.clear();
62 seat.dispatch(&mut events).expect("dispatch");
63 for event in &mut events {
64 match event {
65 InputEvent::Key(key) => {
66 keyboard.process_key(key);
67 repeater.on_key(key, keyboard.should_repeat(key.key));
68 if report(key) {
69 return;
70 }
71 }
72 other => println!("{other:?}"),
73 }
74 }
75
76 repeats.clear();
77 repeater.dispatch(now, &mut repeats).expect("repeat");
78 for key in &mut repeats {
79 // Resolved, not replayed: a Shift pressed since the key went down
80 // changes what this types.
81 keyboard.resolve(key);
82 report(key);
83 }
84
85 let current = keyboard.leds();
86 if current != leds {
87 seat.set_leds(current);
88 leds = current;
89 }
90 }
91}Sourcepub fn from_file(path: &Path) -> Result<Self, InputError>
pub fn from_file(path: &Path) -> Result<Self, InputError>
Compile a keymap from a file.
§Errors
InputError::Io if the file cannot be read, InputError::Keymap
if it does not compile.
Sourcepub fn from_string(keymap: &str) -> Result<Self, InputError>
pub fn from_string(keymap: &str) -> Result<Self, InputError>
Compile a keymap from text already in hand.
For a keymap that arrived over a socket or through an mmap and never touched a filesystem.
§Errors
InputError::Keymap if it does not compile.
Sourcepub fn reload(&mut self, names: &KeymapNames) -> Result<(), InputError>
pub fn reload(&mut self, names: &KeymapNames) -> Result<(), InputError>
Swap in a keymap compiled from different names.
Keys still held are replayed onto the new state, and the lock latch is carried over, so a layout change mid-keystroke does not strand a modifier down or turn Caps Lock off underneath the user.
The current keymap is left alone if the new names do not compile.
§Errors
Sourcepub fn resolve(&self, event: &mut KeyEvent)
pub fn resolve(&self, event: &mut KeyEvent)
Fill in what a key resolves to, without touching the keyboard state.
This is what a repeat wants: the same physical key, re-read against whatever modifiers are held now, so pressing Shift partway through a held key changes what the next repeat types.
Examples found in repository?
28fn main() {
29 let mut seat = match Seat::open(&SeatOptions::default()) {
30 Ok(seat) => seat,
31 Err(error) => {
32 eprintln!("{error}");
33 std::process::exit(1);
34 }
35 };
36 let mut keyboard = Keyboard::from_names(&KeymapNames::default()).expect("keymap");
37 let mut repeater = KeyRepeater::new(RepeatConfig::default()).expect("timer");
38
39 let started = Instant::now();
40 let mut events = Vec::new();
41 let mut repeats: Vec<KeyEvent> = Vec::new();
42 let mut leds = keyboard.leds();
43
44 loop {
45 {
46 let seat_fd = seat.as_fd();
47 let timer_fd = repeater.fd();
48 let mut fds = [
49 PollFd::new(&seat_fd, PollFlags::IN),
50 PollFd::new(&timer_fd, PollFlags::IN),
51 ];
52 let timeout = Duration::from_secs(30).try_into().expect("timeout");
53 if poll(&mut fds, Some(&timeout)).expect("poll") == 0 {
54 println!("nothing for thirty seconds");
55 return;
56 }
57 }
58
59 let now = u32::try_from(started.elapsed().as_millis()).unwrap_or(u32::MAX);
60
61 events.clear();
62 seat.dispatch(&mut events).expect("dispatch");
63 for event in &mut events {
64 match event {
65 InputEvent::Key(key) => {
66 keyboard.process_key(key);
67 repeater.on_key(key, keyboard.should_repeat(key.key));
68 if report(key) {
69 return;
70 }
71 }
72 other => println!("{other:?}"),
73 }
74 }
75
76 repeats.clear();
77 repeater.dispatch(now, &mut repeats).expect("repeat");
78 for key in &mut repeats {
79 // Resolved, not replayed: a Shift pressed since the key went down
80 // changes what this types.
81 keyboard.resolve(key);
82 report(key);
83 }
84
85 let current = keyboard.leds();
86 if current != leds {
87 seat.set_leds(current);
88 leds = current;
89 }
90 }
91}Sourcepub fn process_key(&mut self, event: &mut KeyEvent)
pub fn process_key(&mut self, event: &mut KeyEvent)
Resolve a key event and fold it into the keyboard state.
Resolution happens before the state update, which is the order
xkbcommon documents: a key’s own press must not change what that press
produces. With a latching modifier – a sticky Shift, a dead key – the
press being resolved is the one that consumes the latch, so reading
afterward reads a state the user has already left. The reference
resolves first too (keyboard.cpp); see the module tests.
A repeat – KeyEvent::repeat, as a key repeater synthesizes it –
is resolved and nothing more, as the reference treats it: feeding xkb
another press of a key it already holds is mutating the state from a
read.
Examples found in repository?
28fn main() {
29 let mut seat = match Seat::open(&SeatOptions::default()) {
30 Ok(seat) => seat,
31 Err(error) => {
32 eprintln!("{error}");
33 std::process::exit(1);
34 }
35 };
36 let mut keyboard = Keyboard::from_names(&KeymapNames::default()).expect("keymap");
37 let mut repeater = KeyRepeater::new(RepeatConfig::default()).expect("timer");
38
39 let started = Instant::now();
40 let mut events = Vec::new();
41 let mut repeats: Vec<KeyEvent> = Vec::new();
42 let mut leds = keyboard.leds();
43
44 loop {
45 {
46 let seat_fd = seat.as_fd();
47 let timer_fd = repeater.fd();
48 let mut fds = [
49 PollFd::new(&seat_fd, PollFlags::IN),
50 PollFd::new(&timer_fd, PollFlags::IN),
51 ];
52 let timeout = Duration::from_secs(30).try_into().expect("timeout");
53 if poll(&mut fds, Some(&timeout)).expect("poll") == 0 {
54 println!("nothing for thirty seconds");
55 return;
56 }
57 }
58
59 let now = u32::try_from(started.elapsed().as_millis()).unwrap_or(u32::MAX);
60
61 events.clear();
62 seat.dispatch(&mut events).expect("dispatch");
63 for event in &mut events {
64 match event {
65 InputEvent::Key(key) => {
66 keyboard.process_key(key);
67 repeater.on_key(key, keyboard.should_repeat(key.key));
68 if report(key) {
69 return;
70 }
71 }
72 other => println!("{other:?}"),
73 }
74 }
75
76 repeats.clear();
77 repeater.dispatch(now, &mut repeats).expect("repeat");
78 for key in &mut repeats {
79 // Resolved, not replayed: a Shift pressed since the key went down
80 // changes what this types.
81 keyboard.resolve(key);
82 report(key);
83 }
84
85 let current = keyboard.leds();
86 if current != leds {
87 seat.set_leds(current);
88 leds = current;
89 }
90 }
91}Sourcepub fn release_all(&mut self)
pub fn release_all(&mut self)
Release everything held, keeping the lock state.
For a session coming back from a VT switch, which is a thing the user does by holding Ctrl and Alt. Those keys come up while the device is revoked, and whether their releases survive the round trip is libinput’s business rather than something to depend on – so the state is squared away on resume instead. Getting it wrong the other way is a session where every keystroke is a Ctrl chord until the user presses and releases Ctrl again.
Locks survive: Caps Lock is not something the user let go of.
Sourcepub fn should_repeat(&self, key: u32) -> bool
pub fn should_repeat(&self, key: u32) -> bool
Whether the keymap says this key auto-repeats.
False for modifiers and lock keys, true for letters, digits, arrows and function keys – and it is the keymap’s answer, not a guess.
Examples found in repository?
28fn main() {
29 let mut seat = match Seat::open(&SeatOptions::default()) {
30 Ok(seat) => seat,
31 Err(error) => {
32 eprintln!("{error}");
33 std::process::exit(1);
34 }
35 };
36 let mut keyboard = Keyboard::from_names(&KeymapNames::default()).expect("keymap");
37 let mut repeater = KeyRepeater::new(RepeatConfig::default()).expect("timer");
38
39 let started = Instant::now();
40 let mut events = Vec::new();
41 let mut repeats: Vec<KeyEvent> = Vec::new();
42 let mut leds = keyboard.leds();
43
44 loop {
45 {
46 let seat_fd = seat.as_fd();
47 let timer_fd = repeater.fd();
48 let mut fds = [
49 PollFd::new(&seat_fd, PollFlags::IN),
50 PollFd::new(&timer_fd, PollFlags::IN),
51 ];
52 let timeout = Duration::from_secs(30).try_into().expect("timeout");
53 if poll(&mut fds, Some(&timeout)).expect("poll") == 0 {
54 println!("nothing for thirty seconds");
55 return;
56 }
57 }
58
59 let now = u32::try_from(started.elapsed().as_millis()).unwrap_or(u32::MAX);
60
61 events.clear();
62 seat.dispatch(&mut events).expect("dispatch");
63 for event in &mut events {
64 match event {
65 InputEvent::Key(key) => {
66 keyboard.process_key(key);
67 repeater.on_key(key, keyboard.should_repeat(key.key));
68 if report(key) {
69 return;
70 }
71 }
72 other => println!("{other:?}"),
73 }
74 }
75
76 repeats.clear();
77 repeater.dispatch(now, &mut repeats).expect("repeat");
78 for key in &mut repeats {
79 // Resolved, not replayed: a Shift pressed since the key went down
80 // changes what this types.
81 keyboard.resolve(key);
82 report(key);
83 }
84
85 let current = keyboard.leds();
86 if current != leds {
87 seat.set_leds(current);
88 leds = current;
89 }
90 }
91}Sourcepub fn leds(&self) -> Leds
pub fn leds(&self) -> Leds
The lock state.
Compare two of these to spot a transition, then push the new one to the devices so the physical lights follow.
Examples found in repository?
28fn main() {
29 let mut seat = match Seat::open(&SeatOptions::default()) {
30 Ok(seat) => seat,
31 Err(error) => {
32 eprintln!("{error}");
33 std::process::exit(1);
34 }
35 };
36 let mut keyboard = Keyboard::from_names(&KeymapNames::default()).expect("keymap");
37 let mut repeater = KeyRepeater::new(RepeatConfig::default()).expect("timer");
38
39 let started = Instant::now();
40 let mut events = Vec::new();
41 let mut repeats: Vec<KeyEvent> = Vec::new();
42 let mut leds = keyboard.leds();
43
44 loop {
45 {
46 let seat_fd = seat.as_fd();
47 let timer_fd = repeater.fd();
48 let mut fds = [
49 PollFd::new(&seat_fd, PollFlags::IN),
50 PollFd::new(&timer_fd, PollFlags::IN),
51 ];
52 let timeout = Duration::from_secs(30).try_into().expect("timeout");
53 if poll(&mut fds, Some(&timeout)).expect("poll") == 0 {
54 println!("nothing for thirty seconds");
55 return;
56 }
57 }
58
59 let now = u32::try_from(started.elapsed().as_millis()).unwrap_or(u32::MAX);
60
61 events.clear();
62 seat.dispatch(&mut events).expect("dispatch");
63 for event in &mut events {
64 match event {
65 InputEvent::Key(key) => {
66 keyboard.process_key(key);
67 repeater.on_key(key, keyboard.should_repeat(key.key));
68 if report(key) {
69 return;
70 }
71 }
72 other => println!("{other:?}"),
73 }
74 }
75
76 repeats.clear();
77 repeater.dispatch(now, &mut repeats).expect("repeat");
78 for key in &mut repeats {
79 // Resolved, not replayed: a Shift pressed since the key went down
80 // changes what this types.
81 keyboard.resolve(key);
82 report(key);
83 }
84
85 let current = keyboard.leds();
86 if current != leds {
87 seat.set_leds(current);
88 leds = current;
89 }
90 }
91}Sourcepub fn set_leds(&mut self, desired: Leds)
pub fn set_leds(&mut self, desired: Leds)
Drive the lock state to desired.
By synthesizing a press and release of each lock key that is on the wrong side, which is the only way to move a latch xkb owns. Produces no events and does not disturb the held-key set.
For honoring a lock state from elsewhere – what the console had, what
the session manager reports – and used internally by
Keyboard::reload.