diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/api/wayland/context.rs | 33 | ||||
| -rw-r--r-- | src/api/wayland/events.rs | 91 | ||||
| -rw-r--r-- | src/api/wayland/window.rs | 4 | 
3 files changed, 119 insertions, 9 deletions
| diff --git a/src/api/wayland/context.rs b/src/api/wayland/context.rs index 8e1196d..4b39d85 100644 --- a/src/api/wayland/context.rs +++ b/src/api/wayland/context.rs @@ -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);                  } diff --git a/src/api/wayland/events.rs b/src/api/wayland/events.rs index 86f0575..6a7a2e7 100644 --- a/src/api/wayland/events.rs +++ b/src/api/wayland/events.rs @@ -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}; + +use super::context::WaylandFocuses; -pub fn translate_event(evt: WaylandEvent) -> Option<(GlutinEvent, ProxyId)> { -    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      }  }
\ No newline at end of file diff --git a/src/api/wayland/window.rs b/src/api/wayland/window.rs index 7532443..faf772e 100644 --- a/src/api/wayland/window.rs +++ b/src/api/wayland/window.rs @@ -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(())      } | 
