From d051e141cfcf8c88e7b5ca1610fcc470bac6902c Mon Sep 17 00:00:00 2001 From: Drakulix Date: Thu, 22 Mar 2018 16:09:58 +0100 Subject: [PATCH] Refactor PointerAxisEvent to handle multiple axis --- examples/udev.rs | 66 +++++++++++++++++++++++++--------- examples/winit.rs | 45 +++++++++++++++++------- src/backend/input.rs | 26 ++++++++------ src/backend/libinput.rs | 78 ++++++++++++----------------------------- src/backend/winit.rs | 59 ++++++++++--------------------- 5 files changed, 138 insertions(+), 136 deletions(-) diff --git a/examples/udev.rs b/examples/udev.rs index fe68aff..6cbe5dc 100644 --- a/examples/udev.rs +++ b/examples/udev.rs @@ -34,8 +34,7 @@ use smithay::backend::graphics::egl::EGLGraphicsBackend; use smithay::backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions, Format}; use smithay::backend::input::{self, Event, InputBackend, InputHandler, KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent}; -use smithay::backend::libinput::{libinput_bind, LibinputInputBackend, LibinputSessionInterface, - PointerAxisEvent as LibinputPointerAxisEvent}; +use smithay::backend::libinput::{libinput_bind, LibinputInputBackend, LibinputSessionInterface}; use smithay::backend::session::{Session, SessionNotifier}; use smithay::backend::session::auto::{auto_session_bind, AutoSession}; use smithay::backend::udev::{primary_gpu, udev_backend_bind, SessionFdDrmDevice, UdevBackend, UdevHandler}; @@ -187,27 +186,60 @@ impl InputHandler for LibinputInputHandler { self.pointer.button(button, state, serial, evt.time()); } fn on_pointer_axis( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: LibinputPointerAxisEvent + &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: event::pointer::PointerAxisEvent ) { - let axis = match evt.axis() { - input::Axis::Vertical => wayland_server::protocol::wl_pointer::Axis::VerticalScroll, - input::Axis::Horizontal => wayland_server::protocol::wl_pointer::Axis::HorizontalScroll, - }; let source = match evt.source() { - input::AxisSource::Continuous | input::AxisSource::Finger => wayland_server::protocol::wl_pointer::AxisSource::Continuous, - input::AxisSource::Wheel | input::AxisSource::WheelTilt => wayland_server::protocol::wl_pointer::AxisSource::Wheel, - }; - let amount = match evt.source() { - input::AxisSource::Continuous | input::AxisSource::Finger => evt.amount(), - input::AxisSource::Wheel | input::AxisSource::WheelTilt => evt.amount() * 3.0, // amount represents steps in that case, + input::AxisSource::Continuous => wayland_server::protocol::wl_pointer::AxisSource::Continuous, + input::AxisSource::Finger => wayland_server::protocol::wl_pointer::AxisSource::Finger, + input::AxisSource::Wheel | input::AxisSource::WheelTilt => { + wayland_server::protocol::wl_pointer::AxisSource::Wheel + } }; + let horizontal_amount = evt.amount(&input::Axis::Horizontal) + .unwrap_or_else(|| evt.amount_discrete(&input::Axis::Horizontal).unwrap() * 3.0); + let vertical_amount = evt.amount(&input::Axis::Vertical) + .unwrap_or_else(|| evt.amount_discrete(&input::Axis::Vertical).unwrap() * 3.0); + let horizontal_amount_discrete = evt.amount_discrete(&input::Axis::Horizontal); + let vertical_amount_discrete = evt.amount_discrete(&input::Axis::Vertical); { let mut event = self.pointer.axis(); - event.source(source) - .value(axis, amount, evt.time()); - if let input::AxisSource::Wheel = evt.source() { - event.discrete(axis, evt.amount() as i32); + event.source(source); + if horizontal_amount != 0.0 { + event.value( + wayland_server::protocol::wl_pointer::Axis::HorizontalScroll, + horizontal_amount, + evt.time(), + ); + if let Some(discrete) = horizontal_amount_discrete { + event.discrete( + wayland_server::protocol::wl_pointer::Axis::HorizontalScroll, + discrete as i32, + ); + } + } else if source == wayland_server::protocol::wl_pointer::AxisSource::Finger { + event.stop( + wayland_server::protocol::wl_pointer::Axis::HorizontalScroll, + evt.time(), + ); + } + if vertical_amount != 0.0 { + event.value( + wayland_server::protocol::wl_pointer::Axis::VerticalScroll, + vertical_amount, + evt.time(), + ); + if let Some(discrete) = vertical_amount_discrete { + event.discrete( + wayland_server::protocol::wl_pointer::Axis::VerticalScroll, + discrete as i32, + ); + } + } else if source == wayland_server::protocol::wl_pointer::AxisSource::Finger { + event.stop( + wayland_server::protocol::wl_pointer::Axis::VerticalScroll, + evt.time(), + ); } event.done(); } diff --git a/examples/winit.rs b/examples/winit.rs index b1a0d6f..24ff502 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -108,27 +108,46 @@ impl InputHandler for WinitInputHandler { fn on_pointer_axis( &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: winit::WinitMouseWheelEvent ) { - let axis = match evt.axis() { - input::Axis::Vertical => wayland_server::protocol::wl_pointer::Axis::VerticalScroll, - input::Axis::Horizontal => wayland_server::protocol::wl_pointer::Axis::HorizontalScroll, - }; let source = match evt.source() { input::AxisSource::Continuous => wayland_server::protocol::wl_pointer::AxisSource::Continuous, input::AxisSource::Wheel => wayland_server::protocol::wl_pointer::AxisSource::Wheel, _ => unreachable!(), //winit does not have more specific sources }; - let amount = match evt.source() { - input::AxisSource::Continuous => evt.amount(), - input::AxisSource::Wheel => evt.amount() * 3.0, // amount represents steps in that case, - _ => unreachable!(), //winit does not have more specific sources - }; + let horizontal_amount = evt.amount(&input::Axis::Horizontal) + .unwrap_or_else(|| evt.amount_discrete(&input::Axis::Horizontal).unwrap() * 3.0); + let vertical_amount = evt.amount(&input::Axis::Vertical) + .unwrap_or_else(|| evt.amount_discrete(&input::Axis::Vertical).unwrap() * 3.0); + let horizontal_amount_discrete = evt.amount_discrete(&input::Axis::Horizontal); + let vertical_amount_discrete = evt.amount_discrete(&input::Axis::Vertical); { let mut event = self.pointer.axis(); - event.source(source) - .value(axis, amount, evt.time()); - if let input::AxisSource::Wheel = evt.source() { - event.discrete(axis, evt.amount() as i32); + event.source(source); + if horizontal_amount != 0.0 { + event.value( + wayland_server::protocol::wl_pointer::Axis::HorizontalScroll, + horizontal_amount, + evt.time(), + ); + if let Some(discrete) = horizontal_amount_discrete { + event.discrete( + wayland_server::protocol::wl_pointer::Axis::HorizontalScroll, + discrete as i32, + ); + } + } + if vertical_amount != 0.0 { + event.value( + wayland_server::protocol::wl_pointer::Axis::VerticalScroll, + vertical_amount, + evt.time(), + ); + if let Some(discrete) = vertical_amount_discrete { + event.discrete( + wayland_server::protocol::wl_pointer::Axis::VerticalScroll, + discrete as i32, + ); + } } event.done(); } diff --git a/src/backend/input.rs b/src/backend/input.rs index 379cdfe..bed7877 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -214,26 +214,32 @@ pub enum AxisSource { /// Trait for pointer events generated by scrolling on an axis. pub trait PointerAxisEvent: Event { - /// `Axis` this event was generated for. - fn axis(&self) -> Axis; - /// Source of the scroll event. Important for interpretation of `amount`. + /// Amount of scrolling in pixels on the given `Axis`. + /// + /// Garanteed to be `Some` when source returns either `AxisSource::Finger` or `AxisSource::Continuous`. + fn amount(&self, axis: &Axis) -> Option; + + /// Amount of scrolling in discrete steps on the given `Axis`. + /// + /// Garanteed to be `Some` when source returns either `AxisSource::Wheel` or `AxisSource::WheelTilt`. + fn amount_discrete(&self, axis: &Axis) -> Option; + + /// Source of the scroll event. fn source(&self) -> AxisSource; - /// Amount of scrolling on the given `Axis`. See `source` for interpretation. - fn amount(&self) -> f64; } impl PointerAxisEvent for UnusedEvent { - fn axis(&self) -> Axis { + fn amount(&self, _axis: &Axis) -> Option { + match *self {} + } + + fn amount_discrete(&self, _axis: &Axis) -> Option { match *self {} } fn source(&self) -> AxisSource { match *self {} } - - fn amount(&self) -> f64 { - match *self {} - } } /// Trait for pointer events generated by relative device movement. diff --git a/src/backend/libinput.rs b/src/backend/libinput.rs index 84becdf..caef89d 100644 --- a/src/backend/libinput.rs +++ b/src/backend/libinput.rs @@ -1,6 +1,7 @@ //! Implementation of input backend trait for types provided by `libinput` use backend::input as backend; +use backend::input::Axis; #[cfg(feature = "backend_session")] use backend::session::{AsErrno, Session, SessionObserver}; use input as libinput; @@ -10,7 +11,6 @@ use std::hash::{Hash, Hasher}; use std::io::Error as IoError; use std::os::unix::io::RawFd; use std::path::Path; -use std::rc::Rc; use wayland_server::EventLoopHandle; use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest}; @@ -73,35 +73,23 @@ impl backend::KeyboardKeyEvent for event::keyboard::KeyboardKeyEvent { } } -/// Wrapper for libinput pointer axis events to implement `backend::input::PointerAxisEvent` -pub struct PointerAxisEvent { - axis: event::pointer::Axis, - event: Rc, -} - -impl<'a> backend::Event for PointerAxisEvent { +impl<'a> backend::Event for event::pointer::PointerAxisEvent { fn time(&self) -> u32 { - use input::event::pointer::PointerEventTrait; - self.event.time() + event::pointer::PointerEventTrait::time(self) } } -impl<'a> backend::PointerAxisEvent for PointerAxisEvent { - fn axis(&self) -> backend::Axis { - self.axis.into() +impl backend::PointerAxisEvent for event::pointer::PointerAxisEvent { + fn amount(&self, axis: &Axis) -> Option { + Some(self.axis_value((*axis).into())) + } + + fn amount_discrete(&self, axis: &Axis) -> Option { + self.axis_value_discrete((*axis).into()) } fn source(&self) -> backend::AxisSource { - self.event.axis_source().into() - } - - fn amount(&self) -> f64 { - match self.source() { - backend::AxisSource::Finger | backend::AxisSource::Continuous => self.event.axis_value(self.axis), - backend::AxisSource::Wheel | backend::AxisSource::WheelTilt => { - self.event.axis_value_discrete(self.axis).unwrap() - } - } + self.axis_source().into() } } @@ -258,7 +246,7 @@ impl backend::InputBackend for LibinputInputBackend { type EventError = IoError; type KeyboardKeyEvent = event::keyboard::KeyboardKeyEvent; - type PointerAxisEvent = PointerAxisEvent; + type PointerAxisEvent = event::pointer::PointerAxisEvent; type PointerButtonEvent = event::pointer::PointerButtonEvent; type PointerMotionEvent = event::pointer::PointerMotionEvent; type PointerMotionAbsoluteEvent = event::pointer::PointerMotionAbsoluteEvent; @@ -492,37 +480,8 @@ impl backend::InputBackend for LibinputInputBackend { handler.on_pointer_move_absolute(evlh, seat, motion_abs_event); } PointerEvent::Axis(axis_event) => { - let rc_axis_event = Rc::new(axis_event); - if rc_axis_event.has_axis(Axis::Vertical) { - trace!( - self.logger, - "Calling on_pointer_axis for Axis::Vertical with {:?}", - *rc_axis_event - ); - handler.on_pointer_axis( - evlh, - seat, - self::PointerAxisEvent { - axis: Axis::Vertical, - event: rc_axis_event.clone(), - }, - ); - } - if rc_axis_event.has_axis(Axis::Horizontal) { - trace!( - self.logger, - "Calling on_pointer_axis for Axis::Horizontal with {:?}", - *rc_axis_event - ); - handler.on_pointer_axis( - evlh, - seat, - self::PointerAxisEvent { - axis: Axis::Horizontal, - event: rc_axis_event.clone(), - }, - ); - } + trace!(self.logger, "Calling on_pointer_axis with {:?}", axis_event); + handler.on_pointer_axis(evlh, seat, axis_event); } PointerEvent::Button(button_event) => { trace!( @@ -564,6 +523,15 @@ impl From for backend::Axis { } } +impl From for event::pointer::Axis { + fn from(axis: backend::Axis) -> Self { + match axis { + backend::Axis::Vertical => event::pointer::Axis::Vertical, + backend::Axis::Horizontal => event::pointer::Axis::Horizontal, + } + } +} + impl From for backend::AxisSource { fn from(libinput: event::pointer::AxisSource) -> Self { match libinput { diff --git a/src/backend/winit.rs b/src/backend/winit.rs index f3ef266..40c538f 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -388,7 +388,6 @@ impl PointerMotionAbsoluteEvent for WinitMouseMovedEvent { #[derive(Debug, Clone, Copy, PartialEq)] /// Winit-Backend internal event wrapping winit's types into a `PointerAxisEvent` pub struct WinitMouseWheelEvent { - axis: Axis, time: u32, delta: MouseScrollDelta, } @@ -400,10 +399,6 @@ impl BackendEvent for WinitMouseWheelEvent { } impl PointerAxisEvent for WinitMouseWheelEvent { - fn axis(&self) -> Axis { - self.axis - } - fn source(&self) -> AxisSource { match self.delta { MouseScrollDelta::LineDelta(_, _) => AxisSource::Wheel, @@ -411,12 +406,19 @@ impl PointerAxisEvent for WinitMouseWheelEvent { } } - fn amount(&self) -> f64 { - match (self.axis, self.delta) { - (Axis::Horizontal, MouseScrollDelta::LineDelta(x, _)) - | (Axis::Horizontal, MouseScrollDelta::PixelDelta(x, _)) => x as f64, - (Axis::Vertical, MouseScrollDelta::LineDelta(_, y)) - | (Axis::Vertical, MouseScrollDelta::PixelDelta(_, y)) => y as f64, + fn amount(&self, axis: &Axis) -> Option { + match (axis, self.delta) { + (&Axis::Horizontal, MouseScrollDelta::PixelDelta(x, _)) => Some(x as f64), + (&Axis::Vertical, MouseScrollDelta::PixelDelta(_, y)) => Some(y as f64), + (_, MouseScrollDelta::LineDelta(_, _)) => None, + } + } + + fn amount_discrete(&self, axis: &Axis) -> Option { + match (axis, self.delta) { + (&Axis::Horizontal, MouseScrollDelta::LineDelta(x, _)) => Some(x as f64), + (&Axis::Vertical, MouseScrollDelta::LineDelta(_, y)) => Some(y as f64), + (_, MouseScrollDelta::PixelDelta(_, _)) => None, } } } @@ -764,36 +766,11 @@ impl InputBackend for WinitInputBackend { }, ) } - (WindowEvent::MouseWheel { delta, .. }, Some(handler), _) => match delta { - MouseScrollDelta::LineDelta(x, y) | MouseScrollDelta::PixelDelta(x, y) => { - if x != 0.0 { - let event = WinitMouseWheelEvent { - axis: Axis::Horizontal, - time, - delta: delta, - }; - trace!( - logger, - "Calling on_pointer_axis for Axis::Horizontal with {:?}", - x - ); - handler.on_pointer_axis(evlh, seat, event); - } - if y != 0.0 { - let event = WinitMouseWheelEvent { - axis: Axis::Vertical, - time, - delta: delta, - }; - trace!( - logger, - "Calling on_pointer_axis for Axis::Vertical with {:?}", - y - ); - handler.on_pointer_axis(evlh, seat, event); - } - } - }, + (WindowEvent::MouseWheel { delta, .. }, Some(handler), _) => { + let event = WinitMouseWheelEvent { time, delta }; + trace!(logger, "Calling on_pointer_axis with {:?}", delta); + handler.on_pointer_axis(evlh, seat, event); + } (WindowEvent::MouseInput { state, button, .. }, Some(handler), _) => { trace!( logger,