From 07743faad2cbe2cdefbed51b7441975d824b9294 Mon Sep 17 00:00:00 2001 From: Poly Date: Mon, 5 Jul 2021 23:57:25 +0200 Subject: [PATCH] Apply suggestions from code review & Rebase --- anvil/src/input_handler.rs | 130 ++++++++++++---------- src/backend/input.rs | 7 +- src/backend/input/tablet.rs | 49 ++++---- src/backend/libinput.rs | 11 +- src/backend/libinput/tablet.rs | 30 ++--- src/backend/winit.rs | 6 +- src/wayland/tablet_manager/mod.rs | 9 +- src/wayland/tablet_manager/tablet.rs | 15 +-- src/wayland/tablet_manager/tablet_seat.rs | 10 +- src/wayland/tablet_manager/tablet_tool.rs | 14 +-- 10 files changed, 145 insertions(+), 136 deletions(-) diff --git a/anvil/src/input_handler.rs b/anvil/src/input_handler.rs index 7a21b0f..07a07c0 100644 --- a/anvil/src/input_handler.rs +++ b/anvil/src/input_handler.rs @@ -16,7 +16,7 @@ use smithay::{ wayland::{ output::Mode, seat::{keysyms as xkb, AxisFrame, Keysym, ModifiersState}, - tablet_manager::TabletSeatTrait, + tablet_manager::{TabletDescriptor, TabletSeatTrait}, SERIAL_COUNTER as SCOUNTER, }, }; @@ -246,14 +246,16 @@ impl AnvilState { InputEvent::TabletToolButton { event, .. } => self.on_tablet_button::(event), InputEvent::DeviceAdded { device } => { if device.has_capability(DeviceCapability::TabletTool) { - self.seat.tablet_seat().add_tablet(&device.into()); + self.seat + .tablet_seat() + .add_tablet(&TabletDescriptor::from(&device)); } } InputEvent::DeviceRemoved { device } => { if device.has_capability(DeviceCapability::TabletTool) { let tablet_seat = self.seat.tablet_seat(); - tablet_seat.remove_tablet(&device.into()); + tablet_seat.remove_tablet(&TabletDescriptor::from(&device)); // If there are no tablets in seat we can remove all tools if tablet_seat.count_tablets() == 0 { @@ -283,68 +285,84 @@ impl AnvilState { } fn on_tablet_tool_axis(&mut self, evt: B::TabletToolAxisEvent) { - if let Some(out) = self.backend_data.output_map.first() { - self.pointer_location = evt.position_transformed(out.size); + let output_map = self.output_map.borrow(); + let pointer_location = &mut self.pointer_location; + let tablet_seat = self.seat.tablet_seat(); + let window_map = self.window_map.borrow(); - let under = self.window_map.borrow().get_surface_under(self.pointer_location); - let tablet = self.seat.tablet_seat().get_tablet(&evt.device().into()); - let tool = self.seat.tablet_seat().get_tool(&evt.tool()); + output_map + .with_primary(|_, rect| { + pointer_location.0 = evt.x_transformed(rect.width as u32) + rect.x as f64; + pointer_location.1 = evt.y_transformed(rect.height as u32) + rect.y as f64; - if let (Some(tablet), Some(tool)) = (tablet, tool) { - if evt.pressure_has_changed() { - tool.pressure(evt.pressure()); - } - if evt.distance_has_changed() { - tool.distance(evt.distance()); - } - if evt.tilt_has_changed() { - tool.tilt(evt.tilt()); - } - if evt.slider_has_changed() { - tool.slider_position(evt.slider_position()); - } - if evt.rotation_has_changed() { - tool.rotation(evt.rotation()); - } - if evt.wheel_has_changed() { - tool.wheel(evt.wheel_delta(), evt.wheel_delta_discrete()); - } + let under = window_map.get_surface_under(*pointer_location); + let tablet = tablet_seat.get_tablet(&TabletDescriptor::from(&evt.device())); + let tool = tablet_seat.get_tool(&evt.tool()); - tool.motion( - self.pointer_location, - under, - &tablet, - SCOUNTER.next_serial(), - evt.time(), - ); - } - } - } + if let (Some(tablet), Some(tool)) = (tablet, tool) { + if evt.pressure_has_changed() { + tool.pressure(evt.pressure()); + } + if evt.distance_has_changed() { + tool.distance(evt.distance()); + } + if evt.tilt_has_changed() { + tool.tilt(evt.tilt()); + } + if evt.slider_has_changed() { + tool.slider_position(evt.slider_position()); + } + if evt.rotation_has_changed() { + tool.rotation(evt.rotation()); + } + if evt.wheel_has_changed() { + tool.wheel(evt.wheel_delta(), evt.wheel_delta_discrete()); + } - fn on_tablet_tool_proximity(&mut self, evt: B::TabletToolProximityEvent) { - if let Some(out) = self.backend_data.output_map.first() { - let tool = evt.tool(); - self.seat.tablet_seat().add_tool(&tool); - - self.pointer_location = evt.position_transformed(out.size); - - let under = self.window_map.borrow().get_surface_under(self.pointer_location); - let tablet = self.seat.tablet_seat().get_tablet(&evt.device().into()); - let tool = self.seat.tablet_seat().get_tool(&tool); - - if let (Some(under), Some(tablet), Some(tool)) = (under, tablet, tool) { - match evt.state() { - ProximityState::In => tool.proximity_in( - self.pointer_location, + tool.motion( + *pointer_location, under, &tablet, SCOUNTER.next_serial(), evt.time(), - ), - ProximityState::Out => tool.proximity_out(evt.time()), + ); } - } - } + }) + .unwrap(); + } + + fn on_tablet_tool_proximity(&mut self, evt: B::TabletToolProximityEvent) { + let output_map = self.output_map.borrow(); + let pointer_location = &mut self.pointer_location; + let tablet_seat = self.seat.tablet_seat(); + let window_map = self.window_map.borrow(); + + output_map + .with_primary(|_, rect| { + let tool = evt.tool(); + tablet_seat.add_tool(&tool); + + pointer_location.0 = evt.x_transformed(rect.width as u32) + rect.x as f64; + pointer_location.1 = evt.y_transformed(rect.height as u32) + rect.y as f64; + + let under = window_map.get_surface_under(*pointer_location); + let tablet = tablet_seat.get_tablet(&TabletDescriptor::from(&evt.device())); + let tool = tablet_seat.get_tool(&tool); + + if let (Some(under), Some(tablet), Some(tool)) = (under, tablet, tool) { + match evt.state() { + ProximityState::In => tool.proximity_in( + *pointer_location, + under, + &tablet, + SCOUNTER.next_serial(), + evt.time(), + ), + ProximityState::Out => tool.proximity_out(evt.time()), + } + } + }) + .unwrap(); } fn on_tablet_tool_tip(&mut self, evt: B::TabletToolTipEvent) { diff --git a/src/backend/input.rs b/src/backend/input.rs index 29911da..7def5a8 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -20,11 +20,8 @@ pub trait Device: PartialEq + Eq + std::hash::Hash { /// Test if this device has a specific capability fn has_capability(&self, capability: DeviceCapability) -> bool; - /// Get the product ID for this device. - fn id_product(&self) -> Option; - - /// Get the vendor ID for this device. - fn id_vendor(&self) -> Option; + /// Returns device USB (product,vendor) id + fn usb_id(&self) -> Option<(u32, u32)>; /// Returns the syspath of the device. /// diff --git a/src/backend/input/tablet.rs b/src/backend/input/tablet.rs index 4ebcb33..91813c7 100644 --- a/src/backend/input/tablet.rs +++ b/src/backend/input/tablet.rs @@ -1,4 +1,5 @@ use super::{ButtonState, Event, InputBackend, UnusedEvent}; +use bitflags::bitflags; /// Description of physical tablet tool #[derive(Debug, Clone, Hash, Eq, PartialEq)] @@ -35,23 +36,24 @@ pub enum TabletToolType { Totem, } -/// Describes extra capabilities on a tablet. -/// -/// Any tool must provide x and y values, extra axes are device-specific. -#[derive(Debug, Clone, Hash, Eq, PartialEq)] -pub struct TabletToolCapabilitys { - /// Tilt axes - pub tilt: bool, - /// Pressure axis - pub pressure: bool, - /// Distance axis - pub distance: bool, - /// Z-rotation axis - pub rotation: bool, - /// Slider axis - pub slider: bool, - /// Wheel axis - pub wheel: bool, +bitflags! { + /// Describes extra capabilities on a tablet. + /// + /// Any tool must provide x and y values, extra axes are device-specific. + pub struct TabletToolCapabilitys: u32 { + /// Tilt axes + const TILT = 1; + /// Pressure axis + const PRESSURE = 2; + /// Distance axis + const DISTANCE = 4; + /// Z-rotation axis + const ROTATION = 16; + /// Slider axis + const SLIDER = 32; + /// Wheel axis + const WHEEL = 64; + } } /// Tablet tool event @@ -110,7 +112,7 @@ pub trait TabletToolEvent { /// Return the current absolute Y coordinate of the tablet tool event, transformed to screen coordinates. fn y_transformed(&self, height: u32) -> f64; - /// Returns the current pressure being applied on the tool in use, normalized to the range [0, 1]. + /// Returns the current distance from the tablet's sensor, normalized to the range [0, 1] /// /// If this axis does not exist on the current tool, this function returns 0. fn distance(&self) -> f64; @@ -118,7 +120,7 @@ pub trait TabletToolEvent { /// Check if the distance axis was updated in this event. fn distance_has_changed(&self) -> bool; - /// Returns the current distance from the tablet's sensor, normalized to the range [0, 1] + /// Returns the current pressure being applied on the tool in use, normalized to the range [0, 1]. /// /// If this axis does not exist on the current tool, this function returns 0. fn pressure(&self) -> f64; @@ -168,7 +170,8 @@ pub trait TabletToolEvent { /// Returns the current z rotation of the tool in degrees, clockwise from the tool's logical neutral position. /// - /// For tools of type Mouse and Lens the logical neutral position is pointing to the current logical north of the tablet. For tools of type Brush, the logical neutral position is with the buttons pointing up. + /// For tools of type Mouse and Lens the logical neutral position is pointing to the current logical north of the tablet. + /// For tools of type Brush, the logical neutral position is with the buttons pointing up. /// /// If this axis does not exist on the current tool, this function returns 0. fn rotation(&self) -> f64; @@ -264,7 +267,8 @@ impl TabletToolAxisEvent for UnusedEvent {} /// detectable distance of the tablet device. A tool that is out of proximity cannot /// generate events. /// -/// On some hardware a tool goes out of proximity when it ceases to touch the surface. On /// other hardware, the tool is still detectable within a short distance (a few cm) off +/// On some hardware a tool goes out of proximity when it ceases to touch the surface. On +/// other hardware, the tool is still detectable within a short distance (a few cm) off /// the surface. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ProximityState { @@ -339,7 +343,8 @@ pub trait TabletToolButtonEvent: TabletToolEvent + Event /// Return the button that triggered this event. fn button(&self) -> u32; - /// For the button of a TabletToolButtonEvent, return the total number of buttons pressed on all devices on the associated seat after the the event was triggered. + /// For the button of a TabletToolButtonEvent, + /// return the total number of buttons pressed on all devices on the associated seat after the the event was triggered. fn seat_button_count(&self) -> u32; /// Return the button state of the event. diff --git a/src/backend/libinput.rs b/src/backend/libinput.rs index 6ceb91b..8da6a29 100644 --- a/src/backend/libinput.rs +++ b/src/backend/libinput.rs @@ -97,12 +97,11 @@ impl backend::Device for libinput::Device { libinput::Device::has_capability(self, capability.into()) } - fn id_product(&self) -> Option { - Some(libinput::Device::id_product(self)) - } - - fn id_vendor(&self) -> Option { - Some(libinput::Device::id_vendor(self)) + fn usb_id(&self) -> Option<(u32, u32)> { + Some(( + libinput::Device::id_product(self), + libinput::Device::id_vendor(self), + )) } fn syspath(&self) -> Option { diff --git a/src/backend/libinput/tablet.rs b/src/backend/libinput/tablet.rs index fd0744d..f32eed8 100644 --- a/src/backend/libinput/tablet.rs +++ b/src/backend/libinput/tablet.rs @@ -9,16 +9,16 @@ use input::event::{tablet_tool, EventTrait}; use super::LibinputInputBackend; /// Marker for tablet tool events -pub trait IsTabetEvent: tablet_tool::TabletToolEventTrait + EventTrait {} +pub trait IsTabletEvent: tablet_tool::TabletToolEventTrait + EventTrait {} -impl IsTabetEvent for tablet_tool::TabletToolAxisEvent {} -impl IsTabetEvent for tablet_tool::TabletToolProximityEvent {} -impl IsTabetEvent for tablet_tool::TabletToolTipEvent {} -impl IsTabetEvent for tablet_tool::TabletToolButtonEvent {} +impl IsTabletEvent for tablet_tool::TabletToolAxisEvent {} +impl IsTabletEvent for tablet_tool::TabletToolProximityEvent {} +impl IsTabletEvent for tablet_tool::TabletToolTipEvent {} +impl IsTabletEvent for tablet_tool::TabletToolButtonEvent {} impl backend::Event for E where - E: IsTabetEvent, + E: IsTabletEvent, { fn time(&self) -> u32 { tablet_tool::TabletToolEventTrait::time(self) @@ -51,7 +51,7 @@ impl backend::TabletToolTipEvent for tablet_tool::TabletTo impl backend::TabletToolEvent for E where - E: IsTabetEvent + event::EventTrait, + E: IsTabletEvent + event::EventTrait, { fn tool(&self) -> TabletToolDescriptor { let tool = self.tool(); @@ -70,14 +70,14 @@ where let hardware_serial = tool.serial(); let hardware_id_wacom = tool.tool_id(); - let capabilitys = TabletToolCapabilitys { - tilt: tool.has_tilt(), - pressure: tool.has_pressure(), - distance: tool.has_distance(), - rotation: tool.has_rotation(), - slider: tool.has_slider(), - wheel: tool.has_wheel(), - }; + let mut capabilitys = TabletToolCapabilitys::empty(); + + capabilitys.set(TabletToolCapabilitys::TILT, tool.has_tilt()); + capabilitys.set(TabletToolCapabilitys::PRESSURE, tool.has_pressure()); + capabilitys.set(TabletToolCapabilitys::DISTANCE, tool.has_distance()); + capabilitys.set(TabletToolCapabilitys::ROTATION, tool.has_rotation()); + capabilitys.set(TabletToolCapabilitys::SLIDER, tool.has_slider()); + capabilitys.set(TabletToolCapabilitys::WHEEL, tool.has_wheel()); TabletToolDescriptor { tool_type, diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 4b18f10..e62200a 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -308,11 +308,7 @@ impl Device for WinitVirtualDevice { ) } - fn id_product(&self) -> Option { - None - } - - fn id_vendor(&self) -> Option { + fn usb_id(&self) -> Option<(u32, u32)> { None } diff --git a/src/wayland/tablet_manager/mod.rs b/src/wayland/tablet_manager/mod.rs index 3dbcd39..b083859 100644 --- a/src/wayland/tablet_manager/mod.rs +++ b/src/wayland/tablet_manager/mod.rs @@ -26,8 +26,7 @@ //! .tablet_seat() // Get TabletSeat asosiated with this seat //! .add_tablet(&TabletDescriptor { // Add a new tablet to a seat //! name: "Test".into(), -//! id_product: None, -//! id_vendor: None, +//! usb_id: None, //! syspath: None, //! }); //! @@ -75,11 +74,9 @@ pub fn init_tablet_manager_global(display: &mut Display) -> Global(); + let tablet_seat = user_data.get::().unwrap(); - if let Some(tablet_seat) = tablet_seat { - tablet_seat.add_instance(instance); - } + tablet_seat.add_instance(instance); } zwp_tablet_manager_v2::Request::Destroy => { // Nothing to do diff --git a/src/wayland/tablet_manager/tablet.rs b/src/wayland/tablet_manager/tablet.rs index e6ec81f..bb1c8a2 100644 --- a/src/wayland/tablet_manager/tablet.rs +++ b/src/wayland/tablet_manager/tablet.rs @@ -14,21 +14,18 @@ use crate::backend::input::Device; pub struct TabletDescriptor { /// Tablet device name pub name: String, - /// Tablet device USB product id - pub id_product: Option, - /// Tablet device USB vendor id - pub id_vendor: Option, + /// Tablet device USB (product,vendor) id + pub usb_id: Option<(u32, u32)>, /// Path to the device pub syspath: Option, } -impl From for TabletDescriptor { - fn from(device: D) -> Self { +impl From<&D> for TabletDescriptor { + fn from(device: &D) -> Self { TabletDescriptor { name: device.name(), syspath: device.syspath(), - id_product: device.id_product(), - id_vendor: device.id_vendor(), + usb_id: device.usb_id(), } } } @@ -67,7 +64,7 @@ impl TabletHandle { wl_tablet.name(tablet.name.clone()); - if let (Some(id_product), Some(id_vendor)) = (tablet.id_product, tablet.id_vendor) { + if let Some((id_product, id_vendor)) = tablet.usb_id { wl_tablet.id(id_product, id_vendor); } diff --git a/src/wayland/tablet_manager/tablet_seat.rs b/src/wayland/tablet_manager/tablet_seat.rs index 94683be..ea3d489 100644 --- a/src/wayland/tablet_manager/tablet_seat.rs +++ b/src/wayland/tablet_manager/tablet_seat.rs @@ -43,7 +43,7 @@ impl fmt::Debug for TabletSeat { /// /// TabletSeat extends `Seat` with graphic tablet specyfic functionality /// -/// TabletSeatHandle can be used to advertise avalible graphics tablets and tools to wayland clients +/// TabletSeatHandle can be used to advertise available graphics tablets and tools to wayland clients #[derive(Default, Debug, Clone)] pub struct TabletSeatHandle { inner: Rc>, @@ -53,12 +53,12 @@ impl TabletSeatHandle { pub(super) fn add_instance(&self, seat: Main) { let mut inner = self.inner.borrow_mut(); - // Notify new instance about avaluble tablets + // Notify new instance about available tablets for (desc, tablet) in inner.tablets.iter_mut() { tablet.new_instance(seat.deref(), desc); } - // Notify new instance about avalible tools + // Notify new instance about available tools for (desc, tool) in inner.tools.iter_mut() { let inner = self.inner.clone(); tool.new_instance(seat.deref(), desc, move |desc, status| { @@ -89,7 +89,7 @@ impl TabletSeatHandle { /// Add a new tablet to a seat. /// - /// You can either add tablet on [LibinputEvent::NewDevice](crate::backend::libinput::LibinputEvent::NewDevice) event, + /// You can either add tablet on [input::Event::DeviceAdded](crate::backend::input::InputEvent::DeviceAdded) event, /// or you can add tablet based on tool event, then clients will not know about devices that are not being used /// /// Returns new [TabletHandle] if tablet was not know by this seat, if tablet was allready know it returns exsisting handle. @@ -124,7 +124,7 @@ impl TabletSeatHandle { /// Remove tablet device /// /// Called when tablet is no longer avalible - /// For example on [LibinputEvent::RemovedDevice](crate::backend::libinput::LibinputEvent::RemovedDevice) event. + /// For example on [input::Event::DeviceRemoved](crate::backend::input::InputEvent::DeviceRemoved) event. pub fn remove_tablet(&self, tablet_desc: &TabletDescriptor) { self.inner.borrow_mut().tablets.remove(tablet_desc); } diff --git a/src/wayland/tablet_manager/tablet_tool.rs b/src/wayland/tablet_manager/tablet_tool.rs index ffba6a3..19cb770 100644 --- a/src/wayland/tablet_manager/tablet_tool.rs +++ b/src/wayland/tablet_manager/tablet_tool.rs @@ -2,7 +2,7 @@ use std::ops::Deref as _; use std::sync::Mutex; use std::{cell::RefCell, rc::Rc}; -use crate::backend::input::{ButtonState, TabletToolDescriptor, TabletToolType}; +use crate::backend::input::{ButtonState, TabletToolCapabilitys, TabletToolDescriptor, TabletToolType}; use crate::wayland::seat::{CursorImageAttributes, CursorImageStatus}; use wayland_protocols::unstable::tablet::v2::server::{ zwp_tablet_seat_v2::ZwpTabletSeatV2, @@ -318,27 +318,27 @@ impl TabletToolHandle { let low: u32 = tool.hardware_id_wacom as u32; wl_tool.hardware_id_wacom(high, low); - if tool.capabilitys.pressure { + if tool.capabilitys.contains(TabletToolCapabilitys::PRESSURE) { wl_tool.capability(zwp_tablet_tool_v2::Capability::Pressure); } - if tool.capabilitys.distance { + if tool.capabilitys.contains(TabletToolCapabilitys::DISTANCE) { wl_tool.capability(zwp_tablet_tool_v2::Capability::Distance); } - if tool.capabilitys.tilt { + if tool.capabilitys.contains(TabletToolCapabilitys::TILT) { wl_tool.capability(zwp_tablet_tool_v2::Capability::Tilt); } - if tool.capabilitys.slider { + if tool.capabilitys.contains(TabletToolCapabilitys::SLIDER) { wl_tool.capability(zwp_tablet_tool_v2::Capability::Slider); } - if tool.capabilitys.rotation { + if tool.capabilitys.contains(TabletToolCapabilitys::ROTATION) { wl_tool.capability(zwp_tablet_tool_v2::Capability::Rotation); } - if tool.capabilitys.wheel { + if tool.capabilitys.contains(TabletToolCapabilitys::WHEEL) { wl_tool.capability(zwp_tablet_tool_v2::Capability::Wheel); }