spell_framework/wayland_adapter/window/
wayland.rs1use crate::wayland_adapter::{fractional_scaling::FractionalScaleHandler, window::SpellWin};
2use slint::platform::WindowAdapter;
3use smithay_client_toolkit::{
4 compositor::CompositorHandler,
5 output::{OutputHandler, OutputState},
6 reexports::{
7 client::{
8 Connection, Dispatch, QueueHandle,
9 protocol::{wl_output, wl_seat, wl_surface},
10 },
11 protocols::xdg::shell::client::xdg_surface::XdgSurface,
12 },
13 registry::{ProvidesRegistryState, RegistryState},
14 registry_handlers,
15 seat::{Capability, SeatHandler, SeatState, pointer::PointerData},
16 shell::{
17 WaylandSurface,
18 wlr_layer::{LayerShellHandler, LayerSurface, LayerSurfaceConfigure},
19 xdg::{popup::PopupHandler, window::WindowHandler},
20 },
21 shm::{Shm, ShmHandler},
22};
23use tracing::{info, trace, warn};
24
25impl WindowHandler for SpellWin {
26 fn request_close(
27 &mut self,
28 _: &Connection,
29 _: &QueueHandle<Self>,
30 _: &smithay_client_toolkit::shell::xdg::window::Window,
31 ) {
32 todo!()
33 }
34
35 fn configure(
36 &mut self,
37 _: &Connection,
38 _: &QueueHandle<Self>,
39 _: &smithay_client_toolkit::shell::xdg::window::Window,
40 _: smithay_client_toolkit::shell::xdg::window::WindowConfigure,
41 _: u32,
42 ) {
43 todo!()
44 }
45}
46
47impl SeatHandler for SpellWin {
48 fn seat_state(&mut self) -> &mut SeatState {
49 &mut self.states.seat_state
50 }
51
52 fn new_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
53
54 fn new_capability(
55 &mut self,
56 _conn: &Connection,
57 qh: &QueueHandle<Self>,
58 seat: wl_seat::WlSeat,
59 capability: Capability,
60 ) {
61 if capability == Capability::Keyboard && self.states.keyboard_state.is_none() {
62 info!("Setting keyboard capability");
63 let keyboard = self
64 .states
65 .seat_state
66 .get_keyboard(qh, &seat, None)
67 .expect("Failed to create keyboard");
68 self.states.keyboard_state = Some(keyboard);
69 }
70 if capability == Capability::Touch && self.states.touch_state.is_none() {
71 info!("Setting touch Capability");
72 let touch = self
73 .states
74 .seat_state
75 .get_touch(qh, &seat)
76 .expect("Failed to create touch");
77 self.states.touch_state = Some(touch);
78 }
79 if capability == Capability::Pointer && self.states.pointer_state.pointer.is_none() {
80 info!("Setting pointer capability");
81 let pointer = self
82 .states
83 .seat_state
84 .get_pointer(qh, &seat)
85 .expect("Failed to create pointer");
86 let pointer_data = PointerData::new(seat);
87 self.states.pointer_state.pointer = Some(pointer);
88 self.states.pointer_state.pointer_data = Some(pointer_data);
89 }
90 }
91
92 fn remove_capability(
93 &mut self,
94 _conn: &Connection,
95 _: &QueueHandle<Self>,
96 _: wl_seat::WlSeat,
97 capability: Capability,
98 ) {
99 if capability == Capability::Keyboard && self.states.keyboard_state.is_some() {
100 info!("Unsetting keyboard capability");
101 self.states.keyboard_state.take().unwrap().release();
102 }
103
104 if capability == Capability::Pointer && self.states.pointer_state.pointer.is_some() {
105 info!("Unsetting pointer capability");
106 self.states.pointer_state.pointer.take().unwrap().release();
107 }
108 if capability == Capability::Touch && self.states.touch_state.is_some() {
109 info!("Unsetting pointer capability");
110 self.states.touch_state.take().unwrap().release();
111 }
112 }
113
114 fn remove_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
115}
116
117impl PopupHandler for SpellWin {
118 fn configure(
119 &mut self,
120 _: &Connection,
121 _: &QueueHandle<Self>,
122 popup: &smithay_client_toolkit::shell::xdg::popup::Popup,
123 _: smithay_client_toolkit::shell::xdg::popup::PopupConfigure,
124 ) {
125 let x = self.popup_manager.return_popup(popup);
126 if let Some(current_popup) = x {
127 current_popup.inner().wl_surface().commit();
129 if current_popup.first_configure() {
130 current_popup.converter_popup(current_popup.inner().wl_surface(), &self.queue);
131 }
132 } else {
133 warn!("Popup configured but not pushed to the manager");
134 }
135 }
136
137 fn done(
138 &mut self,
139 _: &Connection,
140 _: &QueueHandle<Self>,
141 _: &smithay_client_toolkit::shell::xdg::popup::Popup,
142 ) {
143 info!("[Popup Manager]: A popup is closed");
144 }
145}
146
147impl ProvidesRegistryState for SpellWin {
149 fn registry(&mut self) -> &mut RegistryState {
150 &mut self.states.registry_state
151 }
152 registry_handlers![OutputState, SeatState];
153}
154
155impl ShmHandler for SpellWin {
156 fn shm_state(&mut self) -> &mut Shm {
157 &mut self.states.shm
158 }
159}
160
161impl OutputHandler for SpellWin {
162 fn output_state(&mut self) -> &mut OutputState {
163 &mut self.states.output_state
164 }
165
166 fn new_output(
167 &mut self,
168 _conn: &Connection,
169 _qh: &QueueHandle<Self>,
170 _output: wl_output::WlOutput,
171 ) {
172 trace!("New output Source Added");
173 }
174
175 fn update_output(
176 &mut self,
177 _conn: &Connection,
178 _qh: &QueueHandle<Self>,
179 _output: wl_output::WlOutput,
180 ) {
181 trace!("Existing output is updated");
182 }
183
184 fn output_destroyed(
185 &mut self,
186 _conn: &Connection,
187 _qh: &QueueHandle<Self>,
188 _output: wl_output::WlOutput,
189 ) {
190 trace!("Output is destroyed");
191 }
192}
193
194impl CompositorHandler for SpellWin {
195 fn scale_factor_changed(
196 &mut self,
197 _: &Connection,
198 _: &QueueHandle<Self>,
199 _: &wl_surface::WlSurface,
200 _: i32,
201 ) {
202 info!("Scale factor changed, compositor msg");
203 }
204
205 fn transform_changed(
206 &mut self,
207 _conn: &Connection,
208 _qh: &QueueHandle<Self>,
209 _surface: &wl_surface::WlSurface,
210 _new_transform: wl_output::Transform,
211 ) {
212 trace!("Compositor transformation changed");
213 }
214
215 fn frame(
216 &mut self,
217 _conn: &Connection,
218 qh: &QueueHandle<Self>,
219 _surface: &wl_surface::WlSurface,
220 _time: u32,
221 ) {
222 self.converter(qh);
223 self.popup_manager.redraw_popups(qh);
224 }
225
226 fn surface_enter(
227 &mut self,
228 _conn: &Connection,
229 _qh: &QueueHandle<Self>,
230 _surface: &wl_surface::WlSurface,
231 _output: &wl_output::WlOutput,
232 ) {
233 trace!("Surface entered");
234 }
235
236 fn surface_leave(
237 &mut self,
238 _conn: &Connection,
239 _qh: &QueueHandle<Self>,
240 _surface: &wl_surface::WlSurface,
241 _output: &wl_output::WlOutput,
242 ) {
243 trace!("Surface left");
244 }
245}
246
247impl FractionalScaleHandler for SpellWin {
248 fn preferred_scale(
249 &mut self,
250 _: &Connection,
251 _: &QueueHandle<Self>,
252 _: &wl_surface::WlSurface,
253 scale: u32,
254 ) {
255 info!("Scale factor changed, invoked from custom trait: {}", scale);
256 let width_old = self.adapter.as_ref().unwrap().size_original.get().width;
257 let height_old = self.adapter.as_ref().unwrap().size_original.get().height;
258 self.layer.as_ref().unwrap().wl_surface().damage_buffer(
259 0,
260 0,
261 self.adapter.as_ref().unwrap().size.get().width as i32,
262 self.adapter.as_ref().unwrap().size.get().height as i32,
263 );
264 let (buffer, width, height, scale_factor) =
265 self.adapter.as_ref().unwrap().changed_scale_factor(scale);
266 self.config.evaluated_width = width;
267 self.config.evaluated_height = height;
268 self.buffer = Some(buffer);
269 self.adapter
270 .as_ref()
271 .unwrap()
272 .try_dispatch_event(slint::platform::WindowEvent::ScaleFactorChanged { scale_factor })
273 .unwrap();
274 self.viewport.as_ref().unwrap().set_source(
275 0.,
276 0.,
277 self.adapter.as_ref().unwrap().size.get().width.into(),
278 self.adapter.as_ref().unwrap().size.get().height.into(),
279 );
280
281 self.viewport
282 .as_ref()
283 .unwrap()
284 .set_destination(width_old as i32, height_old as i32);
285 self.adapter.as_ref().unwrap().request_redraw();
286 self.layer.as_ref().unwrap().commit();
287 }
288}
289
290impl LayerShellHandler for SpellWin {
291 fn closed(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _layer: &LayerSurface) {
292 trace!("Closure of layer called");
293 }
294
295 fn configure(
296 &mut self,
297 _conn: &Connection,
298 qh: &QueueHandle<Self>,
299 _layer: &LayerSurface,
300 _configure: LayerSurfaceConfigure,
301 _serial: u32,
302 ) {
303 self.converter(qh);
304 }
305}
306
307impl Dispatch<XdgSurface, ()> for SpellWin {
308 fn event(
309 state: &mut Self,
310 xdg_surface: &XdgSurface,
311 event: <XdgSurface as smithay_client_toolkit::reexports::client::Proxy>::Event,
312 _: &(),
313 _: &Connection,
314 _: &QueueHandle<Self>,
315 ) {
316 match event {
317 smithay_client_toolkit::reexports::protocols::xdg::shell::client::xdg_surface::Event::Configure { serial } => {
318 info!("[Popup Manager]: ack called with a serial");
319 state.popup_manager.call_ack(xdg_surface, serial);
320 },
321 event_branch => warn!("Unprocessed event branch from popup configure: {:?}", event_branch),
322 }
323 }
324}