See CHANGELOG.txt for what's new in each release.
Transform your DualShock 3, DualShock 4, or DualSense controller into a keyboard. Test inputs, bind buttons to keys, and hide the controller from the system so games think you are using a keyboard.
- Controller testing - real-time visualization of sticks and buttons
- Keyboard emulation - play games that do not support gamepads
- Controller hiding - remove the device from the system (games detect a keyboard instead)
- Deadzone adjustment - precise stick calibration
- Web interface - monitor controller state from a browser
- Native GUI on both Windows and Linux
- Visual gamepad-layout editor (Windows) - import an input-overlay .png/.json preset and bind keys by clicking the picture of your controller
- Windows 10/11 (64-bit)
- .NET 8.0 SDK (https://dotnet.microsoft.com/download/dotnet/8.0) - only needed to build; see
scripts/windows-release.batfor a self-contained build that end users can run without installing anything - DualShock 3, DualShock 4, or DualSense controller (USB or Bluetooth)
Run scripts/windows-build.bat to compile the project, then run.bat to launch. To produce an end-user-ready release build, run scripts/windows-release.bat instead (see its output for details). Both scripts can be run from anywhere - they locate the project root automatically.
After launching:
- The desktop GUI opens automatically
- Web interface available at: http://localhost:8080
- A recent kernel with
hid-sony/hid-playstationsupport (present on effectively all modern distros) - Python 3
python3-tk,python-uinput(installed byinstall.sh)
cd src/linux
./install.sh # installs dependencies, sets up uinput permissions
./run.sh # or: python3 main.py
Alternatively, scripts/linux-build.sh checks your environment and stages a ready-to-run copy in build/linux/, and scripts/linux-release.sh packages a versioned source tarball in publish/ for distribution. Both can be run from anywhere - they locate the project root automatically.
After launching:
- The desktop GUI (Tkinter) opens automatically
- Web interface available at: http://localhost:8080
- Settings, bindings, and indicator colors are saved automatically to
~/.dualkey_config.json - Hiding the controller (unloading the
hid_sony/hid_playstationkernel module) requires running as root, e.g.sudo python3 main.py
- Connect your DualShock 3
- Launch DualKey
- Move the sticks to see visualization
- Press buttons to see their state
- Enable the "Keyboard Emulation" checkbox
- Default bindings:
- Left stick: WASD
- Right stick: Arrow keys
- Buttons: Space, E, Q, R
- Launch any game and play with your controller
- Run the application as Administrator
- Click "Hide Controller"
- The system will no longer detect the controller
- Games will treat your inputs as keyboard presses
| Action | Key |
|---|---|
| Left Stick Up | W |
| Left Stick Down | S |
| Left Stick Left | A |
| Left Stick Right | D |
| Right Stick Up | Up Arrow |
| Right Stick Down | Down Arrow |
| Right Stick Left | Left Arrow |
| Right Stick Right | Right Arrow |
| Cross | Space |
| Circle | E |
| Triangle | Q |
| Square | R |
| L1 | Shift |
| R1 | Ctrl |
| L2 | 1 |
| R2 | 2 |
| L3 | F |
| R3 | G |
| Select | Tab |
| Start | Enter |
| PS Button | Escape |
| D-Pad Up | Up Arrow |
| D-Pad Down | Down Arrow |
| D-Pad Left | Left Arrow |
| D-Pad Right | Right Arrow |
DualKey/ ├── icons/ # Application icon │ └── app.ico ├── src/ │ ├── windows/ # Windows build (C# / .NET 8 WinForms) │ │ ├── DualKey.csproj │ │ ├── Program.cs # Entry point, single-instance guard │ │ ├── MainForm.cs # Main GUI window, XInput/DirectInput input pipeline │ │ ├── SettingsForm.cs # Bindings / sensitivity / indicator settings │ │ ├── GamepadEditorForm.cs # Visual gamepad-layout editor (Edit Gamepad) │ │ ├── GamepadCanvas.cs # Renders the imported skin + clickable hotspots │ │ ├── OverlayLayout.cs # Parses input-overlay .png/.json presets │ │ ├── GamepadLayoutStore.cs# Persists the imported layout + mappings │ │ ├── JoystickEmulator.cs # Keyboard emulation │ │ ├── JoystickHider.cs # Device hiding │ │ └── WebServer.cs # Web interface │ └── linux/ # Linux build (Python / Tkinter) │ ├── main.py # Entry point │ ├── gui.py # Tkinter GUI + settings dialog │ ├── keymap.py # Shared key-name -> uinput/VK table │ ├── joystick_reader.py # Reads /dev/input/jsX │ ├── keyboard_emulator.py # uinput-based key emulation │ ├── joystick_hider.py # hid_sony/hid_playstation unbinding │ ├── web_server.py # Web interface │ ├── install.sh │ └── run.sh ├── scripts/ │ ├── windows-build.bat # Windows: framework-dependent dev build │ ├── windows-release.bat # Windows: self-contained single-file release build │ ├── linux-build.sh # Linux: environment check + staged build/linux/ output │ └── linux-release.sh # Linux: versioned source tarball in publish/ ├── run.bat # Windows: run script ├── README.md ├── CHANGELOG.txt ├── LICENSE # MIT License └── .gitignore
- Windows: C# / .NET 8.0, Windows Forms
- Linux: Python 3, Tkinter
- Controller Input (Windows): XInput (via SharpDX.XInput), with a DirectInput fallback (via SharpDX.DirectInput) for DualShock 4, DualSense, and other plain HID gamepads
- Controller Input (Linux): Linux joystick API (
/dev/input/jsX) - Keyboard Emulation: WinAPI
keybd_event(Windows) /uinput(Linux) - Device Management: PowerShell via WMI (Windows) / kernel module unbinding (Linux)
- Web Server: HttpListener (Windows) /
http.server(Linux)
- Administrator privileges required for controller hiding
- Some anti-cheat software may block keyboard emulation
- DualShock 3 requires third-party drivers on Windows (see Troubleshooting); DualShock 4 and DualSense work natively on both Windows and Linux — no extra driver needed
- Only one controller supported at a time
- Linux key bindings cover the standard keyboard (letters, digits, F-keys, punctuation, navigation/modifier keys) but not numpad or media keys
Controller not detected:
- DualShock 4 works out of the box — Windows already recognizes it as a plain HID gamepad, and DualKey reads it via DirectInput automatically when no XInput controller is found. No extra driver needed.
- DualShock 3 needs a driver, since Windows doesn't recognize it on its own — install ScpToolkit or DsHidMini
- If using DsHidMini: install ViGEmBus alongside it, then open the DsHidMini control app (DSHMC) and set that specific controller's mode to XInput (it isn't the default) — unplug and replug after changing it
- Confirm it works at the Windows level first via "Set up USB game controllers" (
joy.cpl) before assuming DualKey itself is at fault - Check Device Manager for unrecognized devices
Keyboard emulation not working:
- Verify the "Keyboard Emulation" checkbox is enabled
- Try running the application as Administrator
- Some applications may require the window to be in focus
- Games that only read raw input, or that run anti-cheat, may not see
keybd_event-based key presses at all — this is a Windows limitation, not something DualKey can work around
Cannot hide controller:
- Run DualKey as Administrator
- Check if PowerShell execution policy allows scripts
- Manually disable the device in Device Manager
- If DualKey crashes while the controller is hidden, it's automatically re-enabled on the next launch/close; if it's still disabled, re-enable it manually in Device Manager
"Windows protected your PC" / SmartScreen warning on launch:
- The executable isn't code-signed, so this warning is expected on first run — click "More info" → "Run anyway"
Web interface not accessible:
- Ensure port 8080 is not blocked by firewall
- Verify the application is running
- Try accessing http://127.0.0.1:8080
git clone https://github.com/yourusername/DualKey.git cd DualKey scripts\windows-build.bat
The compiled executable will be located in the build directory. On Linux, use scripts/linux-build.sh instead - the staged copy will be in build/linux/.
- Fork the repository
- Create a feature branch (git checkout -b feature/amazing)
- Commit your changes (git commit -m 'Add amazing feature')
- Push to the branch (git push origin feature/amazing)
- Open a Pull Request
- Custom key binding configuration
- Save and load binding profiles
- Support for additional controllers (DualShock 4, Xbox, etc.)
- Mouse emulation for right stick
- Macro recording
- Tray icon with quick settings
- Auto-hide on application launch
This project is licensed under the MIT License - see the LICENSE file for details.
- Microsoft WinMM API for joystick input
- Windows Forms for the GUI framework
- All contributors and testers
If you find this project useful, please consider giving it a star on GitHub.
For issues and feature requests, please use the GitHub Issues page.