You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
right analogue stick no longer scrolls view of open plugin #119
This regressed on InputPlumber-managed devices (e.g. OneXPlayer Apex, Deck when an IP composite drives nav) when IP intercept mode landed (#94). Before that, the evdev path forwarded ABS_RY straight through; now nothing feeds the scroll engine on these devices.
Why the right stick never reaches the overlay while it's open
When the overlay opens, ip-intercept sets InterceptMode=GamepadOnly and nav arrives over D-Bus as InputPlumber's ui_* capability set. Dumped from /usr/share/inputplumber (IP 0.77.7):
There is no analog / scroll capability in that set — so the right stick is intercepted and then dropped. This is exactly what the existing comment at ip-intercept.ts:216 notes ("IP doesn't currently surface analog over the ui_* set"); the onAxis hook is wired but never called.
The evdev path can't cover for it either:
fuser /dev/input/event15 shows InputPlumber holds the raw stick-bearing pad open and grabbed, so the overlay reads nothing from the physical source.
The deck-uhid target is starved during intercept.
So while the overlay is open: raw source → grabbed by IP; D-Bus → no analog capability; emulated target → starved. The stick has nowhere to go.
The rest of the pipeline is intact and correct — axis naming (RightStickY), the webview momentum scroll engine (main.tsxstartRightStickScroll), and the data-scroll-root target resolution all work; they're just never fed on IP devices. (On a Deck-alone setup with no IP composite, readVirtualPadsForNav=true and the evdev path still forwards the stick, so it works there.)
Options for the fix
Upstream InputPlumber — add an analog/scroll capability to the D-Bus intercept set. Cleanest; the onAxis hook will consume it as-is once IP emits it. (Owner: pastaq.)
Read the stick from hidraw directly in the overlay (same approach already used for the Deck native wake button). hidraw allows parallel readers, so it works alongside IP. Cost: per-device HID-report parsing + on-device testing.
Interim: document right-stick scroll as pending IP support; focus-nav still scrolls focused elements into view.
Revisiting later — likely coordinating option 1 with the InputPlumber side, with option 2 as the Loadout-side fallback.
Activity
srsholmes commentedon Jun 24, 2026
Root-cause investigation
This regressed on InputPlumber-managed devices (e.g. OneXPlayer Apex, Deck when an IP composite drives nav) when IP intercept mode landed (#94). Before that, the evdev path forwarded
ABS_RYstraight through; now nothing feeds the scroll engine on these devices.Why the right stick never reaches the overlay while it's open
When the overlay opens,
ip-interceptsetsInterceptMode=GamepadOnlyand nav arrives over D-Bus as InputPlumber'sui_*capability set. Dumped from/usr/share/inputplumber(IP 0.77.7):There is no analog / scroll capability in that set — so the right stick is intercepted and then dropped. This is exactly what the existing comment at
ip-intercept.ts:216notes ("IP doesn't currently surface analog over the ui_* set"); theonAxishook is wired but never called.The evdev path can't cover for it either:
fuser /dev/input/event15shows InputPlumber holds the raw stick-bearing pad open and grabbed, so the overlay reads nothing from the physical source.deck-uhidtarget is starved during intercept.So while the overlay is open: raw source → grabbed by IP; D-Bus → no analog capability; emulated target → starved. The stick has nowhere to go.
The rest of the pipeline is intact and correct — axis naming (
RightStickY), the webview momentum scroll engine (main.tsxstartRightStickScroll), and thedata-scroll-roottarget resolution all work; they're just never fed on IP devices. (On a Deck-alone setup with no IP composite,readVirtualPadsForNav=trueand the evdev path still forwards the stick, so it works there.)Options for the fix
onAxishook will consume it as-is once IP emits it. (Owner: pastaq.)Revisiting later — likely coordinating option 1 with the InputPlumber side, with option 2 as the Loadout-side fallback.