Skip to content

Commit 8392f87

Browse files
dczunset
authored andcommitted
Implement keyboard-filter-experimental.
Merged into wayland-protocols in https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/465
1 parent 6f8ada6 commit 8392f87

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

src/seat/keyboard_filter.rs

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

src/seat/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub mod input_method;
2424
pub mod input_method_v3;
2525
#[cfg(feature = "xkbcommon")]
2626
pub mod keyboard;
27+
pub mod keyboard_filter;
2728
pub mod pointer;
2829
pub mod pointer_constraints;
2930
pub mod relative_pointer;

0 commit comments

Comments
 (0)