Refactor PointerAxisEvent to handle multiple axis

This commit is contained in:
Drakulix 2018-03-22 16:09:58 +01:00
parent daccddf9b6
commit d051e141cf
5 changed files with 138 additions and 136 deletions

View File

@ -34,8 +34,7 @@ use smithay::backend::graphics::egl::EGLGraphicsBackend;
use smithay::backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions, Format}; use smithay::backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions, Format};
use smithay::backend::input::{self, Event, InputBackend, InputHandler, KeyState, KeyboardKeyEvent, use smithay::backend::input::{self, Event, InputBackend, InputHandler, KeyState, KeyboardKeyEvent,
PointerAxisEvent, PointerButtonEvent}; PointerAxisEvent, PointerButtonEvent};
use smithay::backend::libinput::{libinput_bind, LibinputInputBackend, LibinputSessionInterface, use smithay::backend::libinput::{libinput_bind, LibinputInputBackend, LibinputSessionInterface};
PointerAxisEvent as LibinputPointerAxisEvent};
use smithay::backend::session::{Session, SessionNotifier}; use smithay::backend::session::{Session, SessionNotifier};
use smithay::backend::session::auto::{auto_session_bind, AutoSession}; use smithay::backend::session::auto::{auto_session_bind, AutoSession};
use smithay::backend::udev::{primary_gpu, udev_backend_bind, SessionFdDrmDevice, UdevBackend, UdevHandler}; use smithay::backend::udev::{primary_gpu, udev_backend_bind, SessionFdDrmDevice, UdevBackend, UdevHandler};
@ -187,27 +186,60 @@ impl InputHandler<LibinputInputBackend> for LibinputInputHandler {
self.pointer.button(button, state, serial, evt.time()); self.pointer.button(button, state, serial, evt.time());
} }
fn on_pointer_axis( 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() { let source = match evt.source() {
input::AxisSource::Continuous | input::AxisSource::Finger => wayland_server::protocol::wl_pointer::AxisSource::Continuous, input::AxisSource::Continuous => wayland_server::protocol::wl_pointer::AxisSource::Continuous,
input::AxisSource::Wheel | input::AxisSource::WheelTilt => wayland_server::protocol::wl_pointer::AxisSource::Wheel, input::AxisSource::Finger => wayland_server::protocol::wl_pointer::AxisSource::Finger,
}; input::AxisSource::Wheel | input::AxisSource::WheelTilt => {
let amount = match evt.source() { wayland_server::protocol::wl_pointer::AxisSource::Wheel
input::AxisSource::Continuous | input::AxisSource::Finger => evt.amount(), }
input::AxisSource::Wheel | input::AxisSource::WheelTilt => evt.amount() * 3.0, // amount represents steps in that case,
}; };
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(); let mut event = self.pointer.axis();
event.source(source) event.source(source);
.value(axis, amount, evt.time()); if horizontal_amount != 0.0 {
if let input::AxisSource::Wheel = evt.source() { event.value(
event.discrete(axis, evt.amount() as i32); 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(); event.done();
} }

View File

@ -108,27 +108,46 @@ impl InputHandler<winit::WinitInputBackend> for WinitInputHandler {
fn on_pointer_axis( fn on_pointer_axis(
&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: winit::WinitMouseWheelEvent &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() { let source = match evt.source() {
input::AxisSource::Continuous => wayland_server::protocol::wl_pointer::AxisSource::Continuous, input::AxisSource::Continuous => wayland_server::protocol::wl_pointer::AxisSource::Continuous,
input::AxisSource::Wheel => wayland_server::protocol::wl_pointer::AxisSource::Wheel, input::AxisSource::Wheel => wayland_server::protocol::wl_pointer::AxisSource::Wheel,
_ => unreachable!(), //winit does not have more specific sources _ => unreachable!(), //winit does not have more specific sources
}; };
let amount = match evt.source() { let horizontal_amount = evt.amount(&input::Axis::Horizontal)
input::AxisSource::Continuous => evt.amount(), .unwrap_or_else(|| evt.amount_discrete(&input::Axis::Horizontal).unwrap() * 3.0);
input::AxisSource::Wheel => evt.amount() * 3.0, // amount represents steps in that case, let vertical_amount = evt.amount(&input::Axis::Vertical)
_ => unreachable!(), //winit does not have more specific sources .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(); let mut event = self.pointer.axis();
event.source(source) event.source(source);
.value(axis, amount, evt.time()); if horizontal_amount != 0.0 {
if let input::AxisSource::Wheel = evt.source() { event.value(
event.discrete(axis, evt.amount() as i32); 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(); event.done();
} }

View File

@ -214,26 +214,32 @@ pub enum AxisSource {
/// Trait for pointer events generated by scrolling on an axis. /// Trait for pointer events generated by scrolling on an axis.
pub trait PointerAxisEvent: Event { pub trait PointerAxisEvent: Event {
/// `Axis` this event was generated for. /// Amount of scrolling in pixels on the given `Axis`.
fn axis(&self) -> Axis; ///
/// Source of the scroll event. Important for interpretation of `amount`. /// Garanteed to be `Some` when source returns either `AxisSource::Finger` or `AxisSource::Continuous`.
fn amount(&self, axis: &Axis) -> Option<f64>;
/// 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<f64>;
/// Source of the scroll event.
fn source(&self) -> AxisSource; fn source(&self) -> AxisSource;
/// Amount of scrolling on the given `Axis`. See `source` for interpretation.
fn amount(&self) -> f64;
} }
impl PointerAxisEvent for UnusedEvent { impl PointerAxisEvent for UnusedEvent {
fn axis(&self) -> Axis { fn amount(&self, _axis: &Axis) -> Option<f64> {
match *self {}
}
fn amount_discrete(&self, _axis: &Axis) -> Option<f64> {
match *self {} match *self {}
} }
fn source(&self) -> AxisSource { fn source(&self) -> AxisSource {
match *self {} match *self {}
} }
fn amount(&self) -> f64 {
match *self {}
}
} }
/// Trait for pointer events generated by relative device movement. /// Trait for pointer events generated by relative device movement.

View File

@ -1,6 +1,7 @@
//! Implementation of input backend trait for types provided by `libinput` //! Implementation of input backend trait for types provided by `libinput`
use backend::input as backend; use backend::input as backend;
use backend::input::Axis;
#[cfg(feature = "backend_session")] #[cfg(feature = "backend_session")]
use backend::session::{AsErrno, Session, SessionObserver}; use backend::session::{AsErrno, Session, SessionObserver};
use input as libinput; use input as libinput;
@ -10,7 +11,6 @@ use std::hash::{Hash, Hasher};
use std::io::Error as IoError; use std::io::Error as IoError;
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
use std::path::Path; use std::path::Path;
use std::rc::Rc;
use wayland_server::EventLoopHandle; use wayland_server::EventLoopHandle;
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest}; 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` impl<'a> backend::Event for event::pointer::PointerAxisEvent {
pub struct PointerAxisEvent {
axis: event::pointer::Axis,
event: Rc<event::pointer::PointerAxisEvent>,
}
impl<'a> backend::Event for PointerAxisEvent {
fn time(&self) -> u32 { fn time(&self) -> u32 {
use input::event::pointer::PointerEventTrait; event::pointer::PointerEventTrait::time(self)
self.event.time()
} }
} }
impl<'a> backend::PointerAxisEvent for PointerAxisEvent { impl backend::PointerAxisEvent for event::pointer::PointerAxisEvent {
fn axis(&self) -> backend::Axis { fn amount(&self, axis: &Axis) -> Option<f64> {
self.axis.into() Some(self.axis_value((*axis).into()))
}
fn amount_discrete(&self, axis: &Axis) -> Option<f64> {
self.axis_value_discrete((*axis).into())
} }
fn source(&self) -> backend::AxisSource { fn source(&self) -> backend::AxisSource {
self.event.axis_source().into() self.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()
}
}
} }
} }
@ -258,7 +246,7 @@ impl backend::InputBackend for LibinputInputBackend {
type EventError = IoError; type EventError = IoError;
type KeyboardKeyEvent = event::keyboard::KeyboardKeyEvent; type KeyboardKeyEvent = event::keyboard::KeyboardKeyEvent;
type PointerAxisEvent = PointerAxisEvent; type PointerAxisEvent = event::pointer::PointerAxisEvent;
type PointerButtonEvent = event::pointer::PointerButtonEvent; type PointerButtonEvent = event::pointer::PointerButtonEvent;
type PointerMotionEvent = event::pointer::PointerMotionEvent; type PointerMotionEvent = event::pointer::PointerMotionEvent;
type PointerMotionAbsoluteEvent = event::pointer::PointerMotionAbsoluteEvent; type PointerMotionAbsoluteEvent = event::pointer::PointerMotionAbsoluteEvent;
@ -492,37 +480,8 @@ impl backend::InputBackend for LibinputInputBackend {
handler.on_pointer_move_absolute(evlh, seat, motion_abs_event); handler.on_pointer_move_absolute(evlh, seat, motion_abs_event);
} }
PointerEvent::Axis(axis_event) => { PointerEvent::Axis(axis_event) => {
let rc_axis_event = Rc::new(axis_event); trace!(self.logger, "Calling on_pointer_axis with {:?}", axis_event);
if rc_axis_event.has_axis(Axis::Vertical) { handler.on_pointer_axis(evlh, seat, axis_event);
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(),
},
);
}
} }
PointerEvent::Button(button_event) => { PointerEvent::Button(button_event) => {
trace!( trace!(
@ -564,6 +523,15 @@ impl From<event::pointer::Axis> for backend::Axis {
} }
} }
impl From<backend::Axis> 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<event::pointer::AxisSource> for backend::AxisSource { impl From<event::pointer::AxisSource> for backend::AxisSource {
fn from(libinput: event::pointer::AxisSource) -> Self { fn from(libinput: event::pointer::AxisSource) -> Self {
match libinput { match libinput {

View File

@ -388,7 +388,6 @@ impl PointerMotionAbsoluteEvent for WinitMouseMovedEvent {
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
/// Winit-Backend internal event wrapping winit's types into a `PointerAxisEvent` /// Winit-Backend internal event wrapping winit's types into a `PointerAxisEvent`
pub struct WinitMouseWheelEvent { pub struct WinitMouseWheelEvent {
axis: Axis,
time: u32, time: u32,
delta: MouseScrollDelta, delta: MouseScrollDelta,
} }
@ -400,10 +399,6 @@ impl BackendEvent for WinitMouseWheelEvent {
} }
impl PointerAxisEvent for WinitMouseWheelEvent { impl PointerAxisEvent for WinitMouseWheelEvent {
fn axis(&self) -> Axis {
self.axis
}
fn source(&self) -> AxisSource { fn source(&self) -> AxisSource {
match self.delta { match self.delta {
MouseScrollDelta::LineDelta(_, _) => AxisSource::Wheel, MouseScrollDelta::LineDelta(_, _) => AxisSource::Wheel,
@ -411,12 +406,19 @@ impl PointerAxisEvent for WinitMouseWheelEvent {
} }
} }
fn amount(&self) -> f64 { fn amount(&self, axis: &Axis) -> Option<f64> {
match (self.axis, self.delta) { match (axis, self.delta) {
(Axis::Horizontal, MouseScrollDelta::LineDelta(x, _)) (&Axis::Horizontal, MouseScrollDelta::PixelDelta(x, _)) => Some(x as f64),
| (Axis::Horizontal, MouseScrollDelta::PixelDelta(x, _)) => x as f64, (&Axis::Vertical, MouseScrollDelta::PixelDelta(_, y)) => Some(y as f64),
(Axis::Vertical, MouseScrollDelta::LineDelta(_, y)) (_, MouseScrollDelta::LineDelta(_, _)) => None,
| (Axis::Vertical, MouseScrollDelta::PixelDelta(_, y)) => y as f64, }
}
fn amount_discrete(&self, axis: &Axis) -> Option<f64> {
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 { (WindowEvent::MouseWheel { delta, .. }, Some(handler), _) => {
MouseScrollDelta::LineDelta(x, y) | MouseScrollDelta::PixelDelta(x, y) => { let event = WinitMouseWheelEvent { time, delta };
if x != 0.0 { trace!(logger, "Calling on_pointer_axis with {:?}", delta);
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); 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::MouseInput { state, button, .. }, Some(handler), _) => { (WindowEvent::MouseInput { state, button, .. }, Some(handler), _) => {
trace!( trace!(
logger, logger,