fix(linux): Add optional wlroots (wlr-virtual-pointer) backend for mouse input#4972
Open
Cm4nXD wants to merge 3 commits intoLizardByte:masterfrom
Open
fix(linux): Add optional wlroots (wlr-virtual-pointer) backend for mouse input#4972Cm4nXD wants to merge 3 commits intoLizardByte:masterfrom
Cm4nXD wants to merge 3 commits intoLizardByte:masterfrom
Conversation
Adds a configurable alternative to uinput for mouse input on Wayland. When enabled, mouse movement, buttons, and scroll are injected via the zwlr_virtual_pointer_v1 Wayland protocol instead of /dev/uinput. - Generate wlr-virtual-pointer-unstable-v1 bindings via wayland-scanner - New wl_mouse.h / wl_mouse.cpp implement the Wayland virtual pointer - input_raw_t initialises and owns the wl_mouse state when enabled - Each platf::mouse:: function routes through wl_mouse when active - config::input.wlr_virtual_mouse (default: false) controls the toggle - Linux-only checkbox added to the web UI Inputs tab - Locale strings added to all 22 locale files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use create_virtual_pointer_with_output() so that motion_absolute coordinates are interpreted in the captured output's local coordinate frame rather than the full global compositor space. Previously, without an output binding, absolute mouse events were mapped across all monitors in the compositor layout, causing inputs to split across the real and headless virtual displays in a nested sway session. The output is selected using the same index as config::video.capture so the input and capture sides always refer to the same physical output. Falls back to the unbound creation path if no wl_output globals are discovered. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
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.




Description
This PR introduces an optional wlroots-based input backend for mouse events, allowing Sunshine to forward pointer input using the wlr-virtual-pointer protocol instead of the existing uinput path.
This is implemented as a runtime toggle, preserving full backward compatibility with the current behavior.
The primary motivation for this change is to support nested Wayland compositors, specifically:
Running a nested Sway session inside Gamescope (SteamOS GameMode)
Using a headless/virtual output to render secondary content (e.g., Wii U gamepad view from Cemu)
Streaming that headless output via Sunshine to a Moonlight client
In this configuration, the existing uinput backend causes incorrect behavior:
Input events are injected at the system level
The host compositor (Gamescope) receives the events
Gamescope is unaware of the nested compositor's virtual outputs
As a result, mouse input is mapped to the wrong display
By contrast, using wlr-virtual-pointer:
Injects input directly into the target Wayland compositor (Sway)
Allows proper interaction with headless / virtual outputs
Ensures mouse input maps correctly to the streamed surface
Currently this doesn't map keyboard inputs, but it does map to just the selected display using create_virtual_pointer_with_output, but I'd be willing to try.
I've worked very hard, and am perfectly willing to make any adjustments needed to implement this feature! I've never contributed to an open source project or tried to tackle anything even remotely this complicated before as far as coding. 😅
I did use AI to help me, if I hadn't I'm not sure I could even have attempted this. But I did test it on my system, and filmed a demo showing it in action.
Screenshot
Issues Fixed or Closed
I'm not sure....
Roadmap Issues
I'm not sure
Type of Change
Checklist
AI Usage
output.mp4