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::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<LibinputInputBackend> 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();
}

View File

@ -108,27 +108,46 @@ impl InputHandler<winit::WinitInputBackend> 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();
}

View File

@ -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<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;
/// 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<f64> {
match *self {}
}
fn amount_discrete(&self, _axis: &Axis) -> Option<f64> {
match *self {}
}
fn source(&self) -> AxisSource {
match *self {}
}
fn amount(&self) -> f64 {
match *self {}
}
}
/// 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`
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<event::pointer::PointerAxisEvent>,
}
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<f64> {
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 {
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<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 {
fn from(libinput: event::pointer::AxisSource) -> Self {
match libinput {

View File

@ -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<f64> {
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<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 {
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
);
(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);
}
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), _) => {
trace!(
logger,