mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +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 Event as GlutinEvent;
|
||||||
|
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque, HashSet};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
|
@ -9,7 +9,7 @@ use wayland_client::{EventIterator, Proxy, ProxyId};
|
||||||
use wayland_client::wayland::get_display;
|
use wayland_client::wayland::get_display;
|
||||||
use wayland_client::wayland::compositor::{WlCompositor, WlSurface};
|
use wayland_client::wayland::compositor::{WlCompositor, WlSurface};
|
||||||
use wayland_client::wayland::output::WlOutput;
|
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::shell::WlShell;
|
||||||
use wayland_client::wayland::shm::WlShm;
|
use wayland_client::wayland::shm::WlShm;
|
||||||
use wayland_client::wayland::subcompositor::WlSubcompositor;
|
use wayland_client::wayland::subcompositor::WlSubcompositor;
|
||||||
|
@ -30,11 +30,20 @@ wayland_env!(InnerEnv,
|
||||||
subcompositor: WlSubcompositor
|
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 {
|
pub struct WaylandContext {
|
||||||
inner: InnerEnv,
|
inner: InnerEnv,
|
||||||
iterator: Mutex<EventIterator>,
|
iterator: Mutex<EventIterator>,
|
||||||
monitors: Vec<WlOutput>,
|
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 {
|
impl WaylandContext {
|
||||||
|
@ -57,7 +66,14 @@ impl WaylandContext {
|
||||||
inner: inner_env,
|
inner: inner_env,
|
||||||
iterator: Mutex::new(iterator),
|
iterator: Mutex::new(iterator),
|
||||||
monitors: monitors,
|
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))
|
Arc::new(Mutex::new(q))
|
||||||
};
|
};
|
||||||
self.queues.lock().unwrap().insert(id, queue.clone());
|
self.queues.lock().unwrap().insert(id, queue.clone());
|
||||||
|
self.known_surfaces.lock().unwrap().insert(id);
|
||||||
(s, queue)
|
(s, queue)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dropped_surface(&self, id: ProxyId) {
|
pub fn dropped_surface(&self, id: ProxyId) {
|
||||||
self.queues.lock().unwrap().remove(&id);
|
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> {
|
pub fn decorated_from(&self, surface: &WlSurface, width: i32, height: i32) -> Option<DecoratedSurface> {
|
||||||
|
@ -100,9 +118,14 @@ impl WaylandContext {
|
||||||
pub fn dispatch_events(&self) {
|
pub fn dispatch_events(&self) {
|
||||||
self.inner.display.dispatch_pending().unwrap();
|
self.inner.display.dispatch_pending().unwrap();
|
||||||
let mut iterator = self.iterator.lock().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();
|
let queues = self.queues.lock().unwrap();
|
||||||
for evt in &mut *iterator {
|
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) {
|
if let Some(q) = queues.get(&id) {
|
||||||
q.lock().unwrap().push_back(evt);
|
q.lock().unwrap().push_back(evt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,97 @@
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use Event as GlutinEvent;
|
use Event as GlutinEvent;
|
||||||
|
use ElementState;
|
||||||
|
use MouseButton;
|
||||||
|
use MouseScrollDelta;
|
||||||
|
|
||||||
use wayland_client::Event as WaylandEvent;
|
use wayland_client::Event as WaylandEvent;
|
||||||
use wayland_client::ProxyId;
|
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)> {
|
use super::context::WaylandFocuses;
|
||||||
match evt {
|
|
||||||
|
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
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -225,12 +225,12 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
pub fn set_cursor(&self, _cursor: MouseCursor) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
|
pub fn set_cursor_state(&self, _state: CursorState) -> Result<(), String> {
|
||||||
// TODO
|
// TODO
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue