- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1
Add Linux Support for Client-Side Controller Emulation Using uinput #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- 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
There was a problem hiding this 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 theinput-linuxcrate.
- Add setup, launch, and debug scripts for configuring /dev/uinputpermissions and running the client.
- Update shared commoncrate, 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_gamepadandinit_mouse | 
| linux/src/client.rs | Network client that receives and deserializes packets | 
| linux/scripts/setup.sh | Setup script for dependencies and /dev/uinputpermissions | 
| 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 Gamepadshadows the domain concept and may be confusing; consider renaming it to a concise identifier likeGto improve clarity.
impl<Gamepad: DeserializableGamepad<Target = Gamepad>> DeserializablePacket for Packet<Gamepad> {
linux/src/input/mouse.rs:10
- The public function init_mouselacks 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_gamepadwould 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 XGamepadinputs.
pub fn init_gamepad() -> Result<impl FnMut(&XGamepad) -> Result<()>> {
| fi | ||
|  | ||
| # Check if user can access /dev/uinput | ||
| if [ ! -w "/dev/uinput" ]; then | 
    
      
    
      Copilot
AI
    
    
    
      Jul 13, 2025 
    
  
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. | 
There was a problem hiding this comment.
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. | 
There was a problem hiding this comment.
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>` | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
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.