spell_framework/wayland_adapter/
win_impl.rs

1use crate::wayland_adapter::{SpellWin, way_helper::get_string};
2// use owo_colors::OwoColorize;
3use slint::{
4    SharedString,
5    platform::{/*Key,*/ PointerEventButton, WindowEvent},
6};
7use smithay_client_toolkit::{
8    output::OutputState,
9    reexports::{
10        client::{
11            Connection, QueueHandle,
12            protocol::{wl_pointer, wl_seat},
13        },
14        protocols::wp::cursor_shape::v1::client::wp_cursor_shape_device_v1::Shape,
15    },
16    registry::{ProvidesRegistryState, RegistryState},
17    registry_handlers,
18    seat::{
19        Capability, SeatHandler, SeatState,
20        keyboard::{KeyboardHandler /* Keysym*/},
21        pointer::{PointerData, PointerEvent, PointerEventKind, PointerHandler},
22    },
23    shell::WaylandSurface,
24};
25use tracing::{info, trace};
26
27impl KeyboardHandler for SpellWin {
28    fn enter(
29        &mut self,
30        _conn: &Connection,
31        _qh: &QueueHandle<Self>,
32        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
33        _surface: &smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
34        _serial: u32,
35        _raw: &[u32],
36        _keysyms: &[smithay_client_toolkit::seat::keyboard::Keysym],
37    ) {
38        info!("Keyboard focus entered");
39    }
40
41    fn leave(
42        &mut self,
43        _conn: &Connection,
44        _qh: &QueueHandle<Self>,
45        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
46        _surface: &smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
47        _serial: u32,
48    ) {
49        info!("Keyboard focus left");
50    }
51
52    fn press_key(
53        &mut self,
54        _conn: &Connection,
55        _qh: &QueueHandle<Self>,
56        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
57        _serial: u32,
58        event: smithay_client_toolkit::seat::keyboard::KeyEvent,
59    ) {
60        trace!("Key pressed");
61        let string_val: SharedString = get_string(event);
62        // if string_val == <slint::platform::Key as Into<SharedString>>::into(Key::Backspace) {
63        //     self.loop_handle.enable(&self.backspace).unwrap();
64        //     self.adapter
65        //         .try_dispatch_event(WindowEvent::KeyPressed { text: string_val })
66        //         .unwrap();
67        // } else {
68        self.adapter
69            .try_dispatch_event(WindowEvent::KeyPressed { text: string_val })
70            .unwrap();
71        // }
72    }
73
74    fn release_key(
75        &mut self,
76        _conn: &Connection,
77        _qh: &QueueHandle<Self>,
78        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
79        _serial: u32,
80        /*mut*/ event: smithay_client_toolkit::seat::keyboard::KeyEvent,
81    ) {
82        trace!("Key released");
83        // if let Err(err) = self.loop_handle.disable(&self.backspace) {
84        //     warn!("{}", err);
85        // }
86        // let key_sym = Keysym::new(event.raw_code);
87        // event.keysym = key_sym;
88        let string_val: SharedString = get_string(event);
89        self.adapter
90            .try_dispatch_event(WindowEvent::KeyReleased { text: string_val })
91            .unwrap();
92    }
93
94    // TODO needs to be implemented to enable functionalities of ctl, shift, alt etc.
95    fn update_modifiers(
96        &mut self,
97        _conn: &Connection,
98        _qh: &QueueHandle<Self>,
99        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
100        _serial: u32,
101        _modifiers: smithay_client_toolkit::seat::keyboard::Modifiers,
102        _raw_modifiers: smithay_client_toolkit::seat::keyboard::RawModifiers,
103        _layout: u32,
104    ) {
105    }
106    // TODO This method needs to be implemented after the looping mecha is changed to calloop.
107    fn update_repeat_info(
108        &mut self,
109        _conn: &Connection,
110        _qh: &QueueHandle<Self>,
111        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
112        _info: smithay_client_toolkit::seat::keyboard::RepeatInfo,
113    ) {
114    }
115
116    fn repeat_key(
117        &mut self,
118        _conn: &Connection,
119        _qh: &QueueHandle<Self>,
120        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
121        _serial: u32,
122        _event: smithay_client_toolkit::seat::keyboard::KeyEvent,
123    ) {
124    }
125}
126
127impl SeatHandler for SpellWin {
128    fn seat_state(&mut self) -> &mut SeatState {
129        &mut self.states.seat_state
130    }
131
132    fn new_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
133
134    fn new_capability(
135        &mut self,
136        _conn: &Connection,
137        qh: &QueueHandle<Self>,
138        seat: wl_seat::WlSeat,
139        capability: Capability,
140    ) {
141        if capability == Capability::Keyboard && self.states.keyboard_state.board.is_none() {
142            info!("Setting keyboard capability");
143            let keyboard = self
144                .states
145                .seat_state
146                .get_keyboard(qh, &seat, None)
147                .expect("Failed to create keyboard");
148            self.states.keyboard_state.board = Some(keyboard);
149        }
150        if capability == Capability::Pointer && self.states.pointer_state.pointer.is_none() {
151            info!("Setting pointer capability");
152            let pointer = self
153                .states
154                .seat_state
155                .get_pointer(qh, &seat)
156                .expect("Failed to create pointer");
157            let pointer_data = PointerData::new(seat);
158            self.states.pointer_state.pointer = Some(pointer);
159            self.states.pointer_state.pointer_data = Some(pointer_data);
160        }
161    }
162
163    fn remove_capability(
164        &mut self,
165        _conn: &Connection,
166        _: &QueueHandle<Self>,
167        _: wl_seat::WlSeat,
168        capability: Capability,
169    ) {
170        if capability == Capability::Keyboard && self.states.keyboard_state.board.is_some() {
171            info!("Unsetting keyboard capability");
172            self.states.keyboard_state.board.take().unwrap().release();
173        }
174
175        if capability == Capability::Pointer && self.states.pointer_state.pointer.is_some() {
176            info!("Unsetting pointer capability");
177            self.states.pointer_state.pointer.take().unwrap().release();
178        }
179    }
180
181    fn remove_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
182}
183
184impl PointerHandler for SpellWin {
185    fn pointer_frame(
186        &mut self,
187        _conn: &Connection,
188        qh: &QueueHandle<Self>,
189        _pointer: &wl_pointer::WlPointer,
190        events: &[PointerEvent],
191    ) {
192        use PointerEventKind::*;
193        for event in events {
194            // Ignore events for other surfaces
195            if &event.surface != self.layer.wl_surface() {
196                continue;
197            }
198            match event.kind {
199                Enter { .. } => {
200                    info!("Pointer entered: {:?}", event.position);
201
202                    // TODO this code is redundent, as it doesn't set the cursor shape.
203                    let pointer = &self.states.pointer_state.pointer.as_ref().unwrap();
204                    let serial_no: Option<u32> = self
205                        .states
206                        .pointer_state
207                        .pointer_data
208                        .as_ref()
209                        .unwrap()
210                        .latest_enter_serial();
211                    if let Some(no) = serial_no {
212                        self.states
213                            .pointer_state
214                            .cursor_shape
215                            .get_shape_device(pointer, qh)
216                            .set_shape(no, Shape::Pointer);
217                        // self.layer.commit();
218                    }
219                }
220                Leave { .. } => {
221                    info!("Pointer left: {:?}", event.position);
222                    self.adapter
223                        .try_dispatch_event(WindowEvent::PointerExited)
224                        .unwrap();
225                }
226                Motion { .. } => {
227                    // debug!("Pointer entered @{:?}", event.position);
228                    self.adapter
229                        .try_dispatch_event(WindowEvent::PointerMoved {
230                            position: slint::LogicalPosition {
231                                x: event.position.0 as f32,
232                                y: event.position.1 as f32,
233                            },
234                        })
235                        .unwrap();
236                }
237                Press { button, .. } => {
238                    trace!("Press {:x} @ {:?}", button, event.position);
239                    self.adapter
240                        .try_dispatch_event(WindowEvent::PointerPressed {
241                            position: slint::LogicalPosition {
242                                x: event.position.0 as f32,
243                                y: event.position.1 as f32,
244                            },
245                            button: PointerEventButton::Left,
246                        })
247                        .unwrap();
248                }
249                Release { button, .. } => {
250                    trace!("Release {:x} @ {:?}", button, event.position);
251                    self.adapter
252                        .try_dispatch_event(WindowEvent::PointerReleased {
253                            position: slint::LogicalPosition {
254                                x: event.position.0 as f32,
255                                y: event.position.1 as f32,
256                            },
257                            button: PointerEventButton::Left,
258                        })
259                        .unwrap();
260                }
261                Axis {
262                    horizontal,
263                    vertical,
264                    ..
265                } => {
266                    trace!("Scroll H:{horizontal:?}, V:{vertical:?}");
267                    self.adapter
268                        .try_dispatch_event(WindowEvent::PointerScrolled {
269                            position: slint::LogicalPosition {
270                                x: event.position.0 as f32,
271                                y: event.position.1 as f32,
272                            },
273                            delta_x: horizontal.absolute as f32,
274                            delta_y: vertical.absolute as f32,
275                        })
276                        .unwrap();
277                }
278            }
279        }
280    }
281}
282
283// TODO FIND What is the use of registery_handlers here?
284impl ProvidesRegistryState for SpellWin {
285    fn registry(&mut self) -> &mut RegistryState {
286        &mut self.states.registry_state
287    }
288    registry_handlers![OutputState, SeatState];
289}