winit/platform_impl/linux/wayland/seat/touch/
mod.rs
1use tracing::warn;
4
5use sctk::reexports::client::protocol::wl_seat::WlSeat;
6use sctk::reexports::client::protocol::wl_surface::WlSurface;
7use sctk::reexports::client::protocol::wl_touch::WlTouch;
8use sctk::reexports::client::{Connection, Proxy, QueueHandle};
9
10use sctk::seat::touch::{TouchData, TouchHandler};
11
12use crate::dpi::LogicalPosition;
13use crate::event::{Touch, TouchPhase, WindowEvent};
14
15use crate::platform_impl::wayland::state::WinitState;
16use crate::platform_impl::wayland::{self, DeviceId};
17
18impl TouchHandler for WinitState {
19 fn down(
20 &mut self,
21 _: &Connection,
22 _: &QueueHandle<Self>,
23 touch: &WlTouch,
24 _: u32,
25 _: u32,
26 surface: WlSurface,
27 id: i32,
28 position: (f64, f64),
29 ) {
30 let window_id = wayland::make_wid(&surface);
31 let scale_factor = match self.windows.get_mut().get(&window_id) {
32 Some(window) => window.lock().unwrap().scale_factor(),
33 None => return,
34 };
35
36 let seat_state = match self.seats.get_mut(&touch.seat().id()) {
37 Some(seat_state) => seat_state,
38 None => {
39 warn!("Received wl_touch::down without seat");
40 return;
41 },
42 };
43
44 let location = LogicalPosition::<f64>::from(position);
46 seat_state.touch_map.insert(id, TouchPoint { surface, location });
47
48 self.events_sink.push_window_event(
49 WindowEvent::Touch(Touch {
50 device_id: crate::event::DeviceId(crate::platform_impl::DeviceId::Wayland(
51 DeviceId,
52 )),
53 phase: TouchPhase::Started,
54 location: location.to_physical(scale_factor),
55 force: None,
56 id: id as u64,
57 }),
58 window_id,
59 );
60 }
61
62 fn up(
63 &mut self,
64 _: &Connection,
65 _: &QueueHandle<Self>,
66 touch: &WlTouch,
67 _: u32,
68 _: u32,
69 id: i32,
70 ) {
71 let seat_state = match self.seats.get_mut(&touch.seat().id()) {
72 Some(seat_state) => seat_state,
73 None => {
74 warn!("Received wl_touch::up without seat");
75 return;
76 },
77 };
78
79 let touch_point = match seat_state.touch_map.remove(&id) {
81 Some(touch_point) => touch_point,
82 None => return,
83 };
84
85 let window_id = wayland::make_wid(&touch_point.surface);
86 let scale_factor = match self.windows.get_mut().get(&window_id) {
87 Some(window) => window.lock().unwrap().scale_factor(),
88 None => return,
89 };
90
91 self.events_sink.push_window_event(
92 WindowEvent::Touch(Touch {
93 device_id: crate::event::DeviceId(crate::platform_impl::DeviceId::Wayland(
94 DeviceId,
95 )),
96 phase: TouchPhase::Ended,
97 location: touch_point.location.to_physical(scale_factor),
98 force: None,
99 id: id as u64,
100 }),
101 window_id,
102 );
103 }
104
105 fn motion(
106 &mut self,
107 _: &Connection,
108 _: &QueueHandle<Self>,
109 touch: &WlTouch,
110 _: u32,
111 id: i32,
112 position: (f64, f64),
113 ) {
114 let seat_state = match self.seats.get_mut(&touch.seat().id()) {
115 Some(seat_state) => seat_state,
116 None => {
117 warn!("Received wl_touch::motion without seat");
118 return;
119 },
120 };
121
122 let touch_point = match seat_state.touch_map.get_mut(&id) {
124 Some(touch_point) => touch_point,
125 None => return,
126 };
127
128 let window_id = wayland::make_wid(&touch_point.surface);
129 let scale_factor = match self.windows.get_mut().get(&window_id) {
130 Some(window) => window.lock().unwrap().scale_factor(),
131 None => return,
132 };
133
134 touch_point.location = LogicalPosition::<f64>::from(position);
135
136 self.events_sink.push_window_event(
137 WindowEvent::Touch(Touch {
138 device_id: crate::event::DeviceId(crate::platform_impl::DeviceId::Wayland(
139 DeviceId,
140 )),
141 phase: TouchPhase::Moved,
142 location: touch_point.location.to_physical(scale_factor),
143 force: None,
144 id: id as u64,
145 }),
146 window_id,
147 );
148 }
149
150 fn cancel(&mut self, _: &Connection, _: &QueueHandle<Self>, touch: &WlTouch) {
151 let seat_state = match self.seats.get_mut(&touch.seat().id()) {
152 Some(seat_state) => seat_state,
153 None => {
154 warn!("Received wl_touch::cancel without seat");
155 return;
156 },
157 };
158
159 for (id, touch_point) in seat_state.touch_map.drain() {
160 let window_id = wayland::make_wid(&touch_point.surface);
161 let scale_factor = match self.windows.get_mut().get(&window_id) {
162 Some(window) => window.lock().unwrap().scale_factor(),
163 None => return,
164 };
165
166 let location = touch_point.location.to_physical(scale_factor);
167
168 self.events_sink.push_window_event(
169 WindowEvent::Touch(Touch {
170 device_id: crate::event::DeviceId(crate::platform_impl::DeviceId::Wayland(
171 DeviceId,
172 )),
173 phase: TouchPhase::Cancelled,
174 location,
175 force: None,
176 id: id as u64,
177 }),
178 window_id,
179 );
180 }
181 }
182
183 fn shape(
184 &mut self,
185 _: &Connection,
186 _: &QueueHandle<Self>,
187 _: &WlTouch,
188 _: i32,
189 _: f64,
190 _: f64,
191 ) {
192 }
194
195 fn orientation(&mut self, _: &Connection, _: &QueueHandle<Self>, _: &WlTouch, _: i32, _: f64) {
196 }
198}
199
200#[derive(Debug)]
202pub struct TouchPoint {
203 pub surface: WlSurface,
205
206 pub location: LogicalPosition<f64>,
208}
209
210pub trait TouchDataExt {
211 fn seat(&self) -> &WlSeat;
212}
213
214impl TouchDataExt for WlTouch {
215 fn seat(&self) -> &WlSeat {
216 self.data::<TouchData>().expect("failed to get touch data.").seat()
217 }
218}
219
220sctk::delegate_touch!(WinitState);