Skip to main content

smithay_client_toolkit/seat/
keyboard_filter.rs

1/*! This implements support for the experimental xx-keyboard-filter-v1 protocol.
2 */
3
4pub use protocol::xx_keyboard_filter_manager_v1::XxKeyboardFilterManagerV1;
5pub use protocol::xx_keyboard_filter_v1::XxKeyboardFilterV1;
6use wayland_client::globals::{BindError, GlobalList};
7use wayland_client::protocol::wl_keyboard::WlKeyboard;
8use wayland_client::protocol::wl_surface::WlSurface;
9use wayland_client::{Connection, Dispatch, QueueHandle};
10use wayland_protocols_experimental::keyboard_filter::v3::client::{
11    self as protocol, xx_keyboard_filter_manager_v1, xx_keyboard_filter_v1,
12};
13
14use crate::dispatch2::Dispatch2;
15use crate::globals::GlobalData;
16
17#[derive(Debug)]
18pub struct KeyboardFilterManager {
19    manager: XxKeyboardFilterManagerV1,
20}
21
22impl KeyboardFilterManager {
23    /// Bind the input_method global, if it exists
24    pub fn bind<D>(globals: &GlobalList, qh: &QueueHandle<D>) -> Result<Self, BindError>
25    where
26        D: Dispatch<XxKeyboardFilterManagerV1, GlobalData> + 'static,
27    {
28        let manager = globals.bind(qh, 1..=1, GlobalData)?;
29        Ok(Self { manager })
30    }
31
32    /// Request a new keyboard_filter object associated with a given
33    /// keyboard, input method, and surface.
34    ///
35    /// Surface can be any surface, even a dummy one.
36    ///
37    /// May cause a protocol error if there's a bound keyboard already.
38    pub fn bind_to_input_method<D>(
39        &self,
40        qh: &QueueHandle<D>,
41        keyboard: &WlKeyboard,
42        input_method: &super::input_method_v3::XxInputMethodV1,
43        surface: &WlSurface,
44    ) -> KeyboardFilter
45    where
46        D: Dispatch<XxKeyboardFilterV1, GlobalData> + 'static,
47    {
48        KeyboardFilter(self.manager.bind_to_input_method(
49            keyboard,
50            input_method,
51            surface,
52            qh,
53            GlobalData,
54        ))
55    }
56}
57
58impl<D> Dispatch2<XxKeyboardFilterManagerV1, D> for GlobalData {
59    fn event(
60        &self,
61        _data: &mut D,
62        _manager: &XxKeyboardFilterManagerV1,
63        _event: xx_keyboard_filter_manager_v1::Event,
64        _conn: &Connection,
65        _qh: &QueueHandle<D>,
66    ) {
67        unreachable!("Filter manager receives no events")
68    }
69}
70
71#[derive(Debug)]
72pub struct KeyboardFilter(XxKeyboardFilterV1);
73
74impl KeyboardFilter {
75    /// May cause a protocol error if there's no bound keyboard.
76    pub fn unbind(&self) {
77        self.0.unbind();
78    }
79
80    /// May cause a protocol error on invalid serial.
81    pub fn filter(&self, serial: u32, action: xx_keyboard_filter_v1::FilterAction) {
82        self.0.filter(serial, action);
83    }
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
87pub struct KeyboardVersion(pub u32);
88
89impl<D> Dispatch2<XxKeyboardFilterV1, D> for GlobalData {
90    fn event(
91        &self,
92        _data: &mut D,
93        _keyboard: &XxKeyboardFilterV1,
94        _event: xx_keyboard_filter_v1::Event,
95        _conn: &Connection,
96        _qh: &QueueHandle<D>,
97    ) {
98        unreachable!("Filter receives no events")
99    }
100}
101
102#[cfg(test)]
103mod test {
104    use super::*;
105
106    struct Handler {}
107
108    crate::delegate_dispatch2!(Handler);
109
110    fn assert_is_manager_delegate<T>()
111    where
112        T: wayland_client::Dispatch<
113            protocol::xx_keyboard_filter_manager_v1::XxKeyboardFilterManagerV1,
114            crate::globals::GlobalData,
115        >,
116    {
117    }
118
119    fn assert_is_delegate<T>()
120    where
121        T: wayland_client::Dispatch<
122            protocol::xx_keyboard_filter_v1::XxKeyboardFilterV1,
123            crate::globals::GlobalData,
124        >,
125    {
126    }
127
128    #[test]
129    fn test_valid_assignment() {
130        assert_is_manager_delegate::<Handler>();
131        assert_is_delegate::<Handler>();
132    }
133}