iced-yoda/winit/src/platform_specific/wayland/handlers/seat/pointer.rs
2026-08-05 15:31:43 -04:00

82 lines
2.8 KiB
Rust

use crate::platform_specific::wayland::{
event_loop::state::SctkState, sctk_event::SctkEvent,
};
use cctk::sctk::{
delegate_pointer,
reexports::client::Proxy,
seat::pointer::{
CursorIcon, PointerEvent, PointerEventKind, PointerHandler,
},
};
impl PointerHandler for SctkState {
fn pointer_frame(
&mut self,
conn: &cctk::sctk::reexports::client::Connection,
_qh: &cctk::sctk::reexports::client::QueueHandle<Self>,
pointer: &cctk::sctk::reexports::client::protocol::wl_pointer::WlPointer,
events: &[cctk::sctk::seat::pointer::PointerEvent],
) {
let (is_active, my_seat) =
match self.seats.iter_mut().enumerate().find_map(|(i, s)| {
if s.ptr.as_ref().map(|p| p.pointer()) == Some(pointer) {
Some((i, s))
} else {
None
}
}) {
Some((i, s)) => (i == 0, s),
None => return,
};
// track events, but only forward for the active seat
for e in events {
if my_seat.active_icon != my_seat.icon {
// Restore cursor that was set by appliction, or default
my_seat.set_cursor(
conn,
my_seat.icon.unwrap_or(CursorIcon::Default),
);
}
if is_active {
let id = winit::window::WindowId::from_raw(
e.surface.id().as_ptr() as usize,
);
if self.windows.iter().any(|w| w.window.id() == id) {
continue;
}
self.sctk_events.push(SctkEvent::PointerEvent {
variant: PointerEvent {
surface: e.surface.clone(),
position: e.position,
kind: e.kind.clone(),
},
ptr_id: pointer.clone(),
seat_id: my_seat.seat.clone(),
});
}
match e.kind {
PointerEventKind::Enter { .. } => {
_ = my_seat.ptr_focus.replace(e.surface.clone());
}
PointerEventKind::Leave { .. } => {
_ = my_seat.ptr_focus.take();
_ = my_seat.active_icon = None;
}
PointerEventKind::Press {
time,
button,
serial,
} => {
_ = my_seat.last_ptr_press.replace((time, button, serial));
}
// TODO revisit events that ought to be handled and change internal state
_ => {}
}
}
}
}
delegate_pointer!(SctkState);