Skip to content

Commit ea5ec7c

Browse files
Cherser-skosyak
authored and
kosyak
committed
Wayland: Add relative pointer movement (rust-windowing#973)
* Add relative pointer movement for Wayland * Format changed code with rustfmt * Wayland: merge window and device event queues into one * Replace map_or_else call for simplification
1 parent 7398696 commit ea5ec7c

File tree

3 files changed

+113
-48
lines changed

3 files changed

+113
-48
lines changed

src/platform_impl/linux/wayland/event_loop.rs

+70-31
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ use std::{
77
time::Instant,
88
};
99

10+
use smithay_client_toolkit::reexports::protocols::unstable::relative_pointer::v1::client::{
11+
zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
12+
zwp_relative_pointer_v1::ZwpRelativePointerV1,
13+
};
14+
1015
use crate::{
1116
dpi::{PhysicalPosition, PhysicalSize},
1217
event::ModifiersState,
@@ -15,7 +20,7 @@ use crate::{
1520
platform_impl::platform::sticky_exit_callback,
1621
};
1722

18-
use super::{window::WindowStore, WindowId};
23+
use super::{window::WindowStore, DeviceId, WindowId};
1924

2025
use smithay_client_toolkit::{
2126
output::OutputMgr,
@@ -26,33 +31,37 @@ use smithay_client_toolkit::{
2631
Environment,
2732
};
2833

29-
pub struct WindowEventsSink {
30-
buffer: VecDeque<(crate::event::WindowEvent, crate::window::WindowId)>,
34+
pub struct WindowEventsSink<T> {
35+
buffer: VecDeque<crate::event::Event<T>>,
3136
}
3237

33-
impl WindowEventsSink {
34-
pub fn new() -> WindowEventsSink {
38+
impl<T> WindowEventsSink<T> {
39+
pub fn new() -> WindowEventsSink<T> {
3540
WindowEventsSink {
3641
buffer: VecDeque::new(),
3742
}
3843
}
3944

40-
pub fn send_event(&mut self, evt: crate::event::WindowEvent, wid: WindowId) {
41-
self.buffer.push_back((
42-
evt,
43-
crate::window::WindowId(crate::platform_impl::WindowId::Wayland(wid)),
44-
));
45+
pub fn send_window_event(&mut self, evt: crate::event::WindowEvent, wid: WindowId) {
46+
self.buffer.push_back(crate::event::Event::WindowEvent {
47+
event: evt,
48+
window_id: crate::window::WindowId(crate::platform_impl::WindowId::Wayland(wid)),
49+
});
50+
}
51+
52+
pub fn send_device_event(&mut self, evt: crate::event::DeviceEvent, dev_id: DeviceId) {
53+
self.buffer.push_back(crate::event::Event::DeviceEvent {
54+
event: evt,
55+
device_id: crate::event::DeviceId(crate::platform_impl::DeviceId::Wayland(dev_id)),
56+
});
4557
}
4658

47-
fn empty_with<F, T>(&mut self, mut callback: F)
59+
fn empty_with<F>(&mut self, mut callback: F)
4860
where
4961
F: FnMut(crate::event::Event<T>),
5062
{
51-
for (evt, wid) in self.buffer.drain(..) {
52-
callback(crate::event::Event::WindowEvent {
53-
event: evt,
54-
window_id: wid,
55-
})
63+
for evt in self.buffer.drain(..) {
64+
callback(evt)
5665
}
5766
}
5867
}
@@ -65,7 +74,7 @@ pub struct EventLoop<T: 'static> {
6574
// the output manager
6675
pub outputs: OutputMgr,
6776
// our sink, shared with some handlers, buffering the events
68-
sink: Arc<Mutex<WindowEventsSink>>,
77+
sink: Arc<Mutex<WindowEventsSink<T>>>,
6978
pending_user_events: Rc<RefCell<VecDeque<T>>>,
7079
_user_source: ::calloop::Source<::calloop::channel::Channel<T>>,
7180
user_sender: ::calloop::channel::Sender<T>,
@@ -122,13 +131,14 @@ impl<T: 'static> EventLoop<T> {
122131
.handle()
123132
.insert_source(kbd_channel, move |evt, &mut ()| {
124133
if let ::calloop::channel::Event::Msg((evt, wid)) = evt {
125-
kbd_sink.lock().unwrap().send_event(evt, wid);
134+
kbd_sink.lock().unwrap().send_window_event(evt, wid);
126135
}
127136
})
128137
.unwrap();
129138

130139
let mut seat_manager = SeatManager {
131140
sink: sink.clone(),
141+
relative_pointer_manager_proxy: None,
132142
store: store.clone(),
133143
seats: seats.clone(),
134144
kbd_sender,
@@ -143,6 +153,15 @@ impl<T: 'static> EventLoop<T> {
143153
ref interface,
144154
version,
145155
} => {
156+
if interface == "zwp_relative_pointer_manager_v1" {
157+
seat_manager.relative_pointer_manager_proxy = Some(
158+
registry
159+
.bind(version, id, move |pointer_manager| {
160+
pointer_manager.implement_closure(|_, _| (), ())
161+
})
162+
.unwrap(),
163+
)
164+
}
146165
if interface == "wl_seat" {
147166
seat_manager.add_seat(id, version, registry)
148167
}
@@ -392,7 +411,7 @@ impl<T> EventLoop<T> {
392411
let pruned = window_target.store.lock().unwrap().cleanup();
393412
*cleanup_needed = false;
394413
for wid in pruned {
395-
sink.send_event(crate::event::WindowEvent::Destroyed, wid);
414+
sink.send_window_event(crate::event::WindowEvent::Destroyed, wid);
396415
}
397416
}
398417
}
@@ -404,7 +423,10 @@ impl<T> EventLoop<T> {
404423
frame.resize(w, h);
405424
frame.refresh();
406425
let logical_size = crate::dpi::LogicalSize::new(w as f64, h as f64);
407-
sink.send_event(crate::event::WindowEvent::Resized(logical_size), wid);
426+
sink.send_window_event(
427+
crate::event::WindowEvent::Resized(logical_size),
428+
wid,
429+
);
408430
*size = (w, h);
409431
} else if frame_refresh {
410432
frame.refresh();
@@ -414,16 +436,16 @@ impl<T> EventLoop<T> {
414436
}
415437
}
416438
if let Some(dpi) = new_dpi {
417-
sink.send_event(
439+
sink.send_window_event(
418440
crate::event::WindowEvent::HiDpiFactorChanged(dpi as f64),
419441
wid,
420442
);
421443
}
422444
if refresh {
423-
sink.send_event(crate::event::WindowEvent::RedrawRequested, wid);
445+
sink.send_window_event(crate::event::WindowEvent::RedrawRequested, wid);
424446
}
425447
if closed {
426-
sink.send_event(crate::event::WindowEvent::CloseRequested, wid);
448+
sink.send_window_event(crate::event::WindowEvent::CloseRequested, wid);
427449
}
428450
},
429451
)
@@ -434,21 +456,24 @@ impl<T> EventLoop<T> {
434456
* Wayland protocol implementations
435457
*/
436458

437-
struct SeatManager {
438-
sink: Arc<Mutex<WindowEventsSink>>,
459+
struct SeatManager<T: 'static> {
460+
sink: Arc<Mutex<WindowEventsSink<T>>>,
439461
store: Arc<Mutex<WindowStore>>,
440462
seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>,
441463
kbd_sender: ::calloop::channel::Sender<(crate::event::WindowEvent, super::WindowId)>,
464+
relative_pointer_manager_proxy: Option<ZwpRelativePointerManagerV1>,
442465
}
443466

444-
impl SeatManager {
467+
impl<T: 'static> SeatManager<T> {
445468
fn add_seat(&mut self, id: u32, version: u32, registry: wl_registry::WlRegistry) {
446469
use std::cmp::min;
447470

448471
let mut seat_data = SeatData {
449472
sink: self.sink.clone(),
450473
store: self.store.clone(),
451474
pointer: None,
475+
relative_pointer: None,
476+
relative_pointer_manager_proxy: self.relative_pointer_manager_proxy.as_ref().cloned(),
452477
keyboard: None,
453478
touch: None,
454479
kbd_sender: self.kbd_sender.clone(),
@@ -474,17 +499,19 @@ impl SeatManager {
474499
}
475500
}
476501

477-
struct SeatData {
478-
sink: Arc<Mutex<WindowEventsSink>>,
502+
struct SeatData<T> {
503+
sink: Arc<Mutex<WindowEventsSink<T>>>,
479504
store: Arc<Mutex<WindowStore>>,
480505
kbd_sender: ::calloop::channel::Sender<(crate::event::WindowEvent, super::WindowId)>,
481506
pointer: Option<wl_pointer::WlPointer>,
507+
relative_pointer: Option<ZwpRelativePointerV1>,
508+
relative_pointer_manager_proxy: Option<ZwpRelativePointerManagerV1>,
482509
keyboard: Option<wl_keyboard::WlKeyboard>,
483510
touch: Option<wl_touch::WlTouch>,
484511
modifiers_tracker: Arc<Mutex<ModifiersState>>,
485512
}
486513

487-
impl SeatData {
514+
impl<T: 'static> SeatData<T> {
488515
fn receive(&mut self, evt: wl_seat::Event, seat: wl_seat::WlSeat) {
489516
match evt {
490517
wl_seat::Event::Name { .. } => (),
@@ -496,7 +523,19 @@ impl SeatData {
496523
self.sink.clone(),
497524
self.store.clone(),
498525
self.modifiers_tracker.clone(),
499-
))
526+
));
527+
528+
self.relative_pointer =
529+
self.relative_pointer_manager_proxy
530+
.as_ref()
531+
.and_then(|manager| {
532+
super::pointer::implement_relative_pointer(
533+
self.sink.clone(),
534+
self.pointer.as_ref().unwrap(),
535+
manager,
536+
)
537+
.ok()
538+
})
500539
}
501540
// destroy pointer if applicable
502541
if !capabilities.contains(wl_seat::Capability::Pointer) {
@@ -544,7 +583,7 @@ impl SeatData {
544583
}
545584
}
546585

547-
impl Drop for SeatData {
586+
impl<T> Drop for SeatData<T> {
548587
fn drop(&mut self) {
549588
if let Some(pointer) = self.pointer.take() {
550589
if pointer.as_ref().version() >= 3 {

src/platform_impl/linux/wayland/pointer.rs

+37-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::sync::{Arc, Mutex};
22

33
use crate::event::{
4-
ElementState, ModifiersState, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent,
4+
DeviceEvent, ElementState, ModifiersState, MouseButton, MouseScrollDelta, TouchPhase,
5+
WindowEvent,
56
};
67

78
use super::{event_loop::WindowEventsSink, window::WindowStore, DeviceId};
@@ -11,9 +12,14 @@ use smithay_client_toolkit::reexports::client::protocol::{
1112
wl_seat,
1213
};
1314

14-
pub fn implement_pointer(
15+
use smithay_client_toolkit::reexports::protocols::unstable::relative_pointer::v1::client::{
16+
zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, zwp_relative_pointer_v1::Event,
17+
zwp_relative_pointer_v1::ZwpRelativePointerV1,
18+
};
19+
20+
pub fn implement_pointer<T: 'static>(
1521
seat: &wl_seat::WlSeat,
16-
sink: Arc<Mutex<WindowEventsSink>>,
22+
sink: Arc<Mutex<WindowEventsSink<T>>>,
1723
store: Arc<Mutex<WindowStore>>,
1824
modifiers_tracker: Arc<Mutex<ModifiersState>>,
1925
) -> WlPointer {
@@ -37,15 +43,15 @@ pub fn implement_pointer(
3743
let wid = store.find_wid(&surface);
3844
if let Some(wid) = wid {
3945
mouse_focus = Some(wid);
40-
sink.send_event(
46+
sink.send_window_event(
4147
WindowEvent::CursorEntered {
4248
device_id: crate::event::DeviceId(
4349
crate::platform_impl::DeviceId::Wayland(DeviceId),
4450
),
4551
},
4652
wid,
4753
);
48-
sink.send_event(
54+
sink.send_window_event(
4955
WindowEvent::CursorMoved {
5056
device_id: crate::event::DeviceId(
5157
crate::platform_impl::DeviceId::Wayland(DeviceId),
@@ -61,7 +67,7 @@ pub fn implement_pointer(
6167
mouse_focus = None;
6268
let wid = store.find_wid(&surface);
6369
if let Some(wid) = wid {
64-
sink.send_event(
70+
sink.send_window_event(
6571
WindowEvent::CursorLeft {
6672
device_id: crate::event::DeviceId(
6773
crate::platform_impl::DeviceId::Wayland(DeviceId),
@@ -77,7 +83,7 @@ pub fn implement_pointer(
7783
..
7884
} => {
7985
if let Some(wid) = mouse_focus {
80-
sink.send_event(
86+
sink.send_window_event(
8187
WindowEvent::CursorMoved {
8288
device_id: crate::event::DeviceId(
8389
crate::platform_impl::DeviceId::Wayland(DeviceId),
@@ -103,7 +109,7 @@ pub fn implement_pointer(
103109
// TODO figure out the translation ?
104110
_ => return,
105111
};
106-
sink.send_event(
112+
sink.send_window_event(
107113
WindowEvent::MouseInput {
108114
device_id: crate::event::DeviceId(
109115
crate::platform_impl::DeviceId::Wayland(DeviceId),
@@ -127,7 +133,7 @@ pub fn implement_pointer(
127133
wl_pointer::Axis::HorizontalScroll => x += value as f32,
128134
_ => unreachable!(),
129135
}
130-
sink.send_event(
136+
sink.send_window_event(
131137
WindowEvent::MouseWheel {
132138
device_id: crate::event::DeviceId(
133139
crate::platform_impl::DeviceId::Wayland(DeviceId),
@@ -161,7 +167,7 @@ pub fn implement_pointer(
161167
let axis_discrete_buffer = axis_discrete_buffer.take();
162168
if let Some(wid) = mouse_focus {
163169
if let Some((x, y)) = axis_discrete_buffer {
164-
sink.send_event(
170+
sink.send_window_event(
165171
WindowEvent::MouseWheel {
166172
device_id: crate::event::DeviceId(
167173
crate::platform_impl::DeviceId::Wayland(DeviceId),
@@ -173,7 +179,7 @@ pub fn implement_pointer(
173179
wid,
174180
);
175181
} else if let Some((x, y)) = axis_buffer {
176-
sink.send_event(
182+
sink.send_window_event(
177183
WindowEvent::MouseWheel {
178184
device_id: crate::event::DeviceId(
179185
crate::platform_impl::DeviceId::Wayland(DeviceId),
@@ -215,3 +221,23 @@ pub fn implement_pointer(
215221
})
216222
.unwrap()
217223
}
224+
225+
pub fn implement_relative_pointer<T: 'static>(
226+
sink: Arc<Mutex<WindowEventsSink<T>>>,
227+
pointer: &WlPointer,
228+
manager: &ZwpRelativePointerManagerV1,
229+
) -> Result<ZwpRelativePointerV1, ()> {
230+
manager.get_relative_pointer(pointer, |rel_pointer| {
231+
rel_pointer.implement_closure(
232+
move |evt, _rel_pointer| {
233+
let mut sink = sink.lock().unwrap();
234+
match evt {
235+
Event::RelativeMotion { dx, dy, .. } => sink
236+
.send_device_event(DeviceEvent::MouseMotion { delta: (dx, dy) }, DeviceId),
237+
_ => unreachable!(),
238+
}
239+
},
240+
(),
241+
)
242+
})
243+
}

0 commit comments

Comments
 (0)