Repository navigation
fix(linux): send scroll to the mouse device that last moved - #195
ReenigneArcher merged 5 commits into
Conversation
Scroll should come out of the uinput device that moved last, the same way buttons already do. These tests fail until that's fixed, since scroll always goes to the relative device and the absolute device has no wheel axes.
In Moonlight's remote desktop mouse mode the pointer moves through the absolute uinput device, but scroll always went to the relative one, so scrolling didn't work while the mouse was moving. The absolute device now has the wheel axes too, still without REL_X and REL_Y so it stays an absolute pointer, and scroll goes to whichever device moved last, like buttons. inputtino fixed this the same way in games-on-whales/inputtino@65227c7.
Keeps the new line under the 120-character guideline.
Clears SonarCloud's cpp:S6177 finding on the new test.
ReenigneArcher
left a comment
There was a problem hiding this comment.
Reviewed b316f9f366ffae94f1d1d87e8f2df65afb34d7f0 against current master (1e41c36). I found no functional defect in the scroll-routing change; one required backend Doxygen update remains, detailed inline.
Validation: the GoogleTest target built with GCC 15.3.1 in a Fedora 43 container, and cmake-build-review/tests/test_libvirtualhid --gtest_filter='LinuxBackendTest.*' passed all 37 tests, including the new routing test and updated capability assertions. git diff --check 1e41c36...HEAD passed. Real-device libinput validation could not run locally because /dev/uinput and /dev/uhid were unavailable.
Merge/check status: GitHub reports no merge conflicts. SonarCloud and the primary documentation build passed. Actions await maintainer approval; the GH-Pages documentation log timed out waiting for check runs. That workflow limitation is separate from the documentation finding.
Review completed by Codex | Model: gpt-6.1-sol | Thinking: xhigh
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #195 +/- ##
==========================================
- Coverage 73.77% 73.73% -0.04%
==========================================
Files 43 43
Lines 10702 10704 +2
Branches 3695 3696 +1
==========================================
- Hits 7895 7893 -2
- Misses 2196 2198 +2
- Partials 611 613 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report in Codecov by Harness.
|



Description
In Moonlight's "Optimize mouse for remote desktop" mode, scrolling on a Linux host works while the pointer is still, but breaks once it's moving.
The mouse is two uinput devices. Absolute motion goes to the absolute one, but scroll always went to the relative one, and the absolute device had no wheel axes. Buttons already follow whichever device moved last, so this does the same for scroll:
The absolute device still has no
REL_XorREL_Y, so libinput keeps treating it as an absolute pointer.inputtino fixed the same bug this way in games-on-whales/inputtino#38, which Sunshine picked up in LizardByte/Sunshine#5135. It came back when Sunshine moved to libvirtualhid in LizardByte/Sunshine#5368, which I noticed after my last Sunshine update.
Screenshot
Moonlight in remote desktop mode, spinning the wheel non-stop while moving the pointer. The wheel counter stalls on the stock Copr build and keeps counting with the fix:
scroll-fix-before-after.mp4
Issues Fixed or Closed
Roadmap Issues
Testing
New and updated tests:
LinuxBackendTest.PipeBackedUinputMouseScrollsOnLastMotionDevicesends absolute motion, both scroll directions, relative motion and another scroll, then checks which device each wheel event came out of.REL_XorREL_Y.LinuxConsumerTest.LibinputSeesSplitUinputMouseMotionAndButtonsnow scrolls after the absolute moves and expects libinput to reportLIBINPUT_EVENT_POINTER_SCROLL_WHEEL(v120 of -120) from the absolute device.I ran the full suite with no filter in a Fedora 43 VM (kernel 6.17.1-300.fc43, real
/dev/uinputand/dev/uhid), on top of1e41c36:SdlSeesXboxOneCanonicalButtonsandSdlSeesXboxSeriesCanonicalButtons(SDL sees 11 buttons instead of 15), and they fail the same way on unmodified master in that VM, so I don't think they're related.The tests that don't need device nodes also pass when built with gcc 14 in a
fedora:43container, andgit clang-formatreports no changes.Manual: I built the Sunshine Copr RPM for 2026.914.233613 with this fix applied to its pinned libvirtualhid (
53e1a94, same fix lines) and installed it on Fedora 44. Scrolling while moving the mouse in Moonlight's remote desktop mode works now.FreeBSD:
uhid_backend.cppbuilds there too, so I also tested in a FreeBSD 15.1 VM (base clang 19.1.7,uinputloaded). The FreeBSD suite passes on both master and this branch (111 passed, 2 Linux-only tests skipped). I also ran a small throwaway probe (not part of this PR) that creates a mouse, moves it absolutely, scrolls, and reads the absolute/dev/input/event*node with libevdev. On master that node has no wheel axes and gets no scroll events. With this change it getsREL_WHEEL 1andREL_WHEEL_HI_RES 120. I didn't test libinput or a desktop on FreeBSD.Type of Change
Checklist
Let me know if theres any comment needed in here, its a small fix so I thought it unnecessary
AI Usage
See our AI usage policy.
Coded with the help of Opus 5.5