Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions rootfs/usr/share/inputplumber/profiles/mouse_keyboard_wasd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,24 @@ mapping:
button: RightBumper
target_events:
- mouse:
button: WheelUp
wheel:
name: Vertical
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What value is the name attribute providing? I.e. I can't have a horizontal up or vertical left? Plane is essentially assumed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean? Are you saying there would be issues with trying to use both at the same time? The normal scroll up and down function and pushing left or right feel very different (at least on my mice). I think it would be clunky to try and and go horizontal up or vertical left.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name is redundant. Up and down will always be vertical, so it's not adding value. I agree that vertical left would be weird/clunky and doesn't make sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I understand now. The target_events.mouse.wheel.name and target_events.mouse.wheel.direct attributes are somewhat redundant. So maybe I can consolidate into something like this.

Before:

      - mouse:
          wheel:
            name: Vertical
            direction: up

After:

      - mouse:
          wheel: Up

to align with similar existing target events. For example:

      - mouse:
          button: Right

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pastaq The name is the name of the capability, and the direction is used for mapping a particular direction of the wheel if the user doesn't want to map the whole axis. Relying only on the direction kind of breaks convention with how we define mapping every other type of event.

E.g. axes are mapped with this convention:

- gamepad:
    axis:
      name: LeftStick
      direction: left

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pastaq The name is the name of the capability, and the direction is used for mapping a particular direction of the wheel if the user doesn't want to map the whole axis. Relying only on the direction kind of breaks convention with how we define mapping every other type of event.

E.g. axes are mapped with this convention:

- gamepad:
    axis:
      name: LeftStick
      direction: left

This isn't an analogous situation. Vertical and horizontal aren't Capabilities, they are directions. Mouse:Wheel is a Capability that can do up down left right, just like Gamepad:LeftStick. If your analogy was accurate it would be Gamepad:LeftStick: Vertical:Up, which would be equally silly. There's also not a conflict with the button click as that should be handled by Mouse:Button:Middle

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you would rather see Mouse:Wheel changed into a Vector2 value? That will require some minor refactoring.

direction: up
#- mouse:
# wheel:
# name: Horizontal
# direction: right

- name: LB
source_event:
gamepad:
button: LeftBumper
target_events:
- mouse:
button: WheelDown
wheel:
name: Vertical
direction: down
#- mouse:
# wheel:
# name: Horizontal
# direction: left
8 changes: 8 additions & 0 deletions src/config/capability_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ pub struct DialCapability {
pub struct MouseCapability {
pub button: Option<String>,
pub motion: Option<MouseMotionCapability>,
pub wheel: Option<MouseWheelCapability>,
}

#[derive(Debug, Deserialize, Serialize, Clone, JsonSchema, PartialEq)]
Expand All @@ -245,6 +246,13 @@ pub struct MouseMotionCapability {
pub speed_pps: Option<u64>,
}

#[derive(Debug, Deserialize, Serialize, Clone, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub struct MouseWheelCapability {
pub name: String,
pub direction: Option<String>,
}

#[derive(Debug, Deserialize, Serialize, Clone, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub struct TouchpadCapability {
Expand Down
2 changes: 2 additions & 0 deletions src/dbus/interface/composite_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ impl CompositeDeviceInterface {
Capability::Mouse(mouse) => match mouse {
Mouse::Motion => "Mouse:Motion".to_string(),
Mouse::Button(button) => format!("Mouse:Button:{}", button),
Mouse::Wheel(wheel) => format!("Mouse:Wheel:{}", wheel),
},
Capability::Keyboard(key) => format!("Keyboard:{}", key),
_ => cap.to_string(),
Expand Down Expand Up @@ -416,6 +417,7 @@ impl CompositeDeviceInterface {
Capability::Mouse(mouse) => match mouse {
Mouse::Motion => "Mouse:Motion".to_string(),
Mouse::Button(button) => format!("Mouse:Button:{}", button),
Mouse::Wheel(wheel) => format!("Mouse:Wheel:{}", wheel),
},
Capability::Keyboard(key) => format!("Keyboard:{}", key),
_ => cap.to_string(),
Expand Down
41 changes: 41 additions & 0 deletions src/input/capability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ impl From<CapabilityConfig> for Capability {
let button = button.unwrap();
return Capability::Mouse(Mouse::Button(button));
}

// Wheel
if let Some(wheel) = mouse.wheel.as_ref() {
let Ok(wheel) = MouseWheel::from_str(&wheel.name) else {
log::error!("Invalid or unimplemented wheel: {}", wheel.name);
return Capability::NotImplemented;
};
return Capability::Mouse(Mouse::Wheel(wheel));
}
}

// DBus
Expand Down Expand Up @@ -331,13 +340,16 @@ pub enum Mouse {
Motion,
/// Mouse Buttons are typically binary mouse input that represents button presses
Button(MouseButton),
/// Mouse wheel input is relative
Wheel(MouseWheel),
}

impl fmt::Display for Mouse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Mouse::Motion => write!(f, "Motion"),
Mouse::Button(_) => write!(f, "Button"),
Mouse::Wheel(_) => write!(f, "Wheel"),
}
}
}
Expand Down Expand Up @@ -417,6 +429,35 @@ impl FromStr for MouseButton {
}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum MouseWheel {
// Mouse wheel up or down
Vertical,
// Mouse wheel left or right
Horizontal,
}

impl fmt::Display for MouseWheel {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
MouseWheel::Vertical => write!(f, "Vertical"),
MouseWheel::Horizontal => write!(f, "Horizontal"),
}
}
}

impl FromStr for MouseWheel {
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Vertical" => Ok(MouseWheel::Vertical),
"Horizontal" => Ok(MouseWheel::Horizontal),
_ => Err(()),
}
}
}

/// Gamepad Buttons typically use binary input that represents button presses
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum GamepadButton {
Expand Down
1 change: 1 addition & 0 deletions src/input/composite_device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,7 @@ impl CompositeDevice {
continue;
}
}
Mouse::Wheel(_) => {}
},
Capability::Touchscreen(_) => (),
}
Expand Down
14 changes: 13 additions & 1 deletion src/input/event/evdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use evdev::{AbsInfo, AbsoluteAxisCode, EventType, InputEvent, KeyCode, RelativeA

use crate::input::capability::{
Capability, Gamepad, GamepadAxis, GamepadButton, GamepadDial, GamepadTrigger, Keyboard, Mouse,
MouseButton, Touch, TouchButton, Touchpad,
MouseButton, MouseWheel, Touch, TouchButton, Touchpad,
};

use super::{native::NativeEvent, value::InputValue};
Expand Down Expand Up @@ -465,6 +465,12 @@ impl EvdevEvent {
EventType::RELATIVE => match RelativeAxisCode(code) {
RelativeAxisCode::REL_X => Capability::Mouse(Mouse::Motion),
RelativeAxisCode::REL_Y => Capability::Mouse(Mouse::Motion),
RelativeAxisCode::REL_WHEEL => {
Capability::Mouse(Mouse::Wheel(MouseWheel::Vertical))
}
RelativeAxisCode::REL_HWHEEL => {
Capability::Mouse(Mouse::Wheel(MouseWheel::Horizontal))
}
_ => Capability::NotImplemented,
},
EventType::MISC => Capability::NotImplemented,
Expand Down Expand Up @@ -561,6 +567,7 @@ fn event_type_from_capability(capability: Capability) -> Option<EventType> {
Capability::Mouse(mouse) => match mouse {
Mouse::Motion => Some(EventType::RELATIVE),
Mouse::Button(_) => Some(EventType::KEY),
Mouse::Wheel(_) => Some(EventType::RELATIVE),
},
Capability::Gamepad(gamepad) => match gamepad {
Gamepad::Button(button) => match button {
Expand Down Expand Up @@ -701,6 +708,11 @@ fn event_codes_from_capability(capability: Capability) -> Vec<u16> {
MouseButton::Extra => vec![KeyCode::BTN_EXTRA.0],
MouseButton::Side => vec![KeyCode::BTN_SIDE.0],
},

Mouse::Wheel(wheel) => match wheel {
MouseWheel::Vertical => vec![RelativeAxisCode::REL_WHEEL.0],
MouseWheel::Horizontal => vec![RelativeAxisCode::REL_HWHEEL.0],
},
},
Capability::Keyboard(key) => match key {
Keyboard::Key0 => vec![KeyCode::KEY_0.0],
Expand Down
44 changes: 42 additions & 2 deletions src/input/event/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
use super::dbus::Action;

/// Possible errors while doing input value translation
#[derive(Debug)]
pub enum TranslationError {
/// Translation not yet implemented
NotImplemented,
Expand Down Expand Up @@ -138,6 +139,8 @@ impl InputValue {
Mouse::Motion => Err(TranslationError::NotImplemented),
// Gamepad Button -> Mouse Button
Mouse::Button(_) => Ok(self.clone()),
// Gamepad Button -> Mouse Wheel
Mouse::Wheel(_) => self.translate_button_to_wheel(target_config),
},
// Gamepad Button -> Keyboard
Capability::Keyboard(_) => Ok(self.clone()),
Expand Down Expand Up @@ -183,11 +186,10 @@ impl InputValue {
},
// Axis -> Mouse
Capability::Mouse(mouse) => match mouse {
// Axis -> Mouse Motion
Mouse::Motion => self
.translate_axis_to_mouse_motion(source_config, target_config),
// Axis -> Mouse Button
Mouse::Button(_) => self.translate_axis_to_button(source_config),
Mouse::Wheel(_) => Err(TranslationError::NotImplemented),
},
// Axis -> Keyboard
Capability::Keyboard(_) => self.translate_axis_to_button(source_config),
Expand Down Expand Up @@ -233,6 +235,7 @@ impl InputValue {
Mouse::Motion => Err(TranslationError::NotImplemented),
// Trigger -> Mouse Button
Mouse::Button(_) => self.translate_trigger_to_button(source_config),
Mouse::Wheel(_) => Err(TranslationError::NotImplemented),
},
// Trigger -> Keyboard
Capability::Keyboard(_) => self.translate_trigger_to_button(source_config),
Expand Down Expand Up @@ -266,6 +269,7 @@ impl InputValue {
Capability::Mouse(mouse) => match mouse {
Mouse::Motion => Err(TranslationError::NotImplemented),
Mouse::Button(_) => self.translate_dial_to_button(source_config),
Mouse::Wheel(_) => Err(TranslationError::NotImplemented),
},
Capability::Keyboard(_) => self.translate_dial_to_button(source_config),
Capability::Touchpad(touch) => match touch {
Expand Down Expand Up @@ -307,6 +311,7 @@ impl InputValue {
Capability::Mouse(mouse) => match mouse {
Mouse::Motion => Err(TranslationError::NotImplemented),
Mouse::Button(_) => Ok(self.clone()),
Mouse::Wheel(_) => self.translate_button_to_wheel(target_config),
},
// Keyboard Key -> Keyboard
Capability::Keyboard(_) => Ok(self.clone()),
Expand Down Expand Up @@ -340,6 +345,7 @@ impl InputValue {
// Touchscreen Motion -> Mouse Motion
Mouse::Motion => Err(TranslationError::NotImplemented),
Mouse::Button(_) => Err(TranslationError::NotImplemented),
Mouse::Wheel(_) => Err(TranslationError::NotImplemented),
},
Capability::Keyboard(_) => Err(TranslationError::NotImplemented),
// Touchpad Motion -> Touchpad
Expand Down Expand Up @@ -395,6 +401,7 @@ impl InputValue {
// Touchscreen Motion -> Mouse Motion
Mouse::Motion => Err(TranslationError::NotImplemented),
Mouse::Button(_) => Err(TranslationError::NotImplemented),
Mouse::Wheel(_) => Err(TranslationError::NotImplemented),
},
Capability::Keyboard(_) => Err(TranslationError::NotImplemented),
// Touchpad Motion -> Touchpad
Expand Down Expand Up @@ -450,6 +457,7 @@ impl InputValue {
// Touchscreen Motion -> Mouse Motion
Mouse::Motion => Err(TranslationError::NotImplemented),
Mouse::Button(_) => Err(TranslationError::NotImplemented),
Mouse::Wheel(_) => Err(TranslationError::NotImplemented),
},
Capability::Keyboard(_) => Err(TranslationError::NotImplemented),
// Touchpad Motion -> Touchpad
Expand Down Expand Up @@ -509,6 +517,7 @@ impl InputValue {
Mouse::Motion => Err(TranslationError::NotImplemented),
// Touchscreen Motion -> Mouse Button
Mouse::Button(_) => Err(TranslationError::NotImplemented),
Mouse::Wheel(_) => Err(TranslationError::NotImplemented),
},
// Touchscreen Motion -> Keyboard
Capability::Keyboard(_) => Err(TranslationError::NotImplemented),
Expand Down Expand Up @@ -678,6 +687,37 @@ impl InputValue {
}
}

/// Translate the button value into an axis value based on the given config
fn translate_button_to_wheel(
&self,
target_config: &CapabilityConfig,
) -> Result<InputValue, TranslationError> {
let Some(mouse_config) = target_config.mouse.as_ref() else {
return Err(TranslationError::InvalidTargetConfig(
"No mouse config to translate button to mouse wheel".to_string(),
));
};
let Some(wheel) = mouse_config.wheel.as_ref() else {
return Err(TranslationError::InvalidTargetConfig(
"No mouse config found".to_string(),
));
};
let Some(direction) = wheel.direction.as_ref() else {
return Err(TranslationError::InvalidTargetConfig(
"No wheel direction found to translate button to mouse wheel".to_string(),
));
};
match direction.as_str() {
"up" => Ok(InputValue::Float(1.0)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cases with the same return value can be combined.

"up" | "right => Ok(InputValue::Float(1.0)),
 "down" | "left" => Ok(InputValue::Float(-1.0)),      

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I didn't know about that Rust functionality. Thanks! I'll update the code.

"down" => Ok(InputValue::Float(-1.0)),
"left" => Ok(InputValue::Float(-1.0)),
"right" => Ok(InputValue::Float(1.0)),
_ => Err(TranslationError::InvalidTargetConfig(
"Invalid mouse wheel config. Must be of value: up or down (Vertical) or left or right (Horizontal)".to_string(),
)),
}
}

/// Translate the button value into an axis value based on the given config
fn translate_button_to_axis(
&self,
Expand Down
4 changes: 3 additions & 1 deletion src/input/target/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use evdev::{
use crate::{
dbus::interface::{target::mouse::TargetMouseInterface, DBusInterfaceManager},
input::{
capability::{Capability, Mouse, MouseButton},
capability::{Capability, Mouse, MouseButton, MouseWheel},
composite_device::client::CompositeDeviceClient,
event::{evdev::EvdevEvent, native::NativeEvent, value::InputValue},
output_event::OutputEvent,
Expand Down Expand Up @@ -179,6 +179,8 @@ impl TargetInputDevice for MouseDevice {
Capability::Mouse(Mouse::Button(MouseButton::Extra)),
Capability::Mouse(Mouse::Button(MouseButton::WheelUp)),
Capability::Mouse(Mouse::Button(MouseButton::WheelDown)),
Capability::Mouse(Mouse::Wheel(MouseWheel::Vertical)),
Capability::Mouse(Mouse::Wheel(MouseWheel::Horizontal)),
Capability::Mouse(Mouse::Motion),
])
}
Expand Down