smithay/input/keyboard/
mod.rs

1//! Keyboard-related types for smithay's input abstraction
2
3use 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
35/// Trait representing object that can receive keyboard interactions
36pub trait KeyboardTarget<D>: IsAlive + PartialEq + Clone + fmt::Debug + Send
37where
38    D: SeatHandler,
39{
40    /// Keyboard focus of a given seat was assigned to this handler
41    fn enter(&self, seat: &Seat<D>, data: &mut D, keys: Vec<KeysymHandle<'_>>, serial: Serial);
42    /// The keyboard focus of a given seat left this handler
43    fn leave(&self, seat: &Seat<D>, data: &mut D, serial: Serial);
44    /// A key was pressed on a keyboard from a given seat
45    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    /// Hold modifiers were changed on a keyboard from a given seat
55    fn modifiers(&self, seat: &Seat<D>, data: &mut D, modifiers: ModifiersState, serial: Serial);
56    /// Keyboard focus of a given seat moved from another handler to this handler
57    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/// Mapping of the led of a keymap
73#[derive(Debug, Clone, Copy, PartialEq, Eq)]
74pub struct LedMapping {
75    /// Index of the NUMLOCK led
76    pub num: Option<xkb::LedIndex>,
77    /// Index of the CAPSLOCK led
78    pub caps: Option<xkb::LedIndex>,
79    /// Index of the SCROLLLOCK led
80    pub scroll: Option<xkb::LedIndex>,
81}
82
83impl LedMapping {
84    /// Get the mapping from a keymap
85    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/// Current state of the led when available
104#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
105pub struct LedState {
106    /// State of NUMLOCK led
107    pub num: Option<bool>,
108    /// State of CAPSLOCK led
109    pub caps: Option<bool>,
110    /// State of SCROLLLOCK led
111    pub scroll: Option<bool>,
112}
113
114impl LedState {
115    /// Update the led state from an xkb state and mapping
116    ///
117    /// Returns whether the led state changed
118    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    /// Initialize the led state from an xkb state and mapping
127    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
134/// An xkbcommon context, keymap, and state, that can be sent to another
135/// thread, but should not have additional ref-counts kept on one thread.
136pub struct Xkb {
137    context: xkb::Context,
138    keymap: xkb::Keymap,
139    state: xkb::State,
140}
141
142impl Xkb {
143    /// The xkbcommon context.
144    ///
145    /// # Safety
146    /// A ref-count of the context should not outlive the `Xkb`
147    pub unsafe fn context(&self) -> &xkb::Context {
148        &self.context
149    }
150
151    /// The xkbcommon keymap.
152    ///
153    /// # Safety
154    /// A ref-count of the keymap should not outlive the `Xkb`
155    pub unsafe fn keymap(&self) -> &xkb::Keymap {
156        &self.keymap
157    }
158
159    /// The xkbcommon state.
160    ///
161    /// # Safety
162    /// A ref-count of the state should not outlive the `Xkb`
163    pub unsafe fn state(&self) -> &xkb::State {
164        &self.state
165    }
166
167    /// Get the active layout of the keyboard.
168    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    /// Get the human readable name for the layout.
176    pub fn layout_name(&self, layout: Layout) -> &str {
177        self.keymap.layout_get_name(layout.0)
178    }
179
180    /// Iterate over layouts present in the keymap.
181    pub fn layouts(&self) -> impl Iterator<Item = Layout> {
182        (0..self.keymap.num_layouts()).map(Layout)
183    }
184
185    /// Returns the syms for the underlying keycode without any modifications by the current keymap
186    /// state applied.
187    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
202// This is OK because all parts of `xkb` will remain on the
203// same thread
204unsafe 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
220// focus_hook does not implement debug, so we have to impl Debug manually
221impl<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
236// This is OK because all parts of `xkb` will remain on the
237// same thread
238unsafe 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        // we create a new context for each keyboard because libxkbcommon is actually NOT threadsafe
243        // so confining it inside the KbdInternal allows us to use Rusts mutability rules to make
244        // sure nothing goes wrong.
245        //
246        // FIXME: This is an issue with the xkbcommon-rs crate that does not reflect this
247        // non-threadsafety properly.
248        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    // returns whether the modifiers or led state has changed
273    fn key_input(&mut self, keycode: Keycode, state: KeyState) -> (bool, bool) {
274        // track pressed keys as xkbcommon does not seem to expose it :(
275        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        // update state
287        // Offset the keycode by 8, as the evdev XKB rules reflect X's
288        // broken keycode system, which starts at 8.
289        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 this grab is associated with a surface that is no longer alive, discard it
308                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            // the grab has not been ended nor replaced, put it back in place
337            self.grab = grab;
338        }
339    }
340}
341
342/// Errors that can be encountered when creating a keyboard handler
343#[derive(Debug, Error)]
344pub enum Error {
345    /// libxkbcommon could not load the specified keymap
346    #[error("Libxkbcommon could not load the specified keymap")]
347    BadKeymap,
348    /// Smithay could not create a tempfile to share the keymap with clients
349    #[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
385/// Handle to the underlying keycode to allow for different conversions
386pub 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    /// Get the reference to the xkb state.
399    pub fn xkb(&self) -> &Mutex<Xkb> {
400        self.xkb
401    }
402
403    /// Returns the sym for the underlying keycode with all modifications by the current keymap state applied.
404    ///
405    /// This function is similar to [`KeysymHandle::modified_syms`], but is intended for cases where the user
406    /// does not want to or cannot handle multiple keysyms.
407    ///
408    /// If the key does not have exactly one keysym, returns [`keysyms::KEY_NoSymbol`].
409    pub fn modified_sym(&self) -> Keysym {
410        self.xkb.lock().unwrap().state.key_get_one_sym(self.keycode)
411    }
412
413    /// Returns the syms for the underlying keycode with all modifications by the current keymap state applied.
414    pub fn modified_syms(&self) -> Vec<Keysym> {
415        self.xkb.lock().unwrap().state.key_get_syms(self.keycode).to_vec()
416    }
417
418    /// Returns the syms for the underlying keycode without any modifications by the current keymap state applied.
419    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    /// Get the raw latin keysym or fallback to current raw keysym.
427    ///
428    /// This method is handy to implement layout agnostic bindings. Keep in mind that
429    /// it could be not-ideal to use just this function, since some layouts utilize non-standard
430    /// shift levels and you should look into [`Self::modified_sym`] first.
431    ///
432    /// The `None` is returned when the underlying keycode doesn't produce a valid keysym.
433    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        // don't call `self.raw_syms()` to avoid a deadlock
438        // and an unnecessary allocation into a Vec
439        let raw_syms =
440            xkb.keymap
441                .key_get_syms_by_level(self.keycode, xkb.state.key_get_layout(self.keycode), 0);
442        // NOTE: There's always a keysym in the current layout given that we have modified_sym.
443        let base_sym = *raw_syms.first()?;
444
445        // If the character is ascii or non-printable, return it.
446        if base_sym.key_char().map(|ch| ch.is_ascii()).unwrap_or(true) {
447            return Some(base_sym);
448        };
449
450        // Try to look other layouts and find the one with ascii character.
451        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                // NOTE: Only check for ascii non-control characters, since control ones are
458                // layout agnostic.
459                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    /// Returns the raw code in X keycode system (shifted by 8)
473    pub fn raw_code(&'a self) -> Keycode {
474        self.keycode
475    }
476}
477
478/// The currently active state of the Xkb.
479pub 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    /// Get the reference to the xkb state.
490    pub fn xkb(&self) -> &Mutex<Xkb> {
491        self.xkb
492    }
493
494    /// Set layout of the keyboard to the given index.
495    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    /// Switches layout forward cycling when it reaches the end.
516    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    /// Switches layout backward cycling when it reaches the start.
524    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/// Reference to the XkbLayout in the active keymap.
543///
544/// The layout may become invalid after calling [`KeyboardHandle::set_xkb_config`]
545#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
546pub struct Layout(pub xkb::LayoutIndex);
547
548/// Result for key input filtering (see [`KeyboardHandle::input`])
549#[derive(Debug)]
550pub enum FilterResult<T> {
551    /// Forward the given keycode to the client
552    Forward,
553    /// Do not forward and return value
554    Intercept(T),
555}
556
557/// Data about the event that started the grab.
558pub struct GrabStartData<D: SeatHandler> {
559    /// The focused surface, if any, at the start of the grab.
560    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
579/// A trait to implement a keyboard grab
580///
581/// In some context, it is necessary to temporarily change the behavior of the keyboard. This is
582/// typically known as a keyboard grab. A example would be, during a popup grab the keyboard focus
583/// will not be changed and stay on the grabbed popup.
584///
585/// This trait is the interface to intercept regular keyboard events and change them as needed, its
586/// interface mimics the [`KeyboardHandle`] interface.
587///
588/// If your logic decides that the grab should end, both [`KeyboardInnerHandle`] and [`KeyboardHandle`] have
589/// a method to change it.
590///
591/// When your grab ends (either as you requested it or if it was forcefully cancelled by the server),
592/// the struct implementing this trait will be dropped. As such you should put clean-up logic in the destructor,
593/// rather than trying to guess when the grab will end.
594pub trait KeyboardGrab<D: SeatHandler>: Downcast {
595    /// An input was reported.
596    ///
597    /// `modifiers` are only passed when their state actually changes. The modifier must be
598    /// sent after the key event.
599    #[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    /// A focus change was requested.
612    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    /// The data about the event that started the grab.
621    fn start_data(&self) -> &GrabStartData<D>;
622
623    /// The grab has been unset or replaced with another grab.
624    fn unset(&mut self, data: &mut D);
625}
626
627impl_downcast!(KeyboardGrab<D> where D: SeatHandler);
628
629/// An handle to a keyboard handler
630///
631/// It can be cloned and all clones manipulate the same internal state.
632///
633/// This handle gives you 2 main ways to interact with the keyboard handling:
634///
635/// - set the current focus for this keyboard: designing the surface that will receive the key inputs
636///   using the [`KeyboardHandle::set_focus`] method.
637/// - process key inputs from the input backend, allowing them to be caught at the compositor-level
638///   or forwarded to the client. See the documentation of the [`KeyboardHandle::input`] method for
639///   details.
640pub 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    /// Create a keyboard handler from a set of RMLVO rules
668    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    /// Send a new wl_keyboard keymap, without updating the internal keymap.
721    ///
722    /// Returns `true` if the keymap changed from the previous keymap.
723    #[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        // Ignore request which do not change the keymap.
737        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        // Update keymap for every wl_keyboard.
744        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        // Send updated modifiers.
762        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    /// Change the [`Keymap`](xkb::Keymap) used by the keyboard.
808    ///
809    /// The input is a keymap in XKB_KEYMAP_FORMAT_TEXT_V1 format.
810    pub fn set_keymap_from_string(&self, data: &mut D, keymap: String) -> Result<(), Error> {
811        // Construct the Keymap internally instead of accepting one as input
812        // because libxkbcommon is not thread-safe.
813        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    /// Change the [`XkbConfig`] used by the keyboard.
828    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    /// Access the underlying Xkb state and perform mutable operations on it, like
840    /// changing layouts.
841    ///
842    /// The changes to the state are automatically broadcasted to the focused client on exit.
843    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    /// Change the current grab on this keyboard to the provided grab
881    ///
882    /// Overwrites any current grab.
883    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    /// Remove any current grab on this keyboard, resetting it to the default behavior
892    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    /// Check if this keyboard is currently grabbed with this serial
901    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    /// Check if this keyboard is currently being grabbed
910    pub fn is_grabbed(&self) -> bool {
911        let guard = self.arc.internal.lock().unwrap();
912        !matches!(guard.grab, GrabStatus::None)
913    }
914
915    /// Returns the start data for the grab, if any.
916    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    /// Calls `f` with the active grab, if any.
925    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    /// Handle a keystroke
935    ///
936    /// All keystrokes from the input backend should be fed _in order_ to this method of the
937    /// keyboard handler. It will internally track the state of the keymap.
938    ///
939    /// The `filter` argument is expected to be a closure which will peek at the generated input
940    /// as interpreted by the keymap before it is forwarded to the focused client. If this closure
941    /// returns [`FilterResult::Forward`], the input will not be sent to the client. If it returns
942    /// [`FilterResult::Intercept`] a value can be passed to be returned by the whole function.
943    /// This mechanism can be used to implement compositor-level key bindings for example.
944    ///
945    /// The module [`keysyms`](crate::input::keyboard::keysyms) exposes definitions of all possible keysyms
946    /// to be compared against. This includes non-character keysyms, such as XF86 special keys.
947    #[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            // the filter returned `FilterResult::Intercept(T)`, we do not forward to client
963            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    /// Update the state of the keyboard without forwarding the event to the focused client
972    ///
973    /// Useful in conjunction with [`KeyboardHandle::input_forward`] in case you want
974    /// to asynchronously decide if the event should be forwarded to the focused client.
975    ///
976    /// Prefer using [`KeyboardHandle::input`] if this decision can be done synchronously
977    /// in the `filter` closure.
978    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    /// Forward a key event to the focused client
1011    ///
1012    /// Useful in conjunction with [`KeyboardHandle::input_intercept`].
1013    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        // forward to client if no keybinding is triggered
1033        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    /// Set the current focus of this keyboard
1046    ///
1047    /// If the new focus is different from the previous one, any previous focus
1048    /// will be sent a [`wl_keyboard::Event::Leave`](wayland_server::protocol::wl_keyboard::Event::Leave)
1049    /// event, and if the new focus is not `None`,
1050    /// a [`wl_keyboard::Event::Enter`](wayland_server::protocol::wl_keyboard::Event::Enter) event will be sent.
1051    #[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    /// Return the key codes of the currently pressed keys.
1062    pub fn pressed_keys(&self) -> HashSet<Keycode> {
1063        let guard = self.arc.internal.lock().unwrap();
1064        guard.pressed_keys.clone()
1065    }
1066
1067    /// Iterate over the keysyms of the currently pressed keys.
1068    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    /// Get the current modifiers state.
1088    pub fn modifier_state(&self) -> ModifiersState {
1089        self.arc.internal.lock().unwrap().mods_state
1090    }
1091
1092    /// Set the modifiers state.
1093    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            // Return early it nothing changed.
1111            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    /// Get the current led state
1133    pub fn led_state(&self) -> LedState {
1134        self.arc.internal.lock().unwrap().led_state
1135    }
1136
1137    /// Check if keyboard has focus
1138    pub fn is_focused(&self) -> bool {
1139        self.arc.internal.lock().unwrap().focus.is_some()
1140    }
1141
1142    /// Change the repeat info configured for this keyboard
1143    #[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    /// Access the [`Serial`] of the last `keyboard_enter` event, if that focus is still active.
1160    ///
1161    /// In other words this will return `None` again, once a `keyboard_leave` occurred.
1162    #[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    /// Retrieve the current keyboard focus
1184    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
1195/// This inner handle is accessed from inside a keyboard grab logic, and directly
1196/// sends event to the client
1197pub 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    /// Change the current grab on this keyboard to the provided grab
1213    ///
1214    /// Overwrites any current grab.
1215    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    /// Remove any current grab on this keyboard, resetting it to the default behavior
1227    ///
1228    /// This will also restore the focus of the underlying keyboard if restore_focus
1229    /// is [`true`]
1230    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        // restore the focus
1240        if restore_focus {
1241            let focus = self.inner.pending_focus.clone();
1242            self.set_focus(data, focus, serial);
1243        }
1244    }
1245
1246    /// Access the current focus of this keyboard
1247    pub fn current_focus(&self) -> Option<&<D as SeatHandler>::KeyboardFocus> {
1248        self.inner.focus.as_ref().map(|f| &f.0)
1249    }
1250
1251    /// Convert a given keycode as a [`KeysymHandle`] modified by this keyboards state
1252    pub fn keysym_handle(&self, keycode: Keycode) -> KeysymHandle<'_> {
1253        KeysymHandle {
1254            keycode,
1255            xkb: &self.inner.xkb,
1256        }
1257    }
1258
1259    /// Get the current modifiers state
1260    pub fn modifier_state(&self) -> ModifiersState {
1261        self.inner.mods_state
1262    }
1263
1264    /// Send the input to the focused keyboards
1265    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        // Ensure keymap is up to date.
1280        #[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        // key event must be sent before modifiers event for libxkbcommon
1288        // to process them correctly
1289        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    /// Iterate over the currently pressed keys.
1301    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    /// Set the current focus of this keyboard
1316    ///
1317    /// If the new focus is different from the previous one, any previous focus
1318    /// will be sent a [`wl_keyboard::Event::Leave`](wayland_server::protocol::wl_keyboard::Event::Leave)
1319    /// event, and if the new focus is not `None`,
1320    /// a [`wl_keyboard::Event::Enter`](wayland_server::protocol::wl_keyboard::Event::Enter) event will be sent.
1321    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
1371// The default grab, the behavior when no particular grab is in progress
1372struct 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}