1use slint::{
2 PhysicalSize, SharedString,
3 platform::{PointerEventButton, WindowEvent},
4};
5use smithay_client_toolkit::{
6 compositor::CompositorHandler,
7 output::{OutputHandler, OutputState},
8 reexports::{
9 client::{
10 Connection, QueueHandle,
11 protocol::{wl_output, wl_pointer, wl_seat, wl_surface},
12 },
13 protocols::wp::cursor_shape::v1::client::wp_cursor_shape_device_v1::Shape,
14 },
15 registry::{ProvidesRegistryState, RegistryState},
16 registry_handlers,
17 seat::{
18 Capability, SeatHandler, SeatState,
19 keyboard::{KeyboardHandler },
20 pointer::{PointerData, PointerEvent, PointerEventKind, PointerHandler},
21 },
22 session_lock::{
23 SessionLock, SessionLockHandler, SessionLockSurface, SessionLockSurfaceConfigure,
24 },
25 shm::{Shm, ShmHandler, slot::Buffer},
26};
27use tracing::{info, trace, warn};
28
29use crate::{
30 slint_adapter::SpellSkiaWinAdapter,
31 wayland_adapter::{SpellLock, way_helper::get_string},
32};
33
34impl ProvidesRegistryState for SpellLock {
35 fn registry(&mut self) -> &mut RegistryState {
36 &mut self.registry_state
37 }
38 registry_handlers![OutputState, SeatState];
39}
40
41impl ShmHandler for SpellLock {
42 fn shm_state(&mut self) -> &mut Shm {
43 &mut self.shm
44 }
45}
46
47impl OutputHandler for SpellLock {
48 fn output_state(&mut self) -> &mut OutputState {
49 &mut self.output_state
50 }
51
52 fn new_output(
53 &mut self,
54 _conn: &Connection,
55 _qh: &QueueHandle<Self>,
56 _output: wl_output::WlOutput,
57 ) {
58 info!("New output source added");
59 }
60
61 fn update_output(
62 &mut self,
63 _conn: &Connection,
64 _qh: &QueueHandle<Self>,
65 _output: wl_output::WlOutput,
66 ) {
67 info!("Updated output source");
68 }
69
70 fn output_destroyed(
71 &mut self,
72 _conn: &Connection,
73 _qh: &QueueHandle<Self>,
74 _output: wl_output::WlOutput,
75 ) {
76 info!("Output is destroyed");
77 }
78}
79
80impl CompositorHandler for SpellLock {
81 fn scale_factor_changed(
82 &mut self,
83 _conn: &Connection,
84 _qh: &QueueHandle<Self>,
85 _surface: &wl_surface::WlSurface,
86 _new_factor: i32,
87 ) {
88 info!("Scale factor changed");
89 }
90
91 fn transform_changed(
92 &mut self,
93 _conn: &Connection,
94 _qh: &QueueHandle<Self>,
95 _surface: &wl_surface::WlSurface,
96 _new_transform: wl_output::Transform,
97 ) {
98 info!("Compositor transformation changed");
99 }
100
101 fn frame(
102 &mut self,
103 _conn: &Connection,
104 qh: &QueueHandle<Self>,
105 _surface: &wl_surface::WlSurface,
106 _time: u32,
107 ) {
108 self.converter_lock(qh);
109 }
110
111 fn surface_enter(
112 &mut self,
113 _conn: &Connection,
114 _qh: &QueueHandle<Self>,
115 _surface: &wl_surface::WlSurface,
116 _output: &wl_output::WlOutput,
117 ) {
118 info!("Surface entered");
119 }
120
121 fn surface_leave(
122 &mut self,
123 _conn: &Connection,
124 _qh: &QueueHandle<Self>,
125 _surface: &wl_surface::WlSurface,
126 _output: &wl_output::WlOutput,
127 ) {
128 info!("Surface left");
129 }
130}
131
132impl SessionLockHandler for SpellLock {
133 fn locked(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _session_lock: SessionLock) {
134 info!("Session is locked");
135 }
136
137 fn finished(
138 &mut self,
139 _conn: &Connection,
140 _qh: &QueueHandle<Self>,
141 _session_lock: SessionLock,
142 ) {
143 info!("Session could not be locked");
144 self.is_locked = true;
145 }
146 fn configure(
147 &mut self,
148 _conn: &Connection,
149 qh: &QueueHandle<Self>,
150 _surface: SessionLockSurface,
151 _configure: SessionLockSurfaceConfigure,
152 _serial: u32,
153 ) {
154 self.converter_lock(qh);
155 }
156}
157
158impl KeyboardHandler for SpellLock {
159 fn enter(
160 &mut self,
161 _conn: &Connection,
162 _qh: &QueueHandle<Self>,
163 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
164 _surface: &smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
165 _serial: u32,
166 _raw: &[u32],
167 _keysyms: &[smithay_client_toolkit::seat::keyboard::Keysym],
168 ) {
169 info!("Keyboard focus entered");
170 }
171
172 fn leave(
173 &mut self,
174 _conn: &Connection,
175 _qh: &QueueHandle<Self>,
176 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
177 _surface: &smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
178 _serial: u32,
179 ) {
180 info!("Keyboard focus left");
181 }
182
183 fn press_key(
184 &mut self,
185 _conn: &Connection,
186 _qh: &QueueHandle<Self>,
187 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
188 _serial: u32,
189 event: smithay_client_toolkit::seat::keyboard::KeyEvent,
190 ) {
191 let string_val: SharedString = get_string(event);
192 info!("Key pressed with value : {:?}", string_val);
199 self.slint_part.as_ref().unwrap().adapters[0]
200 .try_dispatch_event(WindowEvent::KeyPressed { text: string_val })
201 .unwrap_or_else(|err| warn!("Key press event failed with error: {:?}", err));
202 }
204
205 fn release_key(
206 &mut self,
207 _conn: &Connection,
208 _qh: &QueueHandle<Self>,
209 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
210 _serial: u32,
211 event: smithay_client_toolkit::seat::keyboard::KeyEvent,
212 ) {
213 info!("Key is released");
214 let string_val: SharedString = get_string(event);
220 self.slint_part.as_ref().unwrap().adapters[0]
221 .try_dispatch_event(WindowEvent::KeyReleased { text: string_val })
222 .unwrap_or_else(|err| warn!("Key release event failed with error: {:?}", err));
223 }
224
225 fn update_modifiers(
227 &mut self,
228 _conn: &Connection,
229 _qh: &QueueHandle<Self>,
230 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
231 _serial: u32,
232 _modifiers: smithay_client_toolkit::seat::keyboard::Modifiers,
233 _raw_modifiers: smithay_client_toolkit::seat::keyboard::RawModifiers,
234 _layout: u32,
235 ) {
236 trace!("Updated modifiers");
237 }
238
239 fn repeat_key(
240 &mut self,
241 _conn: &Connection,
242 _qh: &QueueHandle<Self>,
243 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
244 _serial: u32,
245 _event: smithay_client_toolkit::seat::keyboard::KeyEvent,
246 ) {
247 trace!("Repeated key entered");
248 }
249 fn update_repeat_info(
251 &mut self,
252 _conn: &Connection,
253 _qh: &QueueHandle<Self>,
254 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
255 _info: smithay_client_toolkit::seat::keyboard::RepeatInfo,
256 ) {
257 trace!("Repeat info updation called");
258 }
259}
260
261impl SeatHandler for SpellLock {
262 fn seat_state(&mut self) -> &mut SeatState {
263 &mut self.seat_state
264 }
265
266 fn new_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
267
268 fn new_capability(
269 &mut self,
270 _conn: &Connection,
271 qh: &QueueHandle<Self>,
272 seat: wl_seat::WlSeat,
273 capability: Capability,
274 ) {
275 if capability == Capability::Keyboard && self.keyboard_state.board.is_none() {
276 info!("Setting keyboard capability");
277 let keyboard = self
278 .seat_state
279 .get_keyboard(qh, &seat, None)
280 .expect("Failed to create keyboard");
281 self.keyboard_state.board = Some(keyboard);
282 }
283 if capability == Capability::Pointer && self.pointer_state.pointer.is_none() {
284 info!("Setting pointer capability");
285 let pointer = self
286 .seat_state
287 .get_pointer(qh, &seat)
288 .expect("Failed to create pointer");
289 let pointer_data = PointerData::new(seat);
290 self.pointer_state.pointer = Some(pointer);
291 self.pointer_state.pointer_data = Some(pointer_data);
292 }
293 }
294
295 fn remove_capability(
296 &mut self,
297 _conn: &Connection,
298 _: &QueueHandle<Self>,
299 _: wl_seat::WlSeat,
300 capability: Capability,
301 ) {
302 if capability == Capability::Keyboard && self.keyboard_state.board.is_some() {
303 info!("Unsettting keyboard capability");
304 self.keyboard_state.board.take().unwrap().release();
305 }
306 if capability == Capability::Pointer && self.pointer_state.pointer.is_some() {
307 info!("Unsetting pointer capability");
308 self.pointer_state.pointer.take().unwrap().release();
309 }
310 }
311
312 fn remove_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
313}
314
315impl PointerHandler for SpellLock {
316 fn pointer_frame(
317 &mut self,
318 _conn: &Connection,
319 qh: &QueueHandle<Self>,
320 _pointer: &wl_pointer::WlPointer,
321 events: &[PointerEvent],
322 ) {
323 use PointerEventKind::*;
324 for event in events {
325 for surface in self.lock_surfaces.iter() {
327 if event.surface != *surface.wl_surface() {
328 continue;
329 }
330 }
331 match event.kind {
332 Enter { .. } => {
333 info!("Pointer entered: {:?}", event.position);
334
335 let pointer = &self.pointer_state.pointer.as_ref().unwrap();
337 let serial_no: Option<u32> = self
338 .pointer_state
339 .pointer_data
340 .as_ref()
341 .unwrap()
342 .latest_enter_serial();
343 if let Some(no) = serial_no {
344 self.pointer_state
345 .cursor_shape
346 .get_shape_device(pointer, qh)
347 .set_shape(no, Shape::Pointer);
348 }
349 }
350 Leave { .. } => {
351 info!("Pointer left: {:?}", event.position);
352 self.slint_part.as_ref().unwrap().adapters[0]
353 .try_dispatch_event(WindowEvent::PointerExited)
354 .unwrap_or_else(|err| {
355 warn!("Pointer left event failed with error: {:?}", err)
356 });
357 }
358 Motion { .. } => {
359 self.slint_part.as_ref().unwrap().adapters[0]
361 .try_dispatch_event(WindowEvent::PointerMoved {
362 position: slint::LogicalPosition {
363 x: event.position.0 as f32,
364 y: event.position.1 as f32,
365 },
366 })
367 .unwrap_or_else(|err| {
368 warn!("Pointer move event failed with error: {:?}", err)
369 });
370 }
371 Press { button, .. } => {
372 trace!("Press {:x} @ {:?}", button, event.position);
373 self.slint_part.as_ref().unwrap().adapters[0]
374 .try_dispatch_event(WindowEvent::PointerPressed {
375 position: slint::LogicalPosition {
376 x: event.position.0 as f32,
377 y: event.position.1 as f32,
378 },
379 button: PointerEventButton::Left,
380 })
381 .unwrap_or_else(|err| {
382 warn!("Pointer press event failed with error: {:?}", err)
383 });
384 }
385 Release { button, .. } => {
386 trace!("Release {:x} @ {:?}", button, event.position);
387 self.slint_part.as_ref().unwrap().adapters[0]
388 .try_dispatch_event(WindowEvent::PointerReleased {
389 position: slint::LogicalPosition {
390 x: event.position.0 as f32,
391 y: event.position.1 as f32,
392 },
393 button: PointerEventButton::Left,
394 })
395 .unwrap_or_else(|err| {
396 warn!("Pointer release event failed with error: {:?}", err)
397 });
398 }
399 Axis {
400 horizontal,
401 vertical,
402 ..
403 } => {
404 trace!("Scroll H:{horizontal:?}, V:{vertical:?}");
405 self.slint_part.as_ref().unwrap().adapters[0]
406 .try_dispatch_event(WindowEvent::PointerScrolled {
407 position: slint::LogicalPosition {
408 x: event.position.0 as f32,
409 y: event.position.1 as f32,
410 },
411 delta_x: horizontal.absolute as f32,
412 delta_y: vertical.absolute as f32,
413 })
414 .unwrap_or_else(|err| {
415 warn!("Pointer scroll event failed with error: {:?}", err)
416 });
417 }
418 }
419 }
420 }
421}
422pub struct SpellSlintLock {
424 pub(crate) adapters: Vec<std::rc::Rc<SpellSkiaWinAdapter>>,
425 pub(crate) size: Vec<PhysicalSize>,
426 pub(crate) wayland_buffer: Vec<Buffer>,
427}