Skip to content

feat(input): implement multi-seat support and virtual device naming#4954

Open
willybarret wants to merge 2 commits intoLizardByte:masterfrom
willybarret:feature/multiseat-support
Open

feat(input): implement multi-seat support and virtual device naming#4954
willybarret wants to merge 2 commits intoLizardByte:masterfrom
willybarret:feature/multiseat-support

Conversation

@willybarret
Copy link
Copy Markdown

Description

This change introduces multiseat input support and virtual device naming on Linux, allowing multiple users to interact with Sunshine independently on the same system. The intention is to provide flexibility for shared workstations, gaming setups, and other advanced multi-user environments.

Modern systems (based on systemd and logind) have the concept of a seat (seat0 is default), with associated input devices and graphics outputs. For example, look at loginctl seat-status seat0.
When Sunshine fires up uinput, it’s logically similar to plugging in a second USB mouse: the input gets attached to the default seat (seat0).
While I don't know exactly what the solution should look like, (it) should ideally run as a separate "seat" (as far as logind and libinput are concerned).

from #137 (comment)

Screenshot

Issues Fixed or Closed

Roadmap Issues

Type of Change

  • feat: New feature (non-breaking change which adds functionality)
  • fix: Bug fix (non-breaking change which fixes an issue)
  • docs: Documentation only changes
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semicolons, etc.)
  • refactor: Code change that neither fixes a bug nor adds a feature
  • perf: Code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • build: Changes that affect the build system or external dependencies
  • ci: Changes to CI configuration files and scripts
  • chore: Other changes that don't modify src or test files
  • revert: Reverts a previous commit
  • BREAKING CHANGE: Introduces a breaking change (can be combined with any type above)

Checklist

  • Code follows the style guidelines of this project
  • Code has been self-reviewed
  • Code has been commented, particularly in hard-to-understand areas
  • Code docstring/documentation-blocks for new or existing methods/components have been added or updated
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@willybarret willybarret force-pushed the feature/multiseat-support branch from ae6a187 to 2bdec59 Compare April 6, 2026 21:47
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 6, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
1 New issue
1 New Code Smells (required ≤ 0)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@atassis
Copy link
Copy Markdown
Contributor

atassis commented Apr 7, 2026

Hi there. Nice work. I'm working on a similar problem but for containerized/headless deployments where systemd/logind aren't available.
My approach uses the device_phys field on uinput devices to tag them with a per-instance identifier, then filters by that field on the input consumer side. The key insight is that libevdev_set_phys() doesn't actually propagate to the kernel — you need to call ioctl(fd, UI_SET_PHYS, ...) on the uinput fd before UI_DEV_CREATE.
I think this could complement your seat naming nicely — your name suffix is great for human-readable identification (xinput list), while device_phys gives a machine-readable field that compositors and input libraries can filter on. For your use case, something like .device_phys = "sunshine/" + seat_id would let libinput-based compositors route devices to the correct seat automatically, without requiring manual udev rules.
I plan to submit a patch to inputtino that adds UI_SET_PHYS support (since the existing device_phys field in DeviceDefinition is silently ignored by the uinput backend). Would be happy to coordinate if you're interested — both approaches could land together.

@willybarret
Copy link
Copy Markdown
Author

you would still need to use the ID_SEAT udev property to make it work with logind tho
if you can handle that case you can comment the pr of that implementation and I close this one
using the phys attribute sounds cleaner, I'd like to test it

@atassis
Copy link
Copy Markdown
Contributor

atassis commented Apr 8, 2026

Good point. ID_SEAT and device_phys solve different layers of the same problem. phys gives a machine-readable tag that compositors/libinput can filter on without any udev rules or logind dependency, which is essential for containerized/headless setups. ID_SEAT is the right mechanism for bare-metal logind multi-seat.
I think both approaches are complementary, not competing. inputtino could support both: UI_SET_PHYS for the phys field (currently silently ignored), and your seat naming for logind-aware setups. They can land independently.
I'll submit the inputtino patch for UI_SET_PHYS support soon and link it here. Happy to coordinate so the two features work well together.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants