1use crate::backend::input::KeyState;
4use crate::utils::{IsAlive, Serial, SERIAL_COUNTER};
5use downcast_rs::{impl_downcast, Downcast};
6use std::collections::HashSet;
7#[cfg(feature = "wayland_frontend")]
8use std::sync::RwLock;
9use std::{
10 default::Default,
11 fmt, io,
12 sync::{Arc, Mutex},
13};
14use thiserror::Error;
15use tracing::{debug, error, info, info_span, instrument, trace};
16
17use xkbcommon::xkb::ffi::XKB_STATE_LAYOUT_EFFECTIVE;
18pub use xkbcommon::xkb::{self, keysyms, Keycode, Keysym};
19
20use super::{GrabStatus, Seat, SeatHandler};
21
22#[cfg(feature = "wayland_frontend")]
23use wayland_server::{Resource, Weak};
24#[cfg(feature = "wayland_frontend")]
25mod keymap_file;
26#[cfg(feature = "wayland_frontend")]
27pub use keymap_file::{KeymapFile, KeymapFileId};
28
29mod modifiers_state;
30pub use modifiers_state::{ModifiersState, SerializedMods};
31
32mod xkb_config;
33pub use xkb_config::XkbConfig;
34
35pub trait KeyboardTarget<D>: IsAlive + PartialEq + Clone + fmt::Debug + Send
37where
38 D: SeatHandler,
39{
40 fn enter(&self, seat: &Seat<D>, data: &mut D, keys: Vec<KeysymHandle<'_>>, serial: Serial);
42 fn leave(&self, seat: &Seat<D>, data: &mut D, serial: Serial);
44 fn key(
46 &self,
47 seat: &Seat<D>,
48 data: &mut D,
49 key: KeysymHandle<'_>,
50 state: KeyState,
51 serial: Serial,
52 time: u32,
53 );
54 fn modifiers(&self, seat: &Seat<D>, data: &mut D, modifiers: ModifiersState, serial: Serial);
56 fn replace(
58 &self,
59 replaced: <D as SeatHandler>::KeyboardFocus,
60 seat: &Seat<D>,
61 data: &mut D,
62 keys: Vec<KeysymHandle<'_>>,
63 modifiers: ModifiersState,
64 serial: Serial,
65 ) {
66 KeyboardTarget::<D>::leave(&replaced, seat, data, serial);
67 KeyboardTarget::<D>::enter(self, seat, data, keys, serial);
68 KeyboardTarget::<D>::modifiers(self, seat, data, modifiers, serial);
69 }
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
74pub struct LedMapping {
75 pub num: Option<xkb::LedIndex>,
77 pub caps: Option<xkb::LedIndex>,
79 pub scroll: Option<xkb::LedIndex>,
81}
82
83impl LedMapping {
84 pub fn from_keymap(keymap: &xkb::Keymap) -> Self {
86 Self {
87 num: match keymap.led_get_index(xkb::LED_NAME_NUM) {
88 xkb::LED_INVALID => None,
89 index => Some(index),
90 },
91 caps: match keymap.led_get_index(xkb::LED_NAME_CAPS) {
92 xkb::LED_INVALID => None,
93 index => Some(index),
94 },
95 scroll: match keymap.led_get_index(xkb::LED_NAME_SCROLL) {
96 xkb::LED_INVALID => None,
97 index => Some(index),
98 },
99 }
100 }
101}
102
103#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
105pub struct LedState {
106 pub num: Option<bool>,
108 pub caps: Option<bool>,
110 pub scroll: Option<bool>,
112}
113
114impl LedState {
115 pub fn update_with(&mut self, state: &xkb::State, mapping: &LedMapping) -> bool {
119 let previous_state = *self;
120 self.num = mapping.num.map(|idx| state.led_index_is_active(idx));
121 self.caps = mapping.caps.map(|idx| state.led_index_is_active(idx));
122 self.scroll = mapping.scroll.map(|idx| state.led_index_is_active(idx));
123 *self != previous_state
124 }
125
126 pub fn from_state(state: &xkb::State, mapping: &LedMapping) -> Self {
128 let mut led_state = LedState::default();
129 led_state.update_with(state, mapping);
130 led_state
131 }
132}
133
134pub struct Xkb {
137 context: xkb::Context,
138 keymap: xkb::Keymap,
139 state: xkb::State,
140}
141
142impl Xkb {
143 pub unsafe fn context(&self) -> &xkb::Context {
148 &self.context
149 }
150
151 pub unsafe fn keymap(&self) -> &xkb::Keymap {
156 &self.keymap
157 }
158
159 pub unsafe fn state(&self) -> &xkb::State {
164 &self.state
165 }
166
167 pub fn active_layout(&self) -> Layout {
169 (0..self.keymap.num_layouts())
170 .find(|&idx| self.state.layout_index_is_active(idx, XKB_STATE_LAYOUT_EFFECTIVE))
171 .map(Layout)
172 .unwrap_or_default()
173 }
174
175 pub fn layout_name(&self, layout: Layout) -> &str {
177 self.keymap.layout_get_name(layout.0)
178 }
179
180 pub fn layouts(&self) -> impl Iterator<Item = Layout> {
182 (0..self.keymap.num_layouts()).map(Layout)
183 }
184
185 pub fn raw_syms_for_key_in_layout(&self, keycode: Keycode, layout: Layout) -> &[Keysym] {
188 self.keymap.key_get_syms_by_level(keycode, layout.0, 0)
189 }
190}
191
192impl fmt::Debug for Xkb {
193 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194 f.debug_struct("Xkb")
195 .field("context", &self.context.get_raw_ptr())
196 .field("keymap", &self.keymap.get_raw_ptr())
197 .field("state", &self.state.get_raw_ptr())
198 .finish()
199 }
200}
201
202unsafe impl Send for Xkb {}
205
206pub(crate) struct KbdInternal<D: SeatHandler> {
207 pub(crate) focus: Option<(<D as SeatHandler>::KeyboardFocus, Serial)>,
208 pending_focus: Option<<D as SeatHandler>::KeyboardFocus>,
209 pub(crate) pressed_keys: HashSet<Keycode>,
210 pub(crate) forwarded_pressed_keys: HashSet<Keycode>,
211 pub(crate) mods_state: ModifiersState,
212 xkb: Arc<Mutex<Xkb>>,
213 pub(crate) repeat_rate: i32,
214 pub(crate) repeat_delay: i32,
215 led_mapping: LedMapping,
216 pub(crate) led_state: LedState,
217 grab: GrabStatus<dyn KeyboardGrab<D>>,
218}
219
220impl<D: SeatHandler> fmt::Debug for KbdInternal<D> {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 f.debug_struct("KbdInternal")
224 .field("focus", &self.focus)
225 .field("pending_focus", &self.pending_focus)
226 .field("pressed_keys", &self.pressed_keys)
227 .field("forwarded_pressed_keys", &self.forwarded_pressed_keys)
228 .field("mods_state", &self.mods_state)
229 .field("xkb", &self.xkb)
230 .field("repeat_rate", &self.repeat_rate)
231 .field("repeat_delay", &self.repeat_delay)
232 .finish()
233 }
234}
235
236unsafe impl<D: SeatHandler> Send for KbdInternal<D> {}
239
240impl<D: SeatHandler + 'static> KbdInternal<D> {
241 fn new(xkb_config: XkbConfig<'_>, repeat_rate: i32, repeat_delay: i32) -> Result<KbdInternal<D>, ()> {
242 let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
249 let keymap = xkb_config.compile_keymap(&context)?;
250 let state = xkb::State::new(&keymap);
251 let led_mapping = LedMapping::from_keymap(&keymap);
252 let led_state = LedState::from_state(&state, &led_mapping);
253 Ok(KbdInternal {
254 focus: None,
255 pending_focus: None,
256 pressed_keys: HashSet::new(),
257 forwarded_pressed_keys: HashSet::new(),
258 mods_state: ModifiersState::default(),
259 xkb: Arc::new(Mutex::new(Xkb {
260 context,
261 keymap,
262 state,
263 })),
264 repeat_rate,
265 repeat_delay,
266 led_mapping,
267 led_state,
268 grab: GrabStatus::None,
269 })
270 }
271
272 fn key_input(&mut self, keycode: Keycode, state: KeyState) -> (bool, bool) {
274 let direction = match state {
276 KeyState::Pressed => {
277 self.pressed_keys.insert(keycode);
278 xkb::KeyDirection::Down
279 }
280 KeyState::Released => {
281 self.pressed_keys.remove(&keycode);
282 xkb::KeyDirection::Up
283 }
284 };
285
286 let mut xkb = self.xkb.lock().unwrap();
290 let state_components = xkb.state.update_key(keycode, direction);
291 let modifiers_changed = state_components != 0;
292 if modifiers_changed {
293 self.mods_state.update_with(&xkb.state);
294 }
295 let leds_changed = self.led_state.update_with(&xkb.state, &self.led_mapping);
296 (modifiers_changed, leds_changed)
297 }
298
299 fn with_grab<F>(&mut self, data: &mut D, seat: &Seat<D>, f: F)
300 where
301 F: FnOnce(&mut D, &mut KeyboardInnerHandle<'_, D>, &mut dyn KeyboardGrab<D>),
302 {
303 let mut grab = std::mem::replace(&mut self.grab, GrabStatus::Borrowed);
304 match grab {
305 GrabStatus::Borrowed => panic!("Accessed a keyboard grab from within a keyboard grab access."),
306 GrabStatus::Active(_, ref mut handler) => {
307 if let Some(ref surface) = handler.start_data().focus {
309 if !surface.alive() {
310 handler.unset(data);
311 self.grab = GrabStatus::None;
312 f(
313 data,
314 &mut KeyboardInnerHandle { inner: self, seat },
315 &mut DefaultGrab,
316 );
317 return;
318 }
319 }
320 f(
321 data,
322 &mut KeyboardInnerHandle { inner: self, seat },
323 &mut **handler,
324 );
325 }
326 GrabStatus::None => {
327 f(
328 data,
329 &mut KeyboardInnerHandle { inner: self, seat },
330 &mut DefaultGrab,
331 );
332 }
333 }
334
335 if let GrabStatus::Borrowed = self.grab {
336 self.grab = grab;
338 }
339 }
340}
341
342#[derive(Debug, Error)]
344pub enum Error {
345 #[error("Libxkbcommon could not load the specified keymap")]
347 BadKeymap,
348 #[error("Failed to create tempfile to share the keymap: {0}")]
350 IoError(io::Error),
351}
352
353pub(crate) struct KbdRc<D: SeatHandler> {
354 pub(crate) internal: Mutex<KbdInternal<D>>,
355 #[cfg(feature = "wayland_frontend")]
356 pub(crate) keymap: Mutex<KeymapFile>,
357 #[cfg(feature = "wayland_frontend")]
358 pub(crate) known_kbds: Mutex<Vec<Weak<wayland_server::protocol::wl_keyboard::WlKeyboard>>>,
359 #[cfg(feature = "wayland_frontend")]
360 pub(crate) last_enter: Mutex<Option<Serial>>,
361 pub(crate) span: tracing::Span,
362 #[cfg(feature = "wayland_frontend")]
363 pub(crate) active_keymap: RwLock<KeymapFileId>,
364}
365
366#[cfg(not(feature = "wayland_frontend"))]
367impl<D: SeatHandler> fmt::Debug for KbdRc<D> {
368 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
369 f.debug_struct("KbdRc").field("internal", &self.internal).finish()
370 }
371}
372
373#[cfg(feature = "wayland_frontend")]
374impl<D: SeatHandler> fmt::Debug for KbdRc<D> {
375 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
376 f.debug_struct("KbdRc")
377 .field("internal", &self.internal)
378 .field("keymap", &self.keymap)
379 .field("known_kbds", &self.known_kbds)
380 .field("last_enter", &self.last_enter)
381 .finish()
382 }
383}
384
385pub struct KeysymHandle<'a> {
387 xkb: &'a Mutex<Xkb>,
388 keycode: Keycode,
389}
390
391impl fmt::Debug for KeysymHandle<'_> {
392 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
393 write!(f, "{:?}", self.keycode)
394 }
395}
396
397impl<'a> KeysymHandle<'a> {
398 pub fn xkb(&self) -> &Mutex<Xkb> {
400 self.xkb
401 }
402
403 pub fn modified_sym(&self) -> Keysym {
410 self.xkb.lock().unwrap().state.key_get_one_sym(self.keycode)
411 }
412
413 pub fn modified_syms(&self) -> Vec<Keysym> {
415 self.xkb.lock().unwrap().state.key_get_syms(self.keycode).to_vec()
416 }
417
418 pub fn raw_syms(&self) -> Vec<Keysym> {
420 let xkb = self.xkb.lock().unwrap();
421 xkb.keymap
422 .key_get_syms_by_level(self.keycode, xkb.state.key_get_layout(self.keycode), 0)
423 .to_vec()
424 }
425
426 pub fn raw_latin_sym_or_raw_current_sym(&self) -> Option<Keysym> {
434 let xkb = self.xkb.lock().unwrap();
435 let effective_layout = Layout(xkb.state.key_get_layout(self.keycode));
436
437 let raw_syms =
440 xkb.keymap
441 .key_get_syms_by_level(self.keycode, xkb.state.key_get_layout(self.keycode), 0);
442 let base_sym = *raw_syms.first()?;
444
445 if base_sym.key_char().map(|ch| ch.is_ascii()).unwrap_or(true) {
447 return Some(base_sym);
448 };
449
450 for layout in xkb.layouts() {
452 if layout == effective_layout {
453 continue;
454 }
455
456 if let Some(keysym) = xkb.raw_syms_for_key_in_layout(self.keycode, layout).first() {
457 if keysym
460 .key_char()
461 .map(|key| key.is_ascii() && !key.is_ascii_control())
462 .unwrap_or(false)
463 {
464 return Some(*keysym);
465 }
466 }
467 }
468
469 Some(base_sym)
470 }
471
472 pub fn raw_code(&'a self) -> Keycode {
474 self.keycode
475 }
476}
477
478pub struct XkbContext<'a> {
480 xkb: &'a Mutex<Xkb>,
481 mods_state: &'a mut ModifiersState,
482 mods_changed: &'a mut bool,
483 leds_state: &'a mut LedState,
484 leds_changed: &'a mut bool,
485 leds_mapping: &'a LedMapping,
486}
487
488impl XkbContext<'_> {
489 pub fn xkb(&self) -> &Mutex<Xkb> {
491 self.xkb
492 }
493
494 pub fn set_layout(&mut self, layout: Layout) {
496 let mut xkb = self.xkb.lock().unwrap();
497
498 let state = xkb.state.update_mask(
499 self.mods_state.serialized.depressed,
500 self.mods_state.serialized.latched,
501 self.mods_state.serialized.locked,
502 0,
503 0,
504 layout.0,
505 );
506
507 if state != 0 {
508 self.mods_state.update_with(&xkb.state);
509 *self.mods_changed = true;
510 }
511
512 *self.leds_changed = self.leds_state.update_with(&xkb.state, self.leds_mapping);
513 }
514
515 pub fn cycle_next_layout(&mut self) {
517 let xkb = self.xkb.lock().unwrap();
518 let next_layout = (xkb.active_layout().0 + 1) % xkb.keymap.num_layouts();
519 drop(xkb);
520 self.set_layout(Layout(next_layout));
521 }
522
523 pub fn cycle_prev_layout(&mut self) {
525 let xkb = self.xkb.lock().unwrap();
526 let num_layouts = xkb.keymap.num_layouts();
527 let next_layout = (num_layouts + xkb.active_layout().0 - 1) % num_layouts;
528 drop(xkb);
529 self.set_layout(Layout(next_layout));
530 }
531}
532
533impl fmt::Debug for XkbContext<'_> {
534 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
535 f.debug_struct("XkbContext")
536 .field("mods_state", &self.mods_state)
537 .field("mods_changed", &self.mods_changed)
538 .finish()
539 }
540}
541
542#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
546pub struct Layout(pub xkb::LayoutIndex);
547
548#[derive(Debug)]
550pub enum FilterResult<T> {
551 Forward,
553 Intercept(T),
555}
556
557pub struct GrabStartData<D: SeatHandler> {
559 pub focus: Option<<D as SeatHandler>::KeyboardFocus>,
561}
562
563impl<D: SeatHandler + 'static> fmt::Debug for GrabStartData<D> {
564 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
565 f.debug_struct("GrabStartData")
566 .field("focus", &self.focus)
567 .finish()
568 }
569}
570
571impl<D: SeatHandler + 'static> Clone for GrabStartData<D> {
572 fn clone(&self) -> Self {
573 GrabStartData {
574 focus: self.focus.clone(),
575 }
576 }
577}
578
579pub trait KeyboardGrab<D: SeatHandler>: Downcast {
595 #[allow(clippy::too_many_arguments)]
600 fn input(
601 &mut self,
602 data: &mut D,
603 handle: &mut KeyboardInnerHandle<'_, D>,
604 keycode: Keycode,
605 state: KeyState,
606 modifiers: Option<ModifiersState>,
607 serial: Serial,
608 time: u32,
609 );
610
611 fn set_focus(
613 &mut self,
614 data: &mut D,
615 handle: &mut KeyboardInnerHandle<'_, D>,
616 focus: Option<<D as SeatHandler>::KeyboardFocus>,
617 serial: Serial,
618 );
619
620 fn start_data(&self) -> &GrabStartData<D>;
622
623 fn unset(&mut self, data: &mut D);
625}
626
627impl_downcast!(KeyboardGrab<D> where D: SeatHandler);
628
629pub struct KeyboardHandle<D: SeatHandler> {
641 pub(crate) arc: Arc<KbdRc<D>>,
642}
643
644impl<D: SeatHandler> fmt::Debug for KeyboardHandle<D> {
645 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
646 f.debug_struct("KeyboardHandle").field("arc", &self.arc).finish()
647 }
648}
649
650impl<D: SeatHandler> Clone for KeyboardHandle<D> {
651 #[inline]
652 fn clone(&self) -> Self {
653 KeyboardHandle {
654 arc: self.arc.clone(),
655 }
656 }
657}
658
659impl<D: SeatHandler> ::std::cmp::PartialEq for KeyboardHandle<D> {
660 #[inline]
661 fn eq(&self, other: &Self) -> bool {
662 Arc::ptr_eq(&self.arc, &other.arc)
663 }
664}
665
666impl<D: SeatHandler + 'static> KeyboardHandle<D> {
667 pub(crate) fn new(xkb_config: XkbConfig<'_>, repeat_delay: i32, repeat_rate: i32) -> Result<Self, Error> {
669 let span = info_span!("input_keyboard");
670 let _guard = span.enter();
671
672 info!("Initializing a xkbcommon handler with keymap query");
673 let internal = KbdInternal::new(xkb_config, repeat_rate, repeat_delay).map_err(|_| {
674 debug!("Loading keymap failed");
675 Error::BadKeymap
676 })?;
677
678 let xkb = internal.xkb.lock().unwrap();
679
680 info!(name = xkb.keymap.layouts().next(), "Loaded Keymap");
681
682 #[cfg(feature = "wayland_frontend")]
683 let keymap_file = KeymapFile::new(&xkb.keymap);
684 #[cfg(feature = "wayland_frontend")]
685 let active_keymap = keymap_file.id();
686
687 drop(xkb);
688 drop(_guard);
689 Ok(Self {
690 arc: Arc::new(KbdRc {
691 #[cfg(feature = "wayland_frontend")]
692 keymap: Mutex::new(keymap_file),
693 internal: Mutex::new(internal),
694 #[cfg(feature = "wayland_frontend")]
695 known_kbds: Mutex::new(Vec::new()),
696 #[cfg(feature = "wayland_frontend")]
697 last_enter: Mutex::new(None),
698 #[cfg(feature = "wayland_frontend")]
699 active_keymap: RwLock::new(active_keymap),
700 span,
701 }),
702 })
703 }
704
705 #[cfg(feature = "wayland_frontend")]
706 #[instrument(parent = &self.arc.span, skip(self, data, keymap))]
707 pub(crate) fn change_keymap(
708 &self,
709 data: &mut D,
710 focus: &Option<&mut <D as SeatHandler>::KeyboardFocus>,
711 keymap: &xkb::Keymap,
712 mods: ModifiersState,
713 ) {
714 let mut keymap_file = self.arc.keymap.lock().unwrap();
715 keymap_file.change_keymap(keymap);
716
717 self.send_keymap(data, focus, &keymap_file, mods);
718 }
719
720 #[cfg(feature = "wayland_frontend")]
724 #[instrument(parent = &self.arc.span, skip(self, data, keymap_file))]
725 pub(crate) fn send_keymap(
726 &self,
727 data: &mut D,
728 focus: &Option<&mut <D as SeatHandler>::KeyboardFocus>,
729 keymap_file: &KeymapFile,
730 mods: ModifiersState,
731 ) -> bool {
732 use std::os::unix::io::AsFd;
733 use tracing::warn;
734 use wayland_server::{protocol::wl_keyboard::KeymapFormat, Resource};
735
736 let new_id = keymap_file.id();
738 if new_id == *self.arc.active_keymap.read().unwrap() {
739 return false;
740 }
741 *self.arc.active_keymap.write().unwrap() = new_id;
742
743 let known_kbds = &self.arc.known_kbds;
745 for kbd in &*known_kbds.lock().unwrap() {
746 let Ok(kbd) = kbd.upgrade() else {
747 continue;
748 };
749
750 let res = keymap_file.with_fd(kbd.version() >= 7, |fd, size| {
751 kbd.keymap(KeymapFormat::XkbV1, fd.as_fd(), size as u32)
752 });
753 if let Err(e) = res {
754 warn!(
755 err = ?e,
756 "Failed to send keymap to client"
757 );
758 }
759 }
760
761 let seat = self.get_seat(data);
763 if let Some(focus) = focus {
764 focus.modifiers(&seat, data, mods, SERIAL_COUNTER.next_serial());
765 }
766
767 true
768 }
769
770 fn update_xkb_state(&self, data: &mut D, keymap: xkb::Keymap) {
771 let mut internal = self.arc.internal.lock().unwrap();
772
773 let mut state = xkb::State::new(&keymap);
774 for key in &internal.pressed_keys {
775 state.update_key(*key, xkb::KeyDirection::Down);
776 }
777
778 let led_mapping = LedMapping::from_keymap(&keymap);
779 internal.led_mapping = led_mapping;
780 internal.mods_state.update_with(&state);
781 let leds_changed = internal.led_state.update_with(&state, &led_mapping);
782 let mut xkb = internal.xkb.lock().unwrap();
783 xkb.keymap = keymap.clone();
784 xkb.state = state;
785 drop(xkb);
786
787 let mods = internal.mods_state;
788 let focus = internal.focus.as_mut().map(|(focus, _)| focus);
789
790 #[cfg(not(feature = "wayland_frontend"))]
791 if let Some(focus) = focus.as_ref() {
792 let seat = self.get_seat(data);
793 focus.modifiers(&seat, data, mods, SERIAL_COUNTER.next_serial());
794 };
795
796 #[cfg(feature = "wayland_frontend")]
797 self.change_keymap(data, &focus, &keymap, mods);
798
799 if leds_changed {
800 let led_state = internal.led_state;
801 std::mem::drop(internal);
802 let seat = self.get_seat(data);
803 data.led_state_changed(&seat, led_state);
804 }
805 }
806
807 pub fn set_keymap_from_string(&self, data: &mut D, keymap: String) -> Result<(), Error> {
811 let keymap = xkb::Keymap::new_from_string(
814 &self.arc.internal.lock().unwrap().xkb.lock().unwrap().context,
815 keymap,
816 xkb::KEYMAP_FORMAT_TEXT_V1,
817 xkb::KEYMAP_COMPILE_NO_FLAGS,
818 )
819 .ok_or_else(|| {
820 debug!("Loading keymap from string failed");
821 Error::BadKeymap
822 })?;
823 self.update_xkb_state(data, keymap);
824 Ok(())
825 }
826
827 pub fn set_xkb_config(&self, data: &mut D, xkb_config: XkbConfig<'_>) -> Result<(), Error> {
829 let keymap = xkb_config
830 .compile_keymap(&self.arc.internal.lock().unwrap().xkb.lock().unwrap().context)
831 .map_err(|_| {
832 debug!("Loading keymap from XkbConfig failed");
833 Error::BadKeymap
834 })?;
835 self.update_xkb_state(data, keymap);
836 Ok(())
837 }
838
839 pub fn with_xkb_state<F, T>(&self, data: &mut D, mut callback: F) -> T
844 where
845 F: FnMut(XkbContext<'_>) -> T,
846 {
847 let (result, new_led_state) = {
848 let internal = &mut *self.arc.internal.lock().unwrap();
849 let mut mods_changed = false;
850 let mut leds_changed = false;
851 let state = XkbContext {
852 mods_state: &mut internal.mods_state,
853 xkb: &mut internal.xkb,
854 mods_changed: &mut mods_changed,
855 leds_state: &mut internal.led_state,
856 leds_changed: &mut leds_changed,
857 leds_mapping: &internal.led_mapping,
858 };
859
860 let result = callback(state);
861
862 if mods_changed {
863 if let Some((focus, _)) = internal.focus.as_mut() {
864 let seat = self.get_seat(data);
865 focus.modifiers(&seat, data, internal.mods_state, SERIAL_COUNTER.next_serial());
866 };
867 }
868
869 (result, leds_changed.then_some(internal.led_state))
870 };
871
872 if let Some(led_state) = new_led_state {
873 let seat = self.get_seat(data);
874 data.led_state_changed(&seat, led_state)
875 }
876
877 result
878 }
879
880 pub fn set_grab<G: KeyboardGrab<D> + 'static>(&self, data: &mut D, grab: G, serial: Serial) {
884 let mut inner = self.arc.internal.lock().unwrap();
885 if let GrabStatus::Active(_, handler) = &mut inner.grab {
886 handler.unset(data);
887 }
888 inner.grab = GrabStatus::Active(serial, Box::new(grab));
889 }
890
891 pub fn unset_grab(&self, data: &mut D) {
893 let mut inner = self.arc.internal.lock().unwrap();
894 if let GrabStatus::Active(_, handler) = &mut inner.grab {
895 handler.unset(data);
896 }
897 inner.grab = GrabStatus::None;
898 }
899
900 pub fn has_grab(&self, serial: Serial) -> bool {
902 let guard = self.arc.internal.lock().unwrap();
903 match guard.grab {
904 GrabStatus::Active(s, _) => s == serial,
905 _ => false,
906 }
907 }
908
909 pub fn is_grabbed(&self) -> bool {
911 let guard = self.arc.internal.lock().unwrap();
912 !matches!(guard.grab, GrabStatus::None)
913 }
914
915 pub fn grab_start_data(&self) -> Option<GrabStartData<D>> {
917 let guard = self.arc.internal.lock().unwrap();
918 match &guard.grab {
919 GrabStatus::Active(_, g) => Some(g.start_data().clone()),
920 _ => None,
921 }
922 }
923
924 pub fn with_grab<T>(&self, f: impl FnOnce(Serial, &dyn KeyboardGrab<D>) -> T) -> Option<T> {
926 let guard = self.arc.internal.lock().unwrap();
927 if let GrabStatus::Active(s, g) = &guard.grab {
928 Some(f(*s, &**g))
929 } else {
930 None
931 }
932 }
933
934 #[instrument(level = "trace", parent = &self.arc.span, skip(self, data, filter))]
948 pub fn input<T, F>(
949 &self,
950 data: &mut D,
951 keycode: Keycode,
952 state: KeyState,
953 serial: Serial,
954 time: u32,
955 filter: F,
956 ) -> Option<T>
957 where
958 F: FnOnce(&mut D, &ModifiersState, KeysymHandle<'_>) -> FilterResult<T>,
959 {
960 let (filter_result, mods_changed) = self.input_intercept(data, keycode, state, filter);
961 if let FilterResult::Intercept(val) = filter_result {
962 trace!("Input was intercepted by filter");
964 return Some(val);
965 }
966
967 self.input_forward(data, keycode, state, serial, time, mods_changed);
968 None
969 }
970
971 pub fn input_intercept<T, F>(
979 &self,
980 data: &mut D,
981 keycode: Keycode,
982 state: KeyState,
983 filter: F,
984 ) -> (T, bool)
985 where
986 F: FnOnce(&mut D, &ModifiersState, KeysymHandle<'_>) -> T,
987 {
988 trace!("Handling keystroke");
989
990 let mut guard = self.arc.internal.lock().unwrap();
991 let (mods_changed, leds_changed) = guard.key_input(keycode, state);
992 let led_state = guard.led_state;
993 let mods_state = guard.mods_state;
994 let xkb = guard.xkb.clone();
995 std::mem::drop(guard);
996
997 let key_handle = KeysymHandle { xkb: &xkb, keycode };
998
999 trace!(mods_state = ?mods_state, sym = xkb::keysym_get_name(key_handle.modified_sym()), "Calling input filter");
1000 let filter_result = filter(data, &mods_state, key_handle);
1001
1002 if leds_changed {
1003 let seat = self.get_seat(data);
1004 data.led_state_changed(&seat, led_state);
1005 }
1006
1007 (filter_result, mods_changed)
1008 }
1009
1010 pub fn input_forward(
1014 &self,
1015 data: &mut D,
1016 keycode: Keycode,
1017 state: KeyState,
1018 serial: Serial,
1019 time: u32,
1020 mods_changed: bool,
1021 ) {
1022 let mut guard = self.arc.internal.lock().unwrap();
1023 match state {
1024 KeyState::Pressed => {
1025 guard.forwarded_pressed_keys.insert(keycode);
1026 }
1027 KeyState::Released => {
1028 guard.forwarded_pressed_keys.remove(&keycode);
1029 }
1030 };
1031
1032 let seat = self.get_seat(data);
1034 let modifiers = mods_changed.then_some(guard.mods_state);
1035 guard.with_grab(data, &seat, |data, handle, grab| {
1036 grab.input(data, handle, keycode, state, modifiers, serial, time);
1037 });
1038 if guard.focus.is_some() {
1039 trace!("Input forwarded to client");
1040 } else {
1041 trace!("No client currently focused");
1042 }
1043 }
1044
1045 #[instrument(level = "debug", parent = &self.arc.span, skip(self, data, focus), fields(focus = focus.is_some()))]
1052 pub fn set_focus(&self, data: &mut D, focus: Option<<D as SeatHandler>::KeyboardFocus>, serial: Serial) {
1053 let mut guard = self.arc.internal.lock().unwrap();
1054 guard.pending_focus.clone_from(&focus);
1055 let seat = self.get_seat(data);
1056 guard.with_grab(data, &seat, |data, handle, grab| {
1057 grab.set_focus(data, handle, focus, serial);
1058 });
1059 }
1060
1061 pub fn pressed_keys(&self) -> HashSet<Keycode> {
1063 let guard = self.arc.internal.lock().unwrap();
1064 guard.pressed_keys.clone()
1065 }
1066
1067 pub fn with_pressed_keysyms<F, R>(&self, f: F) -> R
1069 where
1070 F: FnOnce(Vec<KeysymHandle<'_>>) -> R,
1071 R: 'static,
1072 {
1073 let guard = self.arc.internal.lock().unwrap();
1074 {
1075 let handles = guard
1076 .pressed_keys
1077 .iter()
1078 .map(|keycode| KeysymHandle {
1079 xkb: &guard.xkb,
1080 keycode: *keycode,
1081 })
1082 .collect::<Vec<_>>();
1083 f(handles)
1084 }
1085 }
1086
1087 pub fn modifier_state(&self) -> ModifiersState {
1089 self.arc.internal.lock().unwrap().mods_state
1090 }
1091
1092 pub fn set_modifier_state(&self, mods_state: ModifiersState) -> u32 {
1094 let internal = &mut self.arc.internal.lock().unwrap();
1095
1096 let (leds_changed, led_state, modifiers_changed, serialized) = {
1097 let state = &mut internal.xkb.lock().unwrap().state;
1098
1099 let serialized = mods_state.serialize_back(state);
1100
1101 let modifiers_changed = state.update_mask(
1102 serialized.depressed,
1103 serialized.latched,
1104 serialized.locked,
1105 serialized.layout_effective & xkb::STATE_LAYOUT_DEPRESSED,
1106 serialized.layout_effective & xkb::STATE_LAYOUT_LATCHED,
1107 serialized.layout_effective & xkb::STATE_LAYOUT_LOCKED,
1108 );
1109
1110 if modifiers_changed == 0 {
1112 return 0;
1113 }
1114
1115 let led_mapping = &internal.led_mapping;
1116 let mut led_state = internal.led_state;
1117 let leds_changed = led_state.update_with(state, led_mapping);
1118
1119 (leds_changed, led_state, modifiers_changed, serialized)
1120 };
1121
1122 internal.mods_state = mods_state;
1123 internal.mods_state.serialized = serialized;
1124
1125 if leds_changed {
1126 internal.led_state = led_state;
1127 }
1128
1129 modifiers_changed
1130 }
1131
1132 pub fn led_state(&self) -> LedState {
1134 self.arc.internal.lock().unwrap().led_state
1135 }
1136
1137 pub fn is_focused(&self) -> bool {
1139 self.arc.internal.lock().unwrap().focus.is_some()
1140 }
1141
1142 #[instrument(parent = &self.arc.span, skip(self))]
1144 pub fn change_repeat_info(&self, rate: i32, delay: i32) {
1145 let mut guard = self.arc.internal.lock().unwrap();
1146 guard.repeat_delay = delay;
1147 guard.repeat_rate = rate;
1148 #[cfg(feature = "wayland_frontend")]
1149 for kbd in &*self.arc.known_kbds.lock().unwrap() {
1150 let Ok(kbd) = kbd.upgrade() else {
1151 continue;
1152 };
1153 if kbd.version() >= 4 {
1154 kbd.repeat_info(rate, delay);
1155 }
1156 }
1157 }
1158
1159 #[cfg(feature = "wayland_frontend")]
1163 pub fn last_enter(&self) -> Option<Serial> {
1164 *self.arc.last_enter.lock().unwrap()
1165 }
1166
1167 fn get_seat(&self, data: &mut D) -> Seat<D> {
1168 let seat_state = data.seat_state();
1169 seat_state
1170 .seats
1171 .iter()
1172 .find(|seat| seat.get_keyboard().map(|h| &h == self).unwrap_or(false))
1173 .cloned()
1174 .unwrap()
1175 }
1176}
1177
1178impl<D> KeyboardHandle<D>
1179where
1180 D: SeatHandler,
1181 <D as SeatHandler>::KeyboardFocus: Clone,
1182{
1183 pub fn current_focus(&self) -> Option<<D as SeatHandler>::KeyboardFocus> {
1185 self.arc
1186 .internal
1187 .lock()
1188 .unwrap()
1189 .focus
1190 .clone()
1191 .map(|(focus, _)| focus)
1192 }
1193}
1194
1195pub struct KeyboardInnerHandle<'a, D: SeatHandler> {
1198 inner: &'a mut KbdInternal<D>,
1199 seat: &'a Seat<D>,
1200}
1201
1202impl<D: SeatHandler> fmt::Debug for KeyboardInnerHandle<'_, D> {
1203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1204 f.debug_struct("KeyboardInnerHandle")
1205 .field("inner", &self.inner)
1206 .field("seat", &self.seat.arc.name)
1207 .finish()
1208 }
1209}
1210
1211impl<D: SeatHandler + 'static> KeyboardInnerHandle<'_, D> {
1212 pub fn set_grab<G: KeyboardGrab<D> + 'static>(
1216 &mut self,
1217 handler: &mut dyn KeyboardGrab<D>,
1218 data: &mut D,
1219 serial: Serial,
1220 grab: G,
1221 ) {
1222 handler.unset(data);
1223 self.inner.grab = GrabStatus::Active(serial, Box::new(grab));
1224 }
1225
1226 pub fn unset_grab(
1231 &mut self,
1232 handler: &mut dyn KeyboardGrab<D>,
1233 data: &mut D,
1234 serial: Serial,
1235 restore_focus: bool,
1236 ) {
1237 handler.unset(data);
1238 self.inner.grab = GrabStatus::None;
1239 if restore_focus {
1241 let focus = self.inner.pending_focus.clone();
1242 self.set_focus(data, focus, serial);
1243 }
1244 }
1245
1246 pub fn current_focus(&self) -> Option<&<D as SeatHandler>::KeyboardFocus> {
1248 self.inner.focus.as_ref().map(|f| &f.0)
1249 }
1250
1251 pub fn keysym_handle(&self, keycode: Keycode) -> KeysymHandle<'_> {
1253 KeysymHandle {
1254 keycode,
1255 xkb: &self.inner.xkb,
1256 }
1257 }
1258
1259 pub fn modifier_state(&self) -> ModifiersState {
1261 self.inner.mods_state
1262 }
1263
1264 pub fn input(
1266 &mut self,
1267 data: &mut D,
1268 keycode: Keycode,
1269 key_state: KeyState,
1270 modifiers: Option<ModifiersState>,
1271 serial: Serial,
1272 time: u32,
1273 ) {
1274 let (focus, _) = match self.inner.focus.as_mut() {
1275 Some(focus) => focus,
1276 None => return,
1277 };
1278
1279 #[cfg(feature = "wayland_frontend")]
1281 if let Some(keyboard_handle) = self.seat.get_keyboard() {
1282 let keymap_file = keyboard_handle.arc.keymap.lock().unwrap();
1283 let mods = self.inner.mods_state;
1284 keyboard_handle.send_keymap(data, &Some(focus), &keymap_file, mods);
1285 }
1286
1287 let key = KeysymHandle {
1290 xkb: &self.inner.xkb,
1291 keycode,
1292 };
1293
1294 focus.key(self.seat, data, key, key_state, serial, time);
1295 if let Some(mods) = modifiers {
1296 focus.modifiers(self.seat, data, mods, serial);
1297 }
1298 }
1299
1300 pub fn with_pressed_keysyms<F, R>(&self, f: F) -> R
1302 where
1303 F: FnOnce(Vec<KeysymHandle<'_>>) -> R,
1304 R: 'static,
1305 {
1306 let handles = self
1307 .inner
1308 .pressed_keys
1309 .iter()
1310 .map(|code| self.keysym_handle(*code))
1311 .collect();
1312 f(handles)
1313 }
1314
1315 pub fn set_focus(
1322 &mut self,
1323 data: &mut D,
1324 focus: Option<<D as SeatHandler>::KeyboardFocus>,
1325 serial: Serial,
1326 ) {
1327 if let Some(focus) = focus {
1328 let old_focus = self.inner.focus.replace((focus.clone(), serial));
1329 match (focus, old_focus) {
1330 (focus, Some((old_focus, _))) if focus == old_focus => {
1331 trace!("Focus unchanged");
1332 }
1333 (focus, Some((old_focus, _))) => {
1334 trace!("Focus set to new surface");
1335 let keys = self
1336 .inner
1337 .forwarded_pressed_keys
1338 .iter()
1339 .map(|keycode| KeysymHandle {
1340 xkb: &self.inner.xkb,
1341 keycode: *keycode,
1342 })
1343 .collect();
1344
1345 focus.replace(old_focus, self.seat, data, keys, self.inner.mods_state, serial);
1346 data.focus_changed(self.seat, Some(&focus));
1347 }
1348 (focus, None) => {
1349 let keys = self
1350 .inner
1351 .forwarded_pressed_keys
1352 .iter()
1353 .map(|keycode| KeysymHandle {
1354 xkb: &self.inner.xkb,
1355 keycode: *keycode,
1356 })
1357 .collect();
1358
1359 focus.enter(self.seat, data, keys, serial);
1360 focus.modifiers(self.seat, data, self.inner.mods_state, serial);
1361 data.focus_changed(self.seat, Some(&focus));
1362 }
1363 }
1364 } else if let Some((old_focus, _)) = self.inner.focus.take() {
1365 trace!("Focus unset");
1366 old_focus.leave(self.seat, data, serial);
1367 }
1368 }
1369}
1370
1371struct DefaultGrab;
1373
1374impl<D: SeatHandler + 'static> KeyboardGrab<D> for DefaultGrab {
1375 fn input(
1376 &mut self,
1377 data: &mut D,
1378 handle: &mut KeyboardInnerHandle<'_, D>,
1379 keycode: Keycode,
1380 state: KeyState,
1381 modifiers: Option<ModifiersState>,
1382 serial: Serial,
1383 time: u32,
1384 ) {
1385 handle.input(data, keycode, state, modifiers, serial, time)
1386 }
1387
1388 fn set_focus(
1389 &mut self,
1390 data: &mut D,
1391 handle: &mut KeyboardInnerHandle<'_, D>,
1392 focus: Option<<D as SeatHandler>::KeyboardFocus>,
1393 serial: Serial,
1394 ) {
1395 handle.set_focus(data, focus, serial)
1396 }
1397
1398 fn start_data(&self) -> &GrabStartData<D> {
1399 unreachable!()
1400 }
1401
1402 fn unset(&mut self, _data: &mut D) {}
1403}