Skip to content

Conversation

@Reidond
Copy link

@Reidond Reidond commented Jul 12, 2025

This pull request introduces support for running the StickDeck client on Linux systems, enabling the emulation of the Steam Deck as a virtual game controller. The implementation utilizes the input-linux Rust crate to interface with the Linux uinput kernel module, providing functional parity with the existing Windows ViGEm-based emulation.

Reidond added 2 commits July 12, 2025 02:27
- Add native Linux client using uinput for virtual controller emulation
- Support all Xbox 360 controller features and mouse input on Linux
- Add setup, launch, and debug scripts for Linux
- Add GitHub Actions workflow for Linux builds
- Update README and CHANGELOG for Linux support
- Add CLAUDE.md and implementation plan for Linux client
- Update common types for cross-platform compatibility
- Change script permissions for debug, launch, and setup scripts to executable
- Simplify launch and setup commands by removing unnecessary directory changes
- Enhance logging in the client connection process for better debugging
@DiscreteTom DiscreteTom requested a review from Copilot July 13, 2025 02:29
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds native Linux support for the StickDeck client by leveraging the uinput kernel module to emulate a virtual gamepad and mouse, matching the existing Windows functionality.

  • Introduce a Rust-based Linux client (linux/src/lib.rs, input/ modules) using the input-linux crate.
  • Add setup, launch, and debug scripts for configuring /dev/uinput permissions and running the client.
  • Update shared common crate, documentation, CI workflow, and release assets to include the Linux client.

Reviewed Changes

Copilot reviewed 16 out of 20 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
linux/src/main.rs Entry point forwarding to stickdeck_linux::main()
linux/src/lib.rs Main loop: connects to server, initializes devices, handles packets
linux/src/input/mouse.rs Implements virtual mouse initialization and event writing via uinput
linux/src/input/gamepad.rs Implements virtual gamepad initialization and mapping for Xbox 360 layout
linux/src/input/mod.rs Exports init_gamepad and init_mouse
linux/src/client.rs Network client that receives and deserializes packets
linux/scripts/setup.sh Setup script for dependencies and /dev/uinput permissions
linux/scripts/launch.sh Launch script for running the Linux client
linux/scripts/debug.sh Debug script for building and running with logging
linux/PLAN.md Implementation plan and step-by-step outline
linux/Cargo.toml Added Linux client package definition and dependencies
common/src/lib.rs Added PORT, mouse and gamepad button constants/forms
README.md Updated usage instructions to include Linux workflow
CHANGELOG.md Documented new Linux client support for v0.3.2
.github/workflows/linux-build-and-upload-release-assets.yml CI workflow for building and uploading Linux releases
Comments suppressed due to low confidence (4)

linux/src/client.rs:72

  • [nitpick] The generic type parameter Gamepad shadows the domain concept and may be confusing; consider renaming it to a concise identifier like G to improve clarity.
impl<Gamepad: DeserializableGamepad<Target = Gamepad>> DeserializablePacket for Packet<Gamepad> {

linux/src/input/mouse.rs:10

  • The public function init_mouse lacks a doc comment. Consider adding documentation that describes its purpose, how the returned closure should be used, and possible error conditions.
pub fn init_mouse() -> Result<impl FnMut(&Mouse) -> Result<()>> {

linux/src/input/gamepad.rs:15

  • The public function init_gamepad would benefit from a doc comment explaining its behavior, expected input mapping, and error handling.
pub fn init_gamepad() -> Result<impl FnMut(&XGamepad) -> Result<()>> {

linux/src/input/gamepad.rs:15

  • The gamepad initialization and mapping logic is not covered by tests. Consider adding unit tests to verify correct event generation for various XGamepad inputs.
pub fn init_gamepad() -> Result<impl FnMut(&XGamepad) -> Result<()>> {

fi

# Check if user can access /dev/uinput
if [ ! -w "/dev/uinput" ]; then
Copy link

Copilot AI Jul 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The permission-check and prompt logic is duplicated in both launch.sh and debug.sh; consider extracting it into a shared helper or sourcing a common functions file to reduce duplication.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please modify this file according to other github action workflow files in this repo, modify the trigger to a workflow_dispatch with a version parameter, run tests before build, include the version in the archive file name, delete existing aset with the same name if exists.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove intermediate files in the final PR.

5. (Optional) If you want to test the controller, run `joy.cpl` (which is a built-in Windows joystick test tool).
4. Run the client on your PC:
- **Windows**: Run `launch.bat`. Once you see `Virtual controller is ready` in the console, StickDeck is ready.
- **Linux**: Run `./scripts/launch.sh <steam_deck_ip>`. Once you see `Ready! Waiting for inputs from Steam Deck...`, StickDeck is ready.
Copy link
Owner

@DiscreteTom DiscreteTom Jul 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use steamdeck as the default host name for the steam deck so users can omit the steam_deck_ip for most of the case.

> By default the client will try to connect `steamdeck:7777`. If you want to connect to a different server, you can edit `launch.bat`, replace the `steamdeck` with your server IP.
> You can find the server IP on the first line of the StickDeck UI window while the server is started.
> - **Windows**: By default the client will try to connect `steamdeck:7777`. If you want to connect to a different server, you can edit `launch.bat`, replace the `steamdeck` with your server IP.
> - **Linux**: You need to provide the Steam Deck IP address as an argument to the launch script.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

- You can checkout the actual update rate on the PC side by running `debug.bat`.
- You can checkout the actual update rate on the PC side by running:
- **Windows**: `debug.bat`
- **Linux**: `./scripts/debug.sh <steam_deck_ip>`
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove intermediate files in the final PR.

Copy link
Owner

@DiscreteTom DiscreteTom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution. Please update the PR according to comments.

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.

2 participants