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