keyboard_events/
main.rs

1use {
2    crate::common::{
3        protocols::wayland::{
4            wl_display::WlDisplay,
5            wl_keyboard::{
6                WlKeyboard, WlKeyboardEventHandler, WlKeyboardKeyState, WlKeyboardKeymapFormat,
7                WlKeyboardRef,
8            },
9            wl_registry::{WlRegistry, WlRegistryEventHandler, WlRegistryRef},
10            wl_seat::{WlSeat, WlSeatCapability, WlSeatEventHandler, WlSeatRef},
11            wl_surface::WlSurfaceRef,
12        },
13        singletons::get_singletons,
14    },
15    common::simple_window,
16    std::{cell::RefCell, collections::HashMap, os::fd::OwnedFd, rc::Rc},
17    wl_client::{
18        Libwayland,
19        proxy::{self, OwnedProxy},
20    },
21};
22
23#[path = "../common/mod.rs"]
24mod common;
25
26fn main() {
27    let lib = Libwayland::open().unwrap();
28    let con = lib.connect_to_default_display().unwrap();
29    let queue = con.create_local_queue(c"keyboard-events");
30    let singletons = get_singletons(&queue.display());
31    let simple_window = simple_window::prepare(singletons);
32
33    let wl_registry = queue.display::<WlDisplay>().get_registry();
34    proxy::set_event_handler_local(
35        &wl_registry,
36        RegistryEventHandler {
37            wl_registry: wl_registry.clone(),
38            seats: Default::default(),
39        },
40    );
41
42    while !simple_window.exit.get() {
43        queue.dispatch_blocking().unwrap();
44    }
45}
46
47struct RegistryEventHandler {
48    wl_registry: WlRegistry,
49    seats: RefCell<HashMap<u32, Rc<Seat>>>,
50}
51
52struct Seat {
53    wl_seat: WlSeat,
54    wl_keyboard: RefCell<Option<WlKeyboard>>,
55}
56
57#[derive(Clone)]
58struct SeatEventHandler(Rc<Seat>);
59
60impl WlRegistryEventHandler for RegistryEventHandler {
61    fn global(&self, _slf: &WlRegistryRef, name: u32, interface: &str, version: u32) {
62        if interface == WlSeat::INTERFACE {
63            let wl_seat = self.wl_registry.bind::<WlSeat>(name, version.min(5));
64            let seat = Rc::new(Seat {
65                wl_seat: wl_seat.clone(),
66                wl_keyboard: Default::default(),
67            });
68            self.seats.borrow_mut().insert(name, seat.clone());
69            proxy::set_event_handler_local(&wl_seat, SeatEventHandler(seat));
70        }
71    }
72
73    fn global_remove(&self, _slf: &WlRegistryRef, name: u32) {
74        if let Some(seat) = self.seats.borrow_mut().remove(&name) {
75            if let Some(kb) = seat.wl_keyboard.take() {
76                if proxy::version(&*kb) >= WlKeyboard::REQ__RELEASE__SINCE {
77                    kb.release();
78                } else {
79                    proxy::destroy(&kb);
80                }
81            }
82            if proxy::version(&*seat.wl_seat) >= WlSeat::REQ__RELEASE__SINCE {
83                seat.wl_seat.release();
84            } else {
85                proxy::destroy(&seat.wl_seat);
86            }
87        }
88    }
89}
90
91impl WlSeatEventHandler for SeatEventHandler {
92    fn capabilities(&self, _slf: &WlSeatRef, capabilities: WlSeatCapability) {
93        let kb = &mut *self.0.wl_keyboard.borrow_mut();
94        if capabilities.contains(WlSeatCapability::KEYBOARD) {
95            if kb.is_none() {
96                let wl_keyboard = self.0.wl_seat.get_keyboard();
97                proxy::set_event_handler_local(&wl_keyboard, self.clone());
98                *kb = Some(wl_keyboard);
99            }
100        } else {
101            if let Some(kb) = kb.take() {
102                if proxy::version(&*kb) >= WlKeyboard::REQ__RELEASE__SINCE {
103                    kb.release();
104                } else {
105                    proxy::destroy(&kb);
106                }
107            }
108        }
109    }
110}
111
112impl WlKeyboardEventHandler for SeatEventHandler {
113    fn keymap(
114        &self,
115        _slf: &WlKeyboardRef,
116        format: WlKeyboardKeymapFormat,
117        _fd: OwnedFd,
118        size: u32,
119    ) {
120        println!("keymap format: {format:?}");
121        println!("keymap size: {size:?}");
122    }
123
124    fn enter(
125        &self,
126        _slf: &WlKeyboardRef,
127        _serial: u32,
128        surface: Option<&WlSurfaceRef>,
129        keys: &[u8],
130    ) {
131        println!("enter surface {:?}", surface.map(proxy::id));
132        println!("keys {keys:?}");
133    }
134
135    fn leave(&self, _slf: &WlKeyboardRef, _serial: u32, surface: Option<&WlSurfaceRef>) {
136        println!("leave surface {:?}", surface.map(proxy::id));
137    }
138
139    fn key(
140        &self,
141        _slf: &WlKeyboardRef,
142        _serial: u32,
143        _time: u32,
144        key: u32,
145        state: WlKeyboardKeyState,
146    ) {
147        println!("key {key:?} {state:?}");
148    }
149
150    fn modifiers(
151        &self,
152        _slf: &WlKeyboardRef,
153        _serial: u32,
154        mods_depressed: u32,
155        mods_latched: u32,
156        mods_locked: u32,
157        group: u32,
158    ) {
159        println!("modifiers {mods_depressed:x?}, {mods_latched:x?}, {mods_locked:x?}, {group}");
160    }
161
162    fn repeat_info(&self, _slf: &WlKeyboardRef, rate: i32, delay: i32) {
163        println!("repeat info {rate:?} {delay:?}");
164    }
165}