Repository navigation
feat: Decouple drivers from InputPlumber intenal types and expand event filtering - #753
Merged
Merged
Conversation
pastaq
force-pushed
the
pastaq/device_native_output
branch
from
October 18, 2026 04:01
a89cd2a to
ae8024b
Compare
The design philosophy of the drivers was intended to be self contained so they could be made into crates. Over time this principle has been violated. Start the process of fixing this by decoupling drivers from the InputPlumber native OutputEvent class. Each driver now implements its own OutputEvent enum, and the source implementation does the event conversion. For DS5 and Deck, permit directly writing the state from the matching source if the source and target are the same. While at it, address a 0x8F event PadSide bug. The newer event swaps the enum meanings for Left/Right, verified in hid-steam. Also fix the 0x8F event missing from the Deck target. This patch is a prerequisite for the next patch in the series. A local LLM was used for searching kernel and SDL sources for correctness. Assisted-by: LLM
Improves the haptic click/tick and haptic pulses behavior on non deck devices. The duration of click/tick events are now set by using the to_click()/to_tick() impls and Haptic Pulse events will now properly emit a series of pulses based on the report data. Assisted-by: LLM
The kernel FF path for the Ally only drives the two main motor magnitudes in the 0x0D extended rumble report, leaving the trigger motor magnitudes unused. As ther is currently no ABI in the kernel for handling impulse trigger events, write the report directly over hidraw to drive all four motors, matching the kernel report layout and its force feedback off pattern. Add the Steam Deck TriggerVibrationExtended report to the uhid target. The 0xEC report id is a placeholder pending confirmation. Report layout and field semantics verified against the vendor HID specification, usbmon captures, and the kernel hid-asus-ally driver. Assisted-by: LLM
Introduces an EventCapability trait in the source layer providing to_capability() and from_capability() conversions between a device's own event type and the InputPlumber Capability type. This is a prerequisite for making the drivers standalone. Drivers will list their own event types in their filters and the source implementation will perform the translation. Assisted-by: LLM
pastaq
force-pushed
the
pastaq/device_native_output
branch
2 times, most recently
from
October 21, 2026 08:33
195b115 to
f3dea5b
Compare
The Legion Go drivers used the InputPlumber Capability type for event filtering, which prevented the drivers from being extracted into crates. The event filter now stores the driver's own Event type and matches on event kind via variant_eq(). The source implementations bridge to Capability through the EventCapability trait. Filtered events are now prevented at generation time by a filtered emit() helper in the translate loop instead of being discarded after the fact. This covers the controller and touchpad drivers. The shared EventCapability impl gains to_value with the per-variant value normalization, including the touchpad axis and right pad force normalization, and the sources' translate_event collapses to glue that calls to_capability and to_value. The touchpad source moves into the shared legion_go module as touchpad.rs since it shares the driver's event type and the module's EventCapability impl. Assisted-by: LLM
The IIO IMU driver used the InputPlumber Capability type for event filtering, which prevented the driver from being extracted into a crate. The event filter now stores the driver's own Event type and matches on event kind via variant_eq(). The source implementations bridge to Capability through the EventCapability trait. The filter check now runs before the sensor decode so a filtered channel does not spend cycles decoding and rotating values it will discard. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the DualSense driver so on-demand event filtering works for DS5 sources. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. CAPABILITIES moves to the end of the file. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. The per-axis calibration (bias and raw-to-physical-unit scale) now applies at the driver emit sites, so InertialInput carries calibrated f64 values and the source-side Calibration struct is gone. Assisted-by: LLM
Add event filtering to the Flydigi Vader 4 Pro driver so on-demand event filtering works for its source. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the FTS3528 touchpad driver so on-demand event filtering works for its source. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the GPD device drivers so on-demand event filtering works for the macro keyboard and touchpad sources. The drivers now keep a list of filtered events and prevent matching events from being emitted in their poll loops via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The sources move into a hidraw/gpd_device/ subdirectory. The shared EventCapability impl for the driver Event type, including to_value with the per-variant value normalization, lives in mod.rs, and each source's translate_event collapses to glue that calls to_capability and to_value. The shared to_value returns None for the touchpad axis and trigger variants because their normalization constants differ per model. The 2023 and 2024 touchpad sources special-case those variants in translate_event with their own constants. Assisted-by: LLM
Add event filtering to the Horipad Steam driver so on-demand event filtering works for its source. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the Legion Go S drivers so on-demand event filtering works for the IMU, touchpad, and XInput sources. Each of the three sub-drivers keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The shared Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The sources move into a hidraw/legion_go_s/ subdirectory. The shared EventCapability impl for the driver Event type, including to_value with the per-variant value normalization, lives in mod.rs, and each source's translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the MSI Claw driver so on-demand event filtering works for its source. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the Opineo touchpad driver so on-demand event filtering works for its source. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the OXP HID driver so on-demand event filtering works for its source. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the OXP TTY driver so on-demand event filtering works for the OneXFly serial and OXP X1 serial sources. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the GamepadButtonEvent gains pressed for value extraction. The sources move into a tty/oxp_serial/ subdirectory holding onexfly and x1. The shared EventCapability impl for the driver Event type, including to_value with the per-variant axis normalization, lives in mod.rs, and each source's translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the Steam Deck driver so on-demand event filtering works for its source. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The haptic state machine paths are untouched. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the Ultimate 2 Wireless driver so on-demand event filtering works for its source. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
Add event filtering to the XPad UHID driver so on-demand event filtering works for its source. The driver now keeps a list of filtered events and prevents matching events from being emitted in its poll loop via an emit helper. The Event enum gains variant_eq for payload-ignoring kind comparison, and the input payload structs derive Default so filter prototypes can be constructed. The source implements EventCapability for the driver Event type, bridging the on-demand filter between Capability and the driver's native event kind. The EventCapability impl gains to_value with the per-variant value normalization, and translate_event collapses to glue that calls to_capability and to_value. Assisted-by: LLM
All changes are formatting only: line wrapping and one trailing whitespace removal. Clippy required no code changes.
pastaq
force-pushed
the
pastaq/device_native_output
branch
from
October 21, 2026 21:44
f3dea5b to
0acbc13
Compare
Contributor
|
🎉 This PR is included in version 0.83.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Over time some InputPlumber internal types have made their way into device drivers. As the intent for these drivers has always been to crate them off, this needs correcting. Two InputPlumber internals were used directly on device drivers. OutputEvent and Capability.
OutputEvent was used directly from a target device and sent to a source device with no intermediary. Drivers implemented the conversion directly. To resolve this, give each driver a new OutputEvent type enum. In the SourceDriver impl do conversion from the InputPlumber type to the driver type.
While fixing OutputEvent some bugs were discovered in HapticPulseReport events. Fix those in flight.
Capability was used for managing event filtering. The dbus interface would take an event filter by Capability and pass it to the source impl that were called out, then the impl would pass that filter on to the driver. To resolve this, add a new EventCapability trait that contains to_capabiltiy, from_capability, and to_value functions. Each SourceDriver impl now adds an EventCapability mapping of each driver event to its eventual capability. Adding the inverse and to_value functions also allows us to simplify the translate step and reuse the trait. As part of the filter update I added a new emit() pattern to the device drivers that will check if a generated event is in the current filter before pushing it to the events list. This enables us to filter all events produced by a driver without adding additional nesting with an
if .. matchesfor every generation site.After addressing the drivers that were cross-contaminated, revisit other source drivers with the new patterns to keep everything synchronized
Specifically out of scope: evdev sources were not addressed. Capability maps applying at the composite device level and the source device level made the series significantly longer than intended and with the additional drivers adjusted already scope creep was already quite large.
A local LLM was used for validation and automating some of the changes after a pattern was established.