Apply suggestions from code review & Rebase

This commit is contained in:
Poly 2021-07-05 23:57:25 +02:00
parent c557adc6a6
commit 07743faad2
10 changed files with 145 additions and 136 deletions

View File

@ -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<UdevData> {
InputEvent::TabletToolButton { event, .. } => self.on_tablet_button::<B>(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,12 +285,19 @@ impl AnvilState<UdevData> {
}
fn on_tablet_tool_axis<B: InputBackend>(&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;
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());
if let (Some(tablet), Some(tool)) = (tablet, tool) {
if evt.pressure_has_changed() {
@ -311,31 +320,39 @@ impl AnvilState<UdevData> {
}
tool.motion(
self.pointer_location,
*pointer_location,
under,
&tablet,
SCOUNTER.next_serial(),
evt.time(),
);
}
}
})
.unwrap();
}
fn on_tablet_tool_proximity<B: InputBackend>(&mut self, evt: B::TabletToolProximityEvent) {
if let Some(out) = self.backend_data.output_map.first() {
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();
self.seat.tablet_seat().add_tool(&tool);
tablet_seat.add_tool(&tool);
self.pointer_location = evt.position_transformed(out.size);
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 = 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);
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(
self.pointer_location,
*pointer_location,
under,
&tablet,
SCOUNTER.next_serial(),
@ -344,7 +361,8 @@ impl AnvilState<UdevData> {
ProximityState::Out => tool.proximity_out(evt.time()),
}
}
}
})
.unwrap();
}
fn on_tablet_tool_tip<B: InputBackend>(&mut self, evt: B::TabletToolTipEvent) {

View File

@ -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<u32>;
/// Get the vendor ID for this device.
fn id_vendor(&self) -> Option<u32>;
/// Returns device USB (product,vendor) id
fn usb_id(&self) -> Option<(u32, u32)>;
/// Returns the syspath of the device.
///

View File

@ -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,
}
bitflags! {
/// 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 {
pub struct TabletToolCapabilitys: u32 {
/// Tilt axes
pub tilt: bool,
const TILT = 1;
/// Pressure axis
pub pressure: bool,
const PRESSURE = 2;
/// Distance axis
pub distance: bool,
const DISTANCE = 4;
/// Z-rotation axis
pub rotation: bool,
const ROTATION = 16;
/// Slider axis
pub slider: bool,
const SLIDER = 32;
/// Wheel axis
pub wheel: bool,
const WHEEL = 64;
}
}
/// Tablet tool event
@ -110,7 +112,7 @@ pub trait TabletToolEvent<B: InputBackend> {
/// 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<B: InputBackend> {
/// 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<B: InputBackend> {
/// 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<B: InputBackend> TabletToolAxisEvent<B> 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<B: InputBackend>: TabletToolEvent<B> + Event<B>
/// 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.

View File

@ -97,12 +97,11 @@ impl backend::Device for libinput::Device {
libinput::Device::has_capability(self, capability.into())
}
fn id_product(&self) -> Option<u32> {
Some(libinput::Device::id_product(self))
}
fn id_vendor(&self) -> Option<u32> {
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<PathBuf> {

View File

@ -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<E> backend::Event<LibinputInputBackend> for E
where
E: IsTabetEvent,
E: IsTabletEvent,
{
fn time(&self) -> u32 {
tablet_tool::TabletToolEventTrait::time(self)
@ -51,7 +51,7 @@ impl backend::TabletToolTipEvent<LibinputInputBackend> for tablet_tool::TabletTo
impl<E> backend::TabletToolEvent<LibinputInputBackend> 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,

View File

@ -308,11 +308,7 @@ impl Device for WinitVirtualDevice {
)
}
fn id_product(&self) -> Option<u32> {
None
}
fn id_vendor(&self) -> Option<u32> {
fn usb_id(&self) -> Option<(u32, u32)> {
None
}

View File

@ -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,12 +74,10 @@ pub fn init_tablet_manager_global(display: &mut Display) -> Global<ZwpTabletMana
user_data.insert_if_missing(TabletSeatHandle::default);
let instance = tablet_seat;
let tablet_seat = user_data.get::<TabletSeatHandle>();
let tablet_seat = user_data.get::<TabletSeatHandle>().unwrap();
if let Some(tablet_seat) = tablet_seat {
tablet_seat.add_instance(instance);
}
}
zwp_tablet_manager_v2::Request::Destroy => {
// Nothing to do
}

View File

@ -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<u32>,
/// Tablet device USB vendor id
pub id_vendor: Option<u32>,
/// Tablet device USB (product,vendor) id
pub usb_id: Option<(u32, u32)>,
/// Path to the device
pub syspath: Option<PathBuf>,
}
impl<D: Device> From<D> for TabletDescriptor {
fn from(device: D) -> Self {
impl<D: Device> 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);
}

View File

@ -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<RefCell<TabletSeat>>,
@ -53,12 +53,12 @@ impl TabletSeatHandle {
pub(super) fn add_instance(&self, seat: Main<ZwpTabletSeatV2>) {
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);
}

View File

@ -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);
}