mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
api/wayland: pointer events support.
This commit is contained in:
parent
6294d3c7dd
commit
0792557f4b
|
@ -1,6 +1,6 @@
|
|||
use Event as GlutinEvent;
|
||||
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::collections::{HashMap, VecDeque, HashSet};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use libc::c_void;
|
||||
|
@ -9,7 +9,7 @@ use wayland_client::{EventIterator, Proxy, ProxyId};
|
|||
use wayland_client::wayland::get_display;
|
||||
use wayland_client::wayland::compositor::{WlCompositor, WlSurface};
|
||||
use wayland_client::wayland::output::WlOutput;
|
||||
use wayland_client::wayland::seat::WlSeat;
|
||||
use wayland_client::wayland::seat::{WlSeat, WlPointer};
|
||||
use wayland_client::wayland::shell::WlShell;
|
||||
use wayland_client::wayland::shm::WlShm;
|
||||
use wayland_client::wayland::subcompositor::WlSubcompositor;
|
||||
|
@ -30,11 +30,20 @@ wayland_env!(InnerEnv,
|
|||
subcompositor: WlSubcompositor
|
||||
);
|
||||
|
||||
pub struct WaylandFocuses {
|
||||
pub pointer: Option<WlPointer>,
|
||||
pub pointer_on: Option<ProxyId>,
|
||||
pub pointer_at: Option<(f64, f64)>,
|
||||
pub keyboard_on: Option<ProxyId>
|
||||
}
|
||||
|
||||
pub struct WaylandContext {
|
||||
inner: InnerEnv,
|
||||
iterator: Mutex<EventIterator>,
|
||||
monitors: Vec<WlOutput>,
|
||||
queues: Mutex<HashMap<ProxyId, Arc<Mutex<VecDeque<GlutinEvent>>>>>
|
||||
queues: Mutex<HashMap<ProxyId, Arc<Mutex<VecDeque<GlutinEvent>>>>>,
|
||||
known_surfaces: Mutex<HashSet<ProxyId>>,
|
||||
focuses: Mutex<WaylandFocuses>
|
||||
}
|
||||
|
||||
impl WaylandContext {
|
||||
|
@ -57,7 +66,14 @@ impl WaylandContext {
|
|||
inner: inner_env,
|
||||
iterator: Mutex::new(iterator),
|
||||
monitors: monitors,
|
||||
queues: Mutex::new(HashMap::new())
|
||||
queues: Mutex::new(HashMap::new()),
|
||||
known_surfaces: Mutex::new(HashSet::new()),
|
||||
focuses: Mutex::new(WaylandFocuses {
|
||||
pointer: None,
|
||||
pointer_on: None,
|
||||
pointer_at: None,
|
||||
keyboard_on: None
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -71,12 +87,14 @@ impl WaylandContext {
|
|||
Arc::new(Mutex::new(q))
|
||||
};
|
||||
self.queues.lock().unwrap().insert(id, queue.clone());
|
||||
self.known_surfaces.lock().unwrap().insert(id);
|
||||
(s, queue)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn dropped_surface(&self, id: ProxyId) {
|
||||
self.queues.lock().unwrap().remove(&id);
|
||||
self.known_surfaces.lock().unwrap().remove(&id);
|
||||
}
|
||||
|
||||
pub fn decorated_from(&self, surface: &WlSurface, width: i32, height: i32) -> Option<DecoratedSurface> {
|
||||
|
@ -100,9 +118,14 @@ impl WaylandContext {
|
|||
pub fn dispatch_events(&self) {
|
||||
self.inner.display.dispatch_pending().unwrap();
|
||||
let mut iterator = self.iterator.lock().unwrap();
|
||||
let mut focuses = self.focuses.lock().unwrap();
|
||||
let known_ids = self.known_surfaces.lock().unwrap();
|
||||
let queues = self.queues.lock().unwrap();
|
||||
for evt in &mut *iterator {
|
||||
if let Some((evt, id)) = super::events::translate_event(evt) {
|
||||
if let Some((evt, id)) = super::events::translate_event(
|
||||
evt, &mut *focuses, &known_ids,
|
||||
self.inner.seat.as_ref().map(|s| &s.0))
|
||||
{
|
||||
if let Some(q) = queues.get(&id) {
|
||||
q.lock().unwrap().push_back(evt);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,97 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use Event as GlutinEvent;
|
||||
use ElementState;
|
||||
use MouseButton;
|
||||
use MouseScrollDelta;
|
||||
|
||||
use wayland_client::Event as WaylandEvent;
|
||||
use wayland_client::ProxyId;
|
||||
use wayland_client::wayland::WaylandProtocolEvent as WPE;
|
||||
use wayland_client::wayland::seat::{WlSeat, WlSeatEvent, WlPointerEvent,
|
||||
WlPointerButtonState,
|
||||
WlPointerAxis, WlSeatCapability};
|
||||
|
||||
pub fn translate_event(evt: WaylandEvent) -> Option<(GlutinEvent, ProxyId)> {
|
||||
match evt {
|
||||
use super::context::WaylandFocuses;
|
||||
|
||||
pub fn translate_event(
|
||||
evt: WaylandEvent,
|
||||
focuses: &mut WaylandFocuses,
|
||||
known_surfaces: &HashSet<ProxyId>,
|
||||
seat: Option<&WlSeat>,
|
||||
) -> Option<(GlutinEvent, ProxyId)> {
|
||||
let WaylandEvent::Wayland(wayland_evt) = evt;
|
||||
match wayland_evt {
|
||||
WPE::WlSeat(_, seat_evt) => match seat_evt {
|
||||
WlSeatEvent::Capabilities(cap) => {
|
||||
if cap.contains(WlSeatCapability::Pointer) && focuses.pointer.is_none() {
|
||||
if let Some(seat) = seat {
|
||||
focuses.pointer = Some(seat.get_pointer());
|
||||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
_ => None
|
||||
},
|
||||
WPE::WlPointer(_, pointer_evt) => match pointer_evt {
|
||||
WlPointerEvent::Enter(_, surface, x, y) => {
|
||||
if known_surfaces.contains(&surface) {
|
||||
focuses.pointer_on = Some(surface);
|
||||
focuses.pointer_at = Some((x, y));
|
||||
Some((GlutinEvent::MouseMoved((x as i32, y as i32)), surface))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
WlPointerEvent::Leave(_, _) => {
|
||||
focuses.pointer_on = None;
|
||||
focuses.pointer_at = None;
|
||||
None
|
||||
}
|
||||
WlPointerEvent::Motion(_, x, y) => {
|
||||
if let Some(surface) = focuses.pointer_on {
|
||||
focuses.pointer_at = Some((x, y));
|
||||
Some((GlutinEvent::MouseMoved((x as i32, y as i32)), surface))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
WlPointerEvent::Button(_, _, button, state) => {
|
||||
if let Some(surface) = focuses.pointer_on {
|
||||
Some((GlutinEvent::MouseInput(
|
||||
match state {
|
||||
WlPointerButtonState::Pressed => ElementState::Pressed,
|
||||
WlPointerButtonState::Released => ElementState::Released
|
||||
},
|
||||
match button {
|
||||
0x110 => MouseButton::Left,
|
||||
0x111 => MouseButton::Right,
|
||||
0x112 => MouseButton::Middle,
|
||||
// TODO figure out the translation ?
|
||||
_ => return None
|
||||
}
|
||||
), surface))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
WlPointerEvent::Axis(_, axis, amplitude) => {
|
||||
if let Some(surface) = focuses.pointer_on {
|
||||
Some((GlutinEvent::MouseWheel(
|
||||
match axis {
|
||||
WlPointerAxis::VerticalScroll => {
|
||||
MouseScrollDelta::PixelDelta(amplitude as f32, 0.0)
|
||||
}
|
||||
WlPointerAxis::HorizontalScroll => {
|
||||
MouseScrollDelta::PixelDelta(0.0, amplitude as f32)
|
||||
}
|
||||
}
|
||||
), surface))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
}
|
|
@ -225,12 +225,12 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
||||
pub fn set_cursor(&self, _cursor: MouseCursor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
|
||||
pub fn set_cursor_state(&self, _state: CursorState) -> Result<(), String> {
|
||||
// TODO
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue