Skip to main content

spell_framework/wayland_adapter/window/
input.rs

1use crate::{
2    slint_adapter::SpellSkiaWinAdapter,
3    wayland_adapter::{SpellWin, common, common::get_string},
4};
5use slint::{SharedString, platform::WindowEvent};
6use smithay_client_toolkit::{
7    reexports::client::{Connection, QueueHandle, protocol::wl_pointer},
8    seat::{
9        keyboard::KeyboardHandler,
10        pointer::{PointerEvent, PointerEventKind, PointerHandler},
11        touch::TouchHandler,
12    },
13    shell::WaylandSurface,
14};
15use tracing::{info, trace, warn};
16
17// Slint doesn't hve very specific
18// APIs for touch support (I think). I am talking with them on what
19// can be done so that things like multi-touch support, gestures etc
20// can be made possible. For now I am going to place empty value in here.
21impl TouchHandler for SpellWin {
22    fn up(
23        &mut self,
24        _conn: &Connection,
25        _qh: &QueueHandle<Self>,
26        _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
27        _serial: u32,
28        _time: u32,
29        _id: i32,
30    ) {
31        info!("Up event from touch");
32    }
33    fn down(
34        &mut self,
35        _conn: &Connection,
36        _qh: &QueueHandle<Self>,
37        _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
38        _serial: u32,
39        _time: u32,
40        _surface: smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
41        _id: i32,
42        position: (f64, f64),
43    ) {
44        info!("Down event produced with posaition: {position:?}");
45    }
46
47    fn motion(
48        &mut self,
49        _conn: &Connection,
50        _qh: &QueueHandle<Self>,
51        _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
52        _time: u32,
53        _id: i32,
54        position: (f64, f64),
55    ) {
56        self.adapter
57            .as_ref()
58            .unwrap()
59            .try_dispatch_event(WindowEvent::PointerMoved {
60                position: slint::LogicalPosition {
61                    x: position.0 as f32,
62                    y: position.1 as f32,
63                },
64            })
65            .unwrap_or_else(|err| warn!("Touch move event failed with error: {:?}", err));
66    }
67
68    fn shape(
69        &mut self,
70        _conn: &Connection,
71        _qh: &QueueHandle<Self>,
72        _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
73        _id: i32,
74        major: f64,
75        minor: f64,
76    ) {
77        info!("Shape data released. Major: {major}, Minor: {minor}");
78    }
79    fn orientation(
80        &mut self,
81        _conn: &Connection,
82        _qh: &QueueHandle<Self>,
83        _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
84        _id: i32,
85        orientation: f64,
86    ) {
87        info!("Orientation data released: {orientation}.")
88    }
89    fn cancel(
90        &mut self,
91        _conn: &Connection,
92        _qh: &QueueHandle<Self>,
93        _touch: &smithay_client_toolkit::reexports::client::protocol::wl_touch::WlTouch,
94    ) {
95        info!("Active touch sequence cancelled");
96    }
97}
98
99impl PointerHandler for SpellWin {
100    fn pointer_frame(
101        &mut self,
102        _conn: &Connection,
103        _qh: &QueueHandle<Self>,
104        _pointer: &wl_pointer::WlPointer,
105        events: &[PointerEvent],
106    ) {
107        use PointerEventKind::*;
108        for event in events {
109            let adapter: &std::rc::Rc<SpellSkiaWinAdapter> =
110                if let Some(popup) = self.popup_manager.return_adapter(&event.surface) {
111                    popup
112                } else if &event.surface == self.layer.as_ref().unwrap().wl_surface() {
113                    self.adapter.as_ref().unwrap()
114                } else {
115                    continue;
116                };
117
118            match event.kind {
119                Enter { serial } => {
120                    trace!(
121                        "Pointer entered with serial {:?} at: {:?}",
122                        serial, event.position
123                    );
124
125                    adapter
126                        .try_dispatch_event(WindowEvent::PointerMoved {
127                            position: slint::LogicalPosition {
128                                x: event.position.0 as f32,
129                                y: event.position.1 as f32,
130                            },
131                        })
132                        .unwrap_or_else(|err| {
133                            warn!(
134                                "Pointer move event after entry failed with error: {:?}",
135                                err
136                            )
137                        });
138                    self.states.pointer_state.last_cursor_enter_serial = Some(serial);
139                }
140                Leave { .. } => {
141                    trace!("Pointer left: {:?}", event.position);
142
143                    adapter
144                        .try_dispatch_event(WindowEvent::PointerExited)
145                        .unwrap_or_else(|err| {
146                            warn!("Pointer exit event failed with error: {:?}", err)
147                        });
148                }
149                Motion { .. } => {
150                    trace!("Pointer entered @{:?}", event.position);
151
152                    adapter
153                        .try_dispatch_event(WindowEvent::PointerMoved {
154                            position: slint::LogicalPosition {
155                                x: event.position.0 as f32,
156                                y: event.position.1 as f32,
157                            },
158                        })
159                        .unwrap_or_else(|err| {
160                            warn!("Pointer move event failed with error: {:?}", err)
161                        });
162                }
163                Press { button, .. } => {
164                    trace!("Press {:?} @ {:?}", button, event.position);
165
166                    adapter
167                        .try_dispatch_event(WindowEvent::PointerPressed {
168                            position: slint::LogicalPosition {
169                                x: event.position.0 as f32,
170                                y: event.position.1 as f32,
171                            },
172                            button: common::map_pointer_button(button),
173                        })
174                        .unwrap_or_else(|err| {
175                            warn!("Pointer press event failed with error: {:?}", err)
176                        });
177                }
178                Release { button, .. } => {
179                    trace!("Release {:?} @ {:?}", button, event.position);
180
181                    adapter
182                        .try_dispatch_event(WindowEvent::PointerReleased {
183                            position: slint::LogicalPosition {
184                                x: event.position.0 as f32,
185                                y: event.position.1 as f32,
186                            },
187                            button: common::map_pointer_button(button),
188                        })
189                        .unwrap_or_else(|err| {
190                            warn!("Pointer release event failed with error: {:?}", err)
191                        });
192                }
193                Axis {
194                    horizontal,
195                    vertical,
196                    ..
197                } => {
198                    trace!("Scroll H:{horizontal:?}, V:{vertical:?}");
199
200                    if !self.natural_scroll {
201                        adapter
202                            .try_dispatch_event(WindowEvent::PointerScrolled {
203                                position: slint::LogicalPosition {
204                                    x: event.position.0 as f32,
205                                    y: event.position.1 as f32,
206                                },
207                                delta_x: horizontal.absolute as f32,
208                                delta_y: vertical.absolute as f32,
209                            })
210                            .unwrap_or_else(|err| {
211                                warn!("Pointer scroll event failed with error: {:?}", err)
212                            });
213                    } else {
214                        adapter
215                            .try_dispatch_event(WindowEvent::PointerScrolled {
216                                position: slint::LogicalPosition {
217                                    x: event.position.0 as f32,
218                                    y: event.position.1 as f32,
219                                },
220                                delta_x: -horizontal.absolute as f32,
221                                delta_y: -vertical.absolute as f32,
222                            })
223                            .unwrap_or_else(|err| {
224                                warn!("Pointer scroll event failed with error: {:?}", err)
225                            });
226                    }
227                }
228            }
229        }
230    }
231}
232
233impl KeyboardHandler for SpellWin {
234    fn enter(
235        &mut self,
236        _conn: &Connection,
237        _qh: &QueueHandle<Self>,
238        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
239        _surface: &smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
240        _serial: u32,
241        _raw: &[u32],
242        _keysyms: &[smithay_client_toolkit::seat::keyboard::Keysym],
243    ) {
244        info!("Keyboard focus entered");
245    }
246
247    fn leave(
248        &mut self,
249        _conn: &Connection,
250        _qh: &QueueHandle<Self>,
251        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
252        _surface: &smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface,
253        _serial: u32,
254    ) {
255        info!("Keyboard focus left");
256    }
257
258    fn press_key(
259        &mut self,
260        _conn: &Connection,
261        _qh: &QueueHandle<Self>,
262        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
263        _serial: u32,
264        event: smithay_client_toolkit::seat::keyboard::KeyEvent,
265    ) {
266        trace!("Key pressed");
267        let string_val: SharedString = get_string(event);
268        // if string_val == <slint::platform::Key as Into<SharedString>>::into(Key::Backspace) {
269        //     self.loop_handle.enable(&self.backspace).unwrap();
270        //     self.adapter
271        //         .try_dispatch_event(WindowEvent::KeyPressed { text: string_val })
272        //         .unwrap();
273        // } else {
274        self.adapter
275            .as_ref()
276            .unwrap()
277            .try_dispatch_event(WindowEvent::KeyPressed { text: string_val })
278            .unwrap_or_else(|err| warn!("Key press event failed with error: {:?}", err));
279        // }
280    }
281
282    fn release_key(
283        &mut self,
284        _conn: &Connection,
285        _qh: &QueueHandle<Self>,
286        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
287        _serial: u32,
288        /*mut*/ event: smithay_client_toolkit::seat::keyboard::KeyEvent,
289    ) {
290        trace!("Key released");
291        // if let Err(err) = self.loop_handle.disable(&self.backspace) {
292        //     warn!("{}", err);
293        // }
294        // let key_sym = Keysym::new(event.raw_code);
295        // event.keysym = key_sym;
296        let string_val: SharedString = get_string(event);
297        self.adapter
298            .as_ref()
299            .unwrap()
300            .try_dispatch_event(WindowEvent::KeyReleased { text: string_val })
301            .unwrap_or_else(|err| warn!("Key release event failed with error: {:?}", err));
302    }
303
304    // TODO needs to be implemented to enable functionalities of ctl, shift, alt etc.
305    fn update_modifiers(
306        &mut self,
307        _conn: &Connection,
308        _qh: &QueueHandle<Self>,
309        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
310        _serial: u32,
311        _modifiers: smithay_client_toolkit::seat::keyboard::Modifiers,
312        _raw_modifiers: smithay_client_toolkit::seat::keyboard::RawModifiers,
313        _layout: u32,
314    ) {
315    }
316    // TODO This method needs to be implemented after the looping mecha is changed to calloop.
317    fn update_repeat_info(
318        &mut self,
319        _conn: &Connection,
320        _qh: &QueueHandle<Self>,
321        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
322        _info: smithay_client_toolkit::seat::keyboard::RepeatInfo,
323    ) {
324        trace!("Key repeat info updated");
325    }
326
327    fn repeat_key(
328        &mut self,
329        _conn: &Connection,
330        _qh: &QueueHandle<Self>,
331        _keyboard: &smithay_client_toolkit::reexports::client::protocol::wl_keyboard::WlKeyboard,
332        _serial: u32,
333        _event: smithay_client_toolkit::seat::keyboard::KeyEvent,
334    ) {
335        trace!("Repeat key called");
336    }
337}