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 touch::TouchHandler,
22 },
23 session_lock::{
24 SessionLock, SessionLockHandler, SessionLockSurface, SessionLockSurfaceConfigure,
25 },
26 shm::{Shm, ShmHandler, slot::Buffer},
27};
28use tracing::{info, trace, warn};
29
30use crate::{
31 slint_adapter::SpellSkiaWinAdapter,
32 wayland_adapter::{SpellLock, way_helper::get_string},
33};
34
35impl ProvidesRegistryState for SpellLock {
36 fn registry(&mut self) -> &mut RegistryState {
37 &mut self.registry_state
38 }
39 registry_handlers![OutputState, SeatState];
40}
41
42impl ShmHandler for SpellLock {
43 fn shm_state(&mut self) -> &mut Shm {
44 &mut self.shm
45 }
46}
47
48impl OutputHandler for SpellLock {
49 fn output_state(&mut self) -> &mut OutputState {
50 &mut self.output_state
51 }
52
53 fn new_output(
54 &mut self,
55 _conn: &Connection,
56 _qh: &QueueHandle<Self>,
57 _output: wl_output::WlOutput,
58 ) {
59 info!("New output source added");
60 }
61
62 fn update_output(
63 &mut self,
64 _conn: &Connection,
65 _qh: &QueueHandle<Self>,
66 _output: wl_output::WlOutput,
67 ) {
68 info!("Updated output source");
69 }
70
71 fn output_destroyed(
72 &mut self,
73 _conn: &Connection,
74 _qh: &QueueHandle<Self>,
75 _output: wl_output::WlOutput,
76 ) {
77 info!("Output is destroyed");
78 }
79}
80
81impl CompositorHandler for SpellLock {
82 fn scale_factor_changed(
83 &mut self,
84 _conn: &Connection,
85 _qh: &QueueHandle<Self>,
86 _surface: &wl_surface::WlSurface,
87 _new_factor: i32,
88 ) {
89 info!("Scale factor changed");
90 }
91
92 fn transform_changed(
93 &mut self,
94 _conn: &Connection,
95 _qh: &QueueHandle<Self>,
96 _surface: &wl_surface::WlSurface,
97 _new_transform: wl_output::Transform,
98 ) {
99 info!("Compositor transformation changed");
100 }
101
102 fn frame(
103 &mut self,
104 _conn: &Connection,
105 qh: &QueueHandle<Self>,
106 _surface: &wl_surface::WlSurface,
107 _time: u32,
108 ) {
109 self.converter_lock(qh);
110 }
111
112 fn surface_enter(
113 &mut self,
114 _conn: &Connection,
115 _qh: &QueueHandle<Self>,
116 _surface: &wl_surface::WlSurface,
117 _output: &wl_output::WlOutput,
118 ) {
119 info!("Surface entered");
120 }
121
122 fn surface_leave(
123 &mut self,
124 _conn: &Connection,
125 _qh: &QueueHandle<Self>,
126 _surface: &wl_surface::WlSurface,
127 _output: &wl_output::WlOutput,
128 ) {
129 info!("Surface left");
130 }
131}
132
133impl SessionLockHandler for SpellLock {
134 fn locked(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _session_lock: SessionLock) {
135 info!("Session is locked");
136 }
137
138 fn finished(
139 &mut self,
140 _conn: &Connection,
141 _qh: &QueueHandle<Self>,
142 _session_lock: SessionLock,
143 ) {
144 info!("Session could not be locked");
145 self.is_locked = true;
146 }
147 fn configure(
148 &mut self,
149 _conn: &Connection,
150 qh: &QueueHandle<Self>,
151 _surface: SessionLockSurface,
152 _configure: SessionLockSurfaceConfigure,
153 _serial: u32,
154 ) {
155 self.converter_lock(qh);
156 }
157}
158
159impl KeyboardHandler for SpellLock {
160 fn enter(
161 &mut self,
162 _conn: &Connection,
163 _qh: &QueueHandle<Self>,
164 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
165 _surface: &smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
166 _serial: u32,
167 _raw: &[u32],
168 _keysyms: &[smithay_client_toolkit::seat::keyboard::Keysym],
169 ) {
170 info!("Keyboard focus entered");
171 }
172
173 fn leave(
174 &mut self,
175 _conn: &Connection,
176 _qh: &QueueHandle<Self>,
177 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
178 _surface: &smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
179 _serial: u32,
180 ) {
181 info!("Keyboard focus left");
182 }
183
184 fn press_key(
185 &mut self,
186 _conn: &Connection,
187 _qh: &QueueHandle<Self>,
188 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
189 _serial: u32,
190 event: smithay_client_toolkit::seat::keyboard::KeyEvent,
191 ) {
192 let string_val: SharedString = get_string(event);
193 info!("Key pressed with value : {:?}", string_val);
200 self.slint_part.as_ref().unwrap().adapters[0]
201 .try_dispatch_event(WindowEvent::KeyPressed { text: string_val })
202 .unwrap_or_else(|err| warn!("Key press event failed with error: {:?}", err));
203 }
205
206 fn release_key(
207 &mut self,
208 _conn: &Connection,
209 _qh: &QueueHandle<Self>,
210 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
211 _serial: u32,
212 event: smithay_client_toolkit::seat::keyboard::KeyEvent,
213 ) {
214 info!("Key is released");
215 let string_val: SharedString = get_string(event);
221 self.slint_part.as_ref().unwrap().adapters[0]
222 .try_dispatch_event(WindowEvent::KeyReleased { text: string_val })
223 .unwrap_or_else(|err| warn!("Key release event failed with error: {:?}", err));
224 }
225
226 fn update_modifiers(
228 &mut self,
229 _conn: &Connection,
230 _qh: &QueueHandle<Self>,
231 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
232 _serial: u32,
233 _modifiers: smithay_client_toolkit::seat::keyboard::Modifiers,
234 _raw_modifiers: smithay_client_toolkit::seat::keyboard::RawModifiers,
235 _layout: u32,
236 ) {
237 trace!("Updated modifiers");
238 }
239
240 fn repeat_key(
241 &mut self,
242 _conn: &Connection,
243 _qh: &QueueHandle<Self>,
244 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
245 _serial: u32,
246 _event: smithay_client_toolkit::seat::keyboard::KeyEvent,
247 ) {
248 trace!("Repeated key entered");
249 }
250 fn update_repeat_info(
252 &mut self,
253 _conn: &Connection,
254 _qh: &QueueHandle<Self>,
255 _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
256 _info: smithay_client_toolkit::seat::keyboard::RepeatInfo,
257 ) {
258 trace!("Repeat info updation called");
259 }
260}
261
262impl SeatHandler for SpellLock {
263 fn seat_state(&mut self) -> &mut SeatState {
264 &mut self.seat_state
265 }
266
267 fn new_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
268
269 fn new_capability(
270 &mut self,
271 _conn: &Connection,
272 qh: &QueueHandle<Self>,
273 seat: wl_seat::WlSeat,
274 capability: Capability,
275 ) {
276 if capability == Capability::Keyboard && self.keyboard_state.is_none() {
277 info!("Setting keyboard capability");
278 let keyboard = self
279 .seat_state
280 .get_keyboard(qh, &seat, None)
281 .expect("Failed to create keyboard");
282 self.keyboard_state = Some(keyboard);
283 }
284 if capability == Capability::Touch && self.touch_state.is_none() {
285 info!("Setting touch Capability");
286 let touch = self
287 .seat_state
288 .get_touch(qh, &seat)
289 .expect("Failed to create touch");
290 self.touch_state = Some(touch);
291 }
292 if capability == Capability::Pointer && self.pointer_state.pointer.is_none() {
293 info!("Setting pointer capability");
294 let pointer = self
295 .seat_state
296 .get_pointer(qh, &seat)
297 .expect("Failed to create pointer");
298 let pointer_data = PointerData::new(seat);
299 self.pointer_state.pointer = Some(pointer);
300 self.pointer_state.pointer_data = Some(pointer_data);
301 }
302 }
303
304 fn remove_capability(
305 &mut self,
306 _conn: &Connection,
307 _: &QueueHandle<Self>,
308 _: wl_seat::WlSeat,
309 capability: Capability,
310 ) {
311 if capability == Capability::Keyboard && self.keyboard_state.is_some() {
312 info!("Unsettting keyboard capability");
313 self.keyboard_state.take().unwrap().release();
314 }
315 if capability == Capability::Pointer && self.pointer_state.pointer.is_some() {
316 info!("Unsetting pointer capability");
317 self.pointer_state.pointer.take().unwrap().release();
318 }
319 if capability == Capability::Touch && self.touch_state.is_some() {
320 info!("Unsetting pointer capability");
321 self.touch_state.take().unwrap().release();
322 }
323 }
324
325 fn remove_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
326}
327
328impl PointerHandler for SpellLock {
329 fn pointer_frame(
330 &mut self,
331 _conn: &Connection,
332 qh: &QueueHandle<Self>,
333 _pointer: &wl_pointer::WlPointer,
334 events: &[PointerEvent],
335 ) {
336 use PointerEventKind::*;
337 for event in events {
338 for surface in self.lock_surfaces.iter() {
340 if event.surface != *surface.wl_surface() {
341 continue;
342 }
343 }
344 match event.kind {
345 Enter { .. } => {
346 info!("Pointer entered: {:?}", event.position);
347
348 let pointer = &self.pointer_state.pointer.as_ref().unwrap();
350 let serial_no: Option<u32> = self
351 .pointer_state
352 .pointer_data
353 .as_ref()
354 .unwrap()
355 .latest_enter_serial();
356 if let Some(no) = serial_no {
357 self.pointer_state
358 .cursor_shape
359 .get_shape_device(pointer, qh)
360 .set_shape(no, Shape::Pointer);
361 }
362 }
363 Leave { .. } => {
364 info!("Pointer left: {:?}", event.position);
365 self.slint_part.as_ref().unwrap().adapters[0]
366 .try_dispatch_event(WindowEvent::PointerExited)
367 .unwrap_or_else(|err| {
368 warn!("Pointer left event failed with error: {:?}", err)
369 });
370 }
371 Motion { .. } => {
372 self.slint_part.as_ref().unwrap().adapters[0]
374 .try_dispatch_event(WindowEvent::PointerMoved {
375 position: slint::LogicalPosition {
376 x: event.position.0 as f32,
377 y: event.position.1 as f32,
378 },
379 })
380 .unwrap_or_else(|err| {
381 warn!("Pointer move event failed with error: {:?}", err)
382 });
383 }
384 Press { button, .. } => {
385 trace!("Press {:x} @ {:?}", button, event.position);
386 self.slint_part.as_ref().unwrap().adapters[0]
387 .try_dispatch_event(WindowEvent::PointerPressed {
388 position: slint::LogicalPosition {
389 x: event.position.0 as f32,
390 y: event.position.1 as f32,
391 },
392 button: PointerEventButton::Left,
393 })
394 .unwrap_or_else(|err| {
395 warn!("Pointer press event failed with error: {:?}", err)
396 });
397 }
398 Release { button, .. } => {
399 trace!("Release {:x} @ {:?}", button, event.position);
400 self.slint_part.as_ref().unwrap().adapters[0]
401 .try_dispatch_event(WindowEvent::PointerReleased {
402 position: slint::LogicalPosition {
403 x: event.position.0 as f32,
404 y: event.position.1 as f32,
405 },
406 button: PointerEventButton::Left,
407 })
408 .unwrap_or_else(|err| {
409 warn!("Pointer release event failed with error: {:?}", err)
410 });
411 }
412 Axis {
413 horizontal,
414 vertical,
415 ..
416 } => {
417 trace!("Scroll H:{horizontal:?}, V:{vertical:?}");
418 self.slint_part.as_ref().unwrap().adapters[0]
419 .try_dispatch_event(WindowEvent::PointerScrolled {
420 position: slint::LogicalPosition {
421 x: event.position.0 as f32,
422 y: event.position.1 as f32,
423 },
424 delta_x: horizontal.absolute as f32,
425 delta_y: vertical.absolute as f32,
426 })
427 .unwrap_or_else(|err| {
428 warn!("Pointer scroll event failed with error: {:?}", err)
429 });
430 }
431 }
432 }
433 }
434}
435
436impl TouchHandler for SpellLock {
437 fn up(
438 &mut self,
439 _conn: &Connection,
440 _qh: &QueueHandle<Self>,
441 _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
442 _serial: u32,
443 _time: u32,
444 _id: i32,
445 ) {
446 info!("Up event from touch");
447 }
448 fn down(
449 &mut self,
450 _conn: &Connection,
451 _qh: &QueueHandle<Self>,
452 _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
453 _serial: u32,
454 _time: u32,
455 _surface: smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
456 _id: i32,
457 position: (f64, f64),
458 ) {
459 info!("Down event produced with posaition: {position:?}");
460 }
461
462 fn motion(
463 &mut self,
464 _conn: &Connection,
465 _qh: &QueueHandle<Self>,
466 _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
467 _time: u32,
468 _id: i32,
469 position: (f64, f64),
470 ) {
471 self.slint_part.as_ref().unwrap().adapters[0]
472 .try_dispatch_event(WindowEvent::PointerMoved {
473 position: slint::LogicalPosition {
474 x: position.0 as f32,
475 y: position.1 as f32,
476 },
477 })
478 .unwrap_or_else(|err| warn!("Touch move event failed with error: {:?}", err));
479 }
480
481 fn shape(
482 &mut self,
483 _conn: &Connection,
484 _qh: &QueueHandle<Self>,
485 _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
486 _id: i32,
487 major: f64,
488 minor: f64,
489 ) {
490 info!("Shape data released. Major: {major}, Minor: {minor}");
491 }
492 fn orientation(
493 &mut self,
494 _conn: &Connection,
495 _qh: &QueueHandle<Self>,
496 _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
497 _id: i32,
498 orientation: f64,
499 ) {
500 info!("Orientation data released: {orientation}.")
501 }
502 fn cancel(
503 &mut self,
504 _conn: &Connection,
505 _qh: &QueueHandle<Self>,
506 _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
507 ) {
508 info!("Active touch sequence cancelled");
509 }
510}
511pub struct SpellSlintLock {
513 pub(crate) adapters: Vec<std::rc::Rc<SpellSkiaWinAdapter>>,
514 pub(crate) size: Vec<PhysicalSize>,
515 pub(crate) wayland_buffer: Vec<Buffer>,
516}