pub fn set_event_handler_local<P, H>(proxy: &P, handler: H)where
P: OwnedProxy,
P::Api: CreateEventHandler<H>,
<P::Api as CreateEventHandler<H>>::EventHandler: 'static,Expand description
Sets the !Send event handler of the proxy.
This function is the same as set_event_handler except that the event handler does
not have to implement Send and the queue of the proxy must be a
local queue.
§Panic
This function panics whenever set_event_handler panics and also if the queue of
the proxy is not a local queue.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_local_queue(c"");
let display: WlDisplay = queue.display();
let sync = display.sync();
let done = Rc::new(Cell::new(false));
// Attach the event handler.
let done2 = done.clone();
proxy::set_event_handler_local(&sync, WlCallback::on_done(move |_, _| {
done2.set(true);
}));
// Wait for the compositor to send the `done` message.
queue.dispatch_roundtrip_blocking().unwrap();
// The event handler sets the value to `true`.
assert!(done.get());Examples found in repository?
examples/keyboard-events/main.rs (lines 34-40)
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 }More examples
examples/poll-integration/../common/simple_window.rs (line 65)
53pub fn prepare(singletons: Singletons) -> SimpleWindow {
54 let lib = Libwayland::open().unwrap();
55 let con = lib.connect_to_default_display().unwrap();
56 let queue = con.create_local_queue(c"simple-window");
57 let display: WlDisplay = queue.display();
58
59 // We have a hard dependency on these globals.
60 let wl_compositor = singletons.get::<WlCompositor>(1, 1);
61 let wl_shm = singletons.get::<WlShm>(1, 1);
62 let xdg_wm_base = singletons.get::<XdgWmBase>(1, 1);
63 let wp_viewporter = singletons.get::<WpViewporter>(1, 1);
64
65 proxy::set_event_handler_local(&xdg_wm_base, XdgWmPingPong);
66
67 // Create the window.
68 let buffer = {
69 let mut tempfile = tempfile().unwrap();
70 tempfile.write_all(&[0, 0, 0, 255]).unwrap();
71 let pool = wl_shm.create_pool(tempfile.as_fd(), 4);
72 let buffer = pool.create_buffer(0, 1, 1, 4, WlShmFormat::ARGB8888);
73 pool.destroy();
74 buffer
75 };
76 let wl_surface = wl_compositor.create_surface();
77 let wp_viewport = wp_viewporter.get_viewport(&wl_surface);
78 let xdg_surface = xdg_wm_base.get_xdg_surface(&wl_surface);
79 let xdg_toplevel = xdg_surface.get_toplevel();
80 xdg_toplevel.set_title("simple-window");
81 wl_surface.commit();
82
83 let exit = Rc::new(Cell::new(false));
84
85 let event_handler = WindowEventHandler {
86 state: Rc::new(WindowState {
87 surface: wl_surface.clone(),
88 buffer,
89 viewport: wp_viewport.clone(),
90 exit: exit.clone(),
91 attached_buffer: Cell::new(false),
92 pending_size: Cell::new((DEFAULT_WIDTH, DEFAULT_HEIGHT)),
93 current_size: Cell::new((0, 0)),
94 }),
95 };
96 proxy::set_event_handler_local(&xdg_surface, event_handler.clone());
97 proxy::set_event_handler_local(&xdg_toplevel, event_handler.clone());
98
99 // If we have the cursor shape manager, create a new registry to handle seats
100 // and give the pointers the default shape when they enter our window.
101 if let Some(cursor_shape) = singletons.get_opt::<WpCursorShapeManagerV1>(1, 1) {
102 let registry = display.get_registry();
103 proxy::set_event_handler_local(
104 ®istry,
105 SeatRegistryHandler {
106 registry: registry.clone(),
107 wp_cursor_shape_manager_v1: cursor_shape,
108 seats: Default::default(),
109 },
110 );
111 }
112
113 SimpleWindow {
114 exit,
115 wl_compositor,
116 wl_shm,
117 xdg_wm_base,
118 wp_viewporter,
119 wl_surface,
120 wp_viewport,
121 xdg_surface,
122 xdg_toplevel,
123 }
124}
125
126struct SeatRegistryHandler {
127 registry: WlRegistry,
128 wp_cursor_shape_manager_v1: WpCursorShapeManagerV1,
129 seats: RefCell<HashMap<u32, Rc<RefCell<SeatData>>>>,
130}
131
132impl WlRegistryEventHandler for SeatRegistryHandler {
133 fn global(&self, _slf: &WlRegistryRef, name: u32, interface: &str, version: u32) {
134 if interface != WlSeat::INTERFACE {
135 return;
136 }
137 let seat: WlSeat = self.registry.bind(name, version.min(5));
138 let data = Rc::new(RefCell::new(SeatData {
139 seat: seat.clone(),
140 pointer: None,
141 shape: None,
142 }));
143 proxy::set_event_handler_local(
144 &seat,
145 SeatEventHandler {
146 wp_cursor_shape_manager_v1: self.wp_cursor_shape_manager_v1.clone(),
147 data: data.clone(),
148 },
149 );
150 self.seats.borrow_mut().insert(name, data);
151 }
152
153 fn global_remove(&self, _slf: &WlRegistryRef, name: u32) {
154 let seats = &mut *self.seats.borrow_mut();
155 let Some(seat) = seats.remove(&name) else {
156 return;
157 };
158 let data = &mut *seat.borrow_mut();
159 data.destroy_pointer();
160 if proxy::version(&*data.seat) >= WlSeat::REQ__RELEASE__SINCE {
161 data.seat.release();
162 } else {
163 proxy::destroy(&data.seat);
164 }
165 }
166}
167
168struct SeatEventHandler {
169 wp_cursor_shape_manager_v1: WpCursorShapeManagerV1,
170 data: Rc<RefCell<SeatData>>,
171}
172
173struct SeatData {
174 seat: WlSeat,
175 pointer: Option<WlPointer>,
176 shape: Option<WpCursorShapeDeviceV1>,
177}
178
179impl SeatData {
180 fn destroy_pointer(&mut self) {
181 if let Some(shape) = self.shape.take() {
182 shape.destroy();
183 }
184 if let Some(pointer) = self.pointer.take() {
185 if proxy::version(&*pointer) >= WlPointer::REQ__RELEASE__SINCE {
186 pointer.release();
187 } else {
188 proxy::destroy(&pointer);
189 }
190 }
191 }
192}
193
194impl WlSeatEventHandler for SeatEventHandler {
195 fn capabilities(&self, _slf: &WlSeatRef, capabilities: WlSeatCapability) {
196 let data = &mut *self.data.borrow_mut();
197 if capabilities.contains(WlSeatCapability::POINTER) {
198 if data.pointer.is_some() {
199 return;
200 }
201 let pointer = data.seat.get_pointer();
202 let shape = self.wp_cursor_shape_manager_v1.get_pointer(&pointer);
203 proxy::set_event_handler_local(
204 &pointer,
205 PointerEventHandler {
206 shape: shape.clone(),
207 },
208 );
209 data.pointer = Some(pointer);
210 data.shape = Some(shape);
211 } else {
212 data.destroy_pointer();
213 }
214 }