How to Test a Controller on Windows 11
Windows prepares gamepad input through the OS driver layer before a browser can read it. The Web Gamepad API lets a page read buttons and axes from gamepads the user agent exposes, and the browser decides whether a controller matches the standard gamepad layout.1 On Windows, Xbox-style XUSB controllers use the XINPUT path and can also expose a DirectInput HID mapping for legacy software.2 DirectInput remains the path for many legacy devices such as steering wheels, fight sticks, and some HOTAS hardware. If a controller is DirectInput-only, the browser may not detect it, or it may expose a mapping that does not match the standard layout.12
Using joy.cpl as your first diagnostic step
Joy.cpl is the DirectInput Game Controller control panel. Microsoft describes it as the single control panel you can open to configure and test game controllers, with a default Test page that shows whether the device responds properly.3 Open it by pressing Win+R, typing joy.cpl, and pressing Enter. If your controller appears in the Game Controllers list, Windows has a driver-level view of the hardware and you can move to browser testing. If it does not appear, troubleshoot the driver or USB connection first because the browser cannot expose a controller Windows does not see.
Why Windows must see it first
To compare mappings, click Properties in joy.cpl and then the Test tab. The Test tab shows axes and buttons in the DirectInput/HID view. For XUSB controllers, Microsoft documents that the HID mapping exposes the left stick, right stick, combined trigger axis, D-pad, and face buttons, and notes that the combined trigger axis cannot show every trigger combination. Compare that view with the browser tester before assuming the browser is wrong.
After Windows recognizes the controller, open the tester in Chrome or Edge and press any button to prompt the browser to expose it before you compare mappings. A controller that shows in joy.cpl but stays hidden on the page usually needs that first button press, so do not assume the browser is misreporting until you have interacted with the device while the tab is open.
Confirming XInput mode before opening the browser
Confirming whether your controller is in XInput or DirectInput mode avoids a common category of detection failures. An XUSB controller can show up through XInput and DirectInput, but the two paths do not report the same control model: Microsoft's XINPUT_GAMEPAD structure exposes separate left and right trigger values, while the DirectInput HID mapping combines the two triggers into one Z axis.4 That means joy.cpl axis numbering is useful for OS-level diagnosis, but it is not a promise that the browser will use the same numbering.
How to switch to XInput mode on Windows 11
For Logitech F310 controllers, set the input mode switch on the back to X for XInput mode and D for DirectInput mode; Logitech recommends XInput whenever possible for modern Windows games.5 For 8BitDo SN30 Pro controllers, the Windows instructions use X + Start before Bluetooth pairing or wired USB connection.6 Other 8BitDo models use different combinations, such as X + Home or B + Home, so check the model manual before connecting. Set the mode before the controller connects so Windows receives the device descriptor for the mode you want to test.
Driver conflicts after Windows Update
After a Windows update, driver state can change for any hardware device. Microsoft says Windows can automatically download recommended drivers through Windows Update and that drivers can also be updated or reinstalled through Device Manager.4 If a controller worked before an update and no longer appears in joy.cpl, treat it as a Windows driver problem first, not as a browser problem. Open Device Manager by pressing Win+X and selecting Device Manager, then expand Human Interface Devices and look for the controller name or a device reporting an error code.
Reinstalling the driver path
If Windows reports a driver problem, right-click the entry and choose Update driver or Uninstall device, then replug the controller so Windows can reinstall it. For third-party controllers, use the manufacturer's official driver package when Windows Update does not provide a compatible driver. For controllers using Microsoft-provided drivers, Windows Update is the first place to check before trying third-party utilities.
Notes
Before testing in the browser, confirm Windows itself sees the controller. Open the Run dialog (Win+R), type joy.cpl, and press Enter. If the controller appears in Game Controllers, Windows has a working driver and the device is ready for browser testing. If it does not appear, troubleshoot at the OS level first: try a different USB port, reinstall the manufacturer's driver, or check Device Manager for driver errors.
If the controller has a mode switch, such as the Logitech F310's D/X switch on the back, confirm it is in XInput mode before opening the browser. XInput is usually the safest mode for browser testing. If a third-party controller needs a driver update, check the manufacturer's website for a Windows 11-compatible package before assuming the hardware is faulty.
Examples
Open Game Controllers in Windows 11
Win+R → type joy.cpl → press Enter → confirm controller appears in Game Controllers
Confirms the OS driver layer sees the device before the browser does
Check for XInput mode
In joy.cpl Properties → Test tab: compare DirectInput/HID axis mapping with the browser tester
DirectInput and browser mappings can describe the same controller differently
Device Manager HID check
Win+X → Device Manager → Human Interface Devices: look for controller name or a device reporting an error code
Use Device Manager to update or reinstall the driver before blaming the browser
Try in the tool
What this page covers
- joy.cpl Win+R > joy.cpl, the DirectInput Game Controller panel with its own Test tab
- XInput vs DirectInput XUSB controllers report separate trigger axes in XInput, but a combined Z axis under DirectInput
- Device Manager Win+X > Device Manager > Human Interface Devices, to update or reinstall a driver
- Mode switches Logitech F310's D/X switch and 8BitDo button combos must be set before the controller connects
Verify with the Gamepad & Joystick Drift Tester tool.
Try it in the tool ↑- 1.
World Wide Web Consortium, "Gamepad," W3C, July 2025. https://www.w3.org/TR/gamepad/
- 2.
Microsoft Learn, "DirectInput and XUSB Devices," learn.microsoft.com, July 2025. https://learn.microsoft.com/en-us/windows/win32/xinput/directinput-and-xusb-devices
- 3.
Microsoft Learn, "Extending the DirectInput Game Controller Control Panel," learn.microsoft.com, January 2024. https://learn.microsoft.com/en-us/previous-versions/windows/hardware/hid/extending-the-directinput-game-controller-control-panel
- 4.
Microsoft Support, "Update drivers through Device Manager in Windows," support.microsoft.com, accessed June 2026. https://support.microsoft.com/en-us/windows/update-drivers-through-device-manager-in-windows-ec62f46c-ff14-c91d-eead-d7126dc1f7b6
- 5.
Logitech Support, "Using the input mode switch on the Gamepad F310 to select DirectInput or XInput," support.logi.com, accessed June 2026. https://support.logi.com/hc/en-us/articles/360023398693-Using-the-input-mode-switch-on-the-Gamepad-F310-to-select-DirectInput-or-XInput
- 6.
8BitDo, "Instruction Manual: SN30 Pro," support.8bitdo.com, accessed June 2026. https://support.8bitdo.com/Manual/sn30-pro/
Third-party drivers can conflict with the built-in Xbox controller driver in Windows. Uninstall the third-party driver through Device Manager, unplug the controller, restart Windows, and plug the controller back in to allow Windows to reinstall its built-in driver.
joy.cpl confirms Windows can see the controller through its driver layer. CapyToolkit depends on what the browser Gamepad API exposes and how it maps the device, so check XInput mode and compare the joy.cpl mapping with the browser readout.
Open Settings and search for Game Bar. Disable it or change the shortcut. If you need to use the Xbox button during testing, avoid holding it long enough to trigger the overlay.
An update can change driver state or leave Windows waiting for a compatible driver package. Check Windows Update and Device Manager, then use the manufacturer's official Windows 11 driver if Windows does not provide one.
Yes, if the fight stick presents itself as a device the browser can expose. CapyToolkit reads the exposed Gamepad API values, so switch to XInput mode for browser compatibility when available, or use the PC compatibility mode described in the stick's manual.
How to Test a Controller on macOS
On macOS Ventura and later, Apple supports wireless Xbox, PlayStation, and other Bluetooth game controllers on Mac, and some controller customization settings require macOS Ventura 13 or later.1 PlayStation DualShock 4, DualSense, and DualSense Edge controllers can connect by USB cable or Bluetooth on Mac, while supported Xbox Wireless Controllers can also pair through Bluetooth settings.23 USB is usually the simplest first connection method for browser testing because it avoids Bluetooth pairing and firmware-update variables. For the cleanest reading, connect the controller before opening the test page, then press any button once the page loads.
If the controller appears in System Information but not in the browser, compare Safari, Chrome, and Firefox before changing macOS settings. Keep the controller awake during long drift checks by tapping a button between readings, because Bluetooth gamepads can sleep when idle. This small habit prevents a power-saving disconnect from looking like a browser mapping failure.
For drift checks, leave the controller flat on the desk and keep the cable from tugging the body. Press a button between readings so the Bluetooth link stays active, then compare screenshots only after the values settle. This keeps power-saving behavior from looking like a mapping problem.
Verifying controller recognition in macOS System Information
When you connect a controller via USB on macOS, verify that the OS itself sees the device before troubleshooting the browser. Open System Information from the Apple menu by holding Option and selecting System Information, then navigate to Hardware and then USB in the sidebar. If the controller does not appear in the USB device tree, no browser fix will make it visible. Resolve the USB recognition at the OS level first.4
Confirm macOS recognition before browser troubleshooting
For Bluetooth controllers, open System Settings and navigate to Bluetooth to check whether the device shows as connected. Apple's Xbox controller guidance says to press the Xbox button, hold the Connect button to enter pairing mode, open Bluetooth settings, and select the controller from nearby devices.3 A controller that shows as paired but not connected needs a reconnect initiated either through the settings panel or by pressing the controller's sync button. Bluetooth controllers must show as connected in the OS before the browser can see them.
After the controller shows as connected, open the tester in Chrome or Firefox and press any button to prompt the browser to expose it before reading the values. A device that remains paired but hidden on the page usually needs that first button press, so do not assume the browser is broken until you have interacted with the controller while the tab is open.
Browser choice for reliable results on macOS
Safari on macOS supports the Gamepad API, and WebKit states that any gamepad that works on macOS without additional drivers will work on a Mac.5 For troubleshooting, Chrome or Firefox can still be easier because they are commonly used for browser-based controller tests and Chrome exposes a local diagnostics page at chrome://gamepad-internals/ for raw Gamepad API data.
Choosing the fastest browser path
If the controller appears in gamepad-internals but not in the tester page, the issue is page-specific and not a browser or driver problem. If it does not appear in gamepad-internals either, return to System Settings and confirm the controller remains connected while the page is open. macOS can keep a Bluetooth controller paired without keeping it actively connected, especially after inactivity. Reconnect it from Bluetooth settings, then press a face button before refreshing the tester page.
Xbox controllers on macOS via Bluetooth
On macOS, supported Xbox Wireless Controllers can pair through the same Apple Bluetooth settings flow used for other wireless accessories: first press the controller Xbox button to power it on, then hold the small Connect button on top until the Xbox logo begins flashing rapidly to enter pairing mode, and finally open System Settings, navigate to Bluetooth, and select the controller from the list of nearby discoverable devices.
Verifying the Bluetooth connection works for browser testing
If the controller appears to connect but does not respond as expected in the browser tester, Apple recommends installing the latest available software updates for both the Mac and the controller firmware, then forgetting the device in Bluetooth settings and re-pairing it from scratch. After successfully re-pairing, open the gamepad tester page and press any button on the controller to register it with the Gamepad API, because macOS may show the controller as paired in Bluetooth settings without actually exposing it to the browser until that first physical button press triggers the HID enumeration.1 For DualSense and DualShock 4 controllers, PlayStation support pages cover USB and Bluetooth pairing on Mac directly, so no Xbox Accessories app download is involved or required.26
Notes
Safari on macOS supports the Gamepad API, but Chrome and Firefox are useful alternatives when you need browser-specific troubleshooting or Chrome's chrome://gamepad-internals/ diagnostics page.
DualShock 4, DualSense, and DualSense Edge can connect to Mac by USB or Bluetooth through Apple's pairing flow. Supported Xbox Wireless Controllers also pair through Bluetooth settings; there is no Xbox Accessories app requirement on Mac.
Examples
Verify controller in System Information
Apple menu → About This Mac → System Report → USB, find controller in the device tree
If the device is not listed here, no browser fix will make it visible, the OS USB stack must see it first
Use Chrome for consistent results on macOS
Open chrome://gamepad-internals/ in Chrome to view raw Gamepad API data before running any test page
This Chrome internal page shows every detected gamepad with all axis and button values in real time
Pair DualSense via Bluetooth on macOS
Hold PS + Create buttons simultaneously until the LED pulses white → macOS Bluetooth settings → select DualSense Wireless Controller
Pairing method is the same on macOS as on Windows, no additional app required for DualSense Bluetooth
Try in the tool
What this page covers
- System Information > USB Apple menu (Option-click) > System Information, confirms the OS sees a wired controller before browser testing
- Bluetooth pairing flow System Settings > Bluetooth, showing paired-but-disconnected devices that need a manual reconnect
- chrome://gamepad-internals/ isolates whether an issue is page-specific or a deeper OS/browser problem
- DualSense pairing hold PS + Create until the LED pulses white, then select it from Bluetooth settings
Verify with the Gamepad & Joystick Drift Tester tool.
Try it in the tool ↑- 1.
Apple Support, "Connect a wireless game controller to your Apple device," support.apple.com, April 2026. https://support.apple.com/en-us/111099
- 2.
PlayStation Support, "How to use DualSense wireless controllers with PC, Mac and mobile devices," playstation.com, accessed June 2026. https://www.playstation.com/en-us/support/hardware/pair-dualsense-controller-bluetooth/
- 3.
Apple Support, "Connect an Xbox wireless game controller to your Apple device," support.apple.com, January 2026. https://support.apple.com/en-us/111101
- 4.
Apple Developer, "USB Device Overview," developer.apple.com, accessed June 2026. https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/USBBook/USBOverview/USBOverview.html
- 5.
WebKit, "New Web Features in Safari 10.1," webkit.org, March 2017. https://webkit.org/blog/7477/new-web-features-in-safari-10-1/
- 6.
PlayStation Support, "How to use DUALSHOCK 4 wireless controllers with PC, Mac, Android, and iOS," playstation.com, accessed June 2026. https://www.playstation.com/en-us/support/hardware/ps4-pair-dualshock-4-wireless-with-pc-or-mac/
Yes. CapyToolkit reads input values such as trigger depth, but it does not control DualSense adaptive trigger resistance or advanced haptics. Those haptic effects are separate from the Gamepad API values this page displays.
Try Chrome or Firefox for troubleshooting. Safari supports the Gamepad API on macOS, but Chrome and Firefox often make it easier to compare results across browser-specific behavior.
Use Apple's Bluetooth pairing flow, update macOS and the controller firmware, then forget and re-pair the controller if needed. If a firmware update is required, follow Microsoft's controller update instructions.
Try a wired USB-C connection first. If Bluetooth is unreliable, forget the controller in Bluetooth settings, reconnect it, and test again after updating macOS.
Yes. Apple supports DualSense over USB-C and Bluetooth for Mac, and CapyToolkit reads the controller's input values through the browser Gamepad API. LED color and haptics are outside the scope of this page.
How to Test a Controller on Linux
Linux exposes gamepad devices through kernel input handlers: evdev for /dev/input/event* devices and the legacy joydev interface for /dev/input/js* devices.1 Chromium's Linux gamepad code reads axis and button state from joydev and reads special button events from evdev, so browser visibility depends on both the kernel nodes and the browser's own input backend.2 The Web Gamepad API then reports the browser-exposed gamepad as buttons and axes with normalized values.3 If a controller appears in jstest-gtk but not in the browser, compare the evdev permissions for the relevant /dev/input/event* device before assuming the browser is broken.
Understanding evdev versus joydev on Linux
Understanding the difference between the two Linux kernel input interfaces is the key to resolving browser detection failures. The joydev interface exposes controllers as /dev/input/js* devices and is the legacy joystick API; the kernel documentation says newer clients are encouraged to use the generic evdev interface.1 The evdev interface exposes devices as /dev/input/event* files and is the generic input event interface for userspace.
Chromium's Linux backend reads button and axis events from the joydev node, then reads special button events from the evdev node when needed.2 That is why jstest-gtk can show a controller while a browser still misses part of the device: the two tools are not reading the same set of Linux input nodes.
Finding the correct event device for your controller
To identify which event* device corresponds to your controller, run cat /proc/bus/input/devices in a terminal. Find your controller name in the output and look at the adjacent Handlers line: it shows the event number, for example event5, that maps to /dev/input/event5. Once you have identified the event device, check whether your current user has read permission on that specific file before diagnosing any browser-level issues.
Adding a udev rule for permanent evdev access
For a permanent permission fix that does not rely solely on temporary group membership changes, you can write a custom udev rule that grants access to your specific controller based on its unique USB vendor and product ID pair. Create a new rules file at /etc/udev/rules.d/99-gamepad.rules using sudo, then add a rule line that specifies the vendor ID, product ID, GROUP="input", and MODE="0664" for your controller hardware. After saving the file, run sudo udevadm control with the reload-rules option followed by sudo udevadm trigger in a terminal, then physically unplug and replug the controller so the new rule is applied to the device node on reconnect.
Checking browser access after the rule takes effect
After reconnecting the controller, refresh the browser tester page and press a button to register the device with the Gamepad API. If the browser still cannot see the controller, re-check the specific /dev/input/event* device permissions with ls -l and confirm the current user account is a member of the input group by running id in a terminal.
systemd's default input subsystem rules automatically assign the input device class to the input group, and they set file mode 0664 for js device nodes so group members can read them.4 systemd also automatically tags joystick input devices with the uaccess tag when they carry the ID_INPUT_JOYSTICK property, which grants the currently logged-in user transparent access through logind without manual group changes.5 For controllers that lack a fixed USB ID or for a quick general fix, the simpler approach is adding your user to the input group: run sudo usermod -aG input $USER and then fully log out of the desktop session and log back in.6 Simply closing and reopening a terminal window is not sufficient, because the group membership change requires a complete session restart to propagate to all processes.
Wayland versus X11 for browser controller testing on Linux
Wayland and X11 can affect how pointer and keyboard focus behave in desktop applications, but controller visibility in the browser fundamentally starts at the kernel input layer below either display server, so the choice of compositor is rarely the root cause of a gamepad detection failure. If the same physical controller works correctly in one desktop session but fails to appear in another session on the exact same Linux system, compare the evdev device permissions between the two sessions rather than immediately assuming the display server protocol is responsible.
Comparing permissions between sessions to isolate the cause
Run ls -l /dev/input/event* in each session to compare the file ownership and permission bits directly side by side. Different ownership or mode values between two sessions on the same machine point to a session-specific udev rule or a logind access policy as the more likely cause of the discrepancy. Always log out of the desktop session completely and log back in after making any group membership changes, because simply closing and reopening a terminal window does not apply the new group permissions to already-running desktop processes.
Notes
First check that the OS sees the controller: run ls /dev/input/js* in a terminal and verify a js0 or similar device exists. Install jstest-gtk, available as the package jstest-gtk or joystick on many distributions, and verify the controller shows full axis and button movement before testing in the browser.
If jstest-gtk works but the browser does not detect the controller, compare evdev permissions. Run ls -l /dev/input/event* and check that the current user can read the relevant event device. A targeted udev rule can set GROUP="input" and MODE="0664" for the controller, then run sudo udevadm control with the reload-rules option and unplug and replug the controller.
Alternatively, add the user to the input group with sudo usermod -aG input $USER and log out and back in. The group change requires a full session restart; closing and reopening the terminal is not enough.
Examples
Check controller appears as a joydev device
ls /dev/input/js* : should return /dev/input/js0 or similar
No output means the kernel module is not loaded or the controller is not recognized; check dmesg after plugging in
Verify evdev permissions for Chrome
ls -l /dev/input/event* : look for crw-rw---- root input; confirm current user is in the input group
Run id to check your groups; if input is not listed, run sudo usermod -aG input $USER and log out and in
Reload udev rules after adding a controller rule file
sudo udevadm control --reload-rules && sudo udevadm trigger : then unplug and replug the controller
The new rule applies on reconnect; the previous session permissions are not retroactively updated
Try in the tool
What this page covers
- evdev vs joydev Chromium reads /dev/input/event* (evdev); jstest-gtk primarily reads /dev/input/js* (joydev)
- Finding the right device cat /proc/bus/input/devices, then match the Handlers line's eventN to /dev/input/eventN
- Permanent udev rule /etc/udev/rules.d/99-gamepad.rules with GROUP="input" MODE="0664", then udevadm control --reload-rules
- input group membership sudo usermod -aG input $USER, requires a full logout/login, not just a new terminal
Verify with the Gamepad & Joystick Drift Tester tool.
Try it in the tool ↑- 1.
Linux Kernel Documentation, "Input Subsystem," docs.kernel.org, accessed June 2026. https://docs.kernel.org/input/input.html
- 2.
Chromium, "gamepad_device_linux.cc," chromium.googlesource.com, accessed June 2026. https://chromium.googlesource.com/chromium/src/+/HEAD/device/gamepad/gamepad_device_linux.cc
- 3.
MDN, "Using the Gamepad API," developer.mozilla.org, April 2026. https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API
- 4.
systemd, "50-udev-default.rules.in," github.com/systemd/systemd, accessed June 2026. https://github.com/systemd/systemd/blob/main/rules.d/50-udev-default.rules.in
- 5.
systemd, "70-uaccess.rules.in," github.com/systemd/systemd, accessed June 2026. https://github.com/systemd/systemd/blob/main/rules.d/70-uaccess.rules.in
- 6.
Red Hat Documentation, "Managing users and groups," docs.redhat.com, accessed June 2026. https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/configuring_basic_system_settings/managing-users-and-groups_configuring-basic-system-settings
The group change requires a full logout and login to take effect, not just closing and reopening the terminal. Log out of your desktop session completely and log back in. Then replug the controller and test again.
The issue is almost always evdev permissions, not a missing package. Chrome uses /dev/input/event*, not /dev/input/js*. CapyToolkit reads the browser Gamepad API view, so if Chrome cannot read the event device, the tester cannot display the controller. Working in jstest-gtk does not guarantee the evdev interface has the correct permissions. Check ls -l /dev/input/event* and confirm your user is in the input group.
Run cat /proc/bus/input/devices in a terminal and look for your controller name. The Handlers line adjacent to it will show the event number, for example event5, that maps to /dev/input/event5.
Some Linux drivers expose motion sensors as separate evdev devices. This tester reads the browser Gamepad API view, not every sensor device, so extra kernel-level inputs may not appear in the browser readout.
Usually, the first thing to check is evdev access. Wayland and X11 can affect pointer and keyboard focus, but controller visibility starts at the kernel input layer. If permissions differ between sessions, compare /dev/input/event* before changing browser settings.
How to Test a Controller on Steam Deck
The Steam Deck runs SteamOS, a Linux-based operating system, with two distinct modes. Gaming Mode is the default game-launching interface; Desktop Mode provides a PC-style desktop for running desktop applications. Valve describes SteamOS as the operating system on Steam Deck and says you can head out to the desktop when you want a more hands-on PC experience.1 Browser controller testing belongs in Desktop Mode, where you can open a browser and run desktop applications. To switch, hold the Steam button and select Power, then Switch to Desktop. For wired external controllers, remember that the Deck has a single multi-purpose USB-C jack, so a hub or dock is needed for USB-A peripherals.
For drift checks, keep the Deck flat and press a button between readings so the built-in controller stays active while the browser samples the axes.2
Switching to Desktop Mode for browser testing
To run any browser-based gamepad test on the Steam Deck, you must first switch the device into Desktop Mode, because the default Gaming Mode interface does not provide access to a standard web browser. Valve describes Desktop Mode as the hands-on PC-style desktop experience built into SteamOS, and it allows you to install and run desktop applications independently from the Steam game library.1
Why the browser needs Desktop Mode rather than Gaming Mode
The gamepad tester requires a normal browser tab with a fully visible page and direct access to the Gamepad API, none of which are available inside the Gaming Mode fullscreen launcher interface. Gaming Mode is designed exclusively for launching and playing Steam games through Valve custom frontend, so it cannot host a standard web page with JavaScript API access.
In Desktop Mode, open a web browser from the taskbar or the application menu. Navigate to the gamepad tester page in whichever browser you prefer, such as Chromium or Firefox. When you finish testing, use the Return to Gaming Mode shortcut icon on the desktop to switch back to the standard Steam game launcher interface.
Built-in Steam Deck controls in Desktop Mode
The Steam Deck's built-in thumbsticks, face buttons, bumpers, triggers, and paddles have a defined controller mapping in SDL's Steam Deck HID driver. That driver sends the sticks, triggers, buttons, and paddles through gamepad axis/button paths, while the trackpads are sent through SDL's joystick touchpad API rather than as ordinary gamepad axes.3 The browser Gamepad API then exposes the browser-visible gamepad as normalized buttons and axes.4
What the browser can see
Press any button on the Deck to register the device, then test each axis and button. The touchpads may still be usable as pointer controls in Desktop Mode, but they should not be treated as standard thumbstick axes in this browser tester. The trackpads report movement through a separate pointer-style API rather than through the Gamepad API axis array, so the tester cannot display trackpad position even though the rest of the Deck controls are visible.
Testing external controllers connected to the Steam Deck
Connecting an external controller to the Steam Deck requires a USB-C hub with a USB-A port for wired connections, since Valve describes the Deck as having a single multi-purpose USB-C jack for charging, peripherals, and display output.2 Connect the hub, plug the controller into the hub's USB-A port, and press a button to register the external controller in the browser. The browser can expose multiple connected gamepads, so the external controller appears as a separate gamepad entry from the Deck's built-in controls.4
When Steam has taken exclusive input ownership
Steam Input can emulate an Xbox controller for games. Steamworks documentation says that on macOS and Linux, emulated controller input is provided by a driver, and the controller appears in games as an Xbox controller.5 On Linux desktops, Steam Input can also use EVIOCGRAB on the raw evdev device on X11 so games see the virtual controller instead of the raw one; this is why the same physical controller can appear differently depending on Steam Input and compositor behavior.6 If an external controller appears when Steam is not running but not when Steam is open in the background, close Steam from the Desktop Mode taskbar and reload the browser page before testing again.
Notes
The Steam Deck's built-in controls, including thumbsticks, trackpads, and buttons, are available to apps and games in Desktop Mode when Steam is running. In Desktop Mode, the built-in sticks should appear as a browser-visible gamepad after pressing a button on the Deck itself. The trackpads are pointer-style inputs and should not be treated as standard thumbstick axes in this browser tester.
For external controllers connected via USB-C with a hub or via Bluetooth, the behavior follows standard browser Gamepad API rules. If an external controller is recognized by Steam in Gaming Mode but not by the browser in Desktop Mode, check Steam Input configuration and the /dev/input/event* permissions described in the Linux controller guide. The Steam Deck runs SteamOS, so the same evdev permission rules apply.
Examples
Switch to Desktop Mode on Steam Deck
Hold Steam button → Power → Switch to Desktop
Desktop Mode gives access to a web browser for gamepad testing; use the Return to Gaming Mode shortcut on the desktop when done
Install Chromium in Desktop Mode
Open Discover app store → search Chromium → install → launch and navigate to the gamepad tester
Firefox is also available in Discover as an alternative browser
Test built-in Steam Deck controls
In Desktop Mode with Chromium open, move the left thumbstick: the axis canvas responds after pressing any button on the Deck
Steam Deck built-in controls behave as a browser-visible gamepad in Desktop Mode for the Gamepad API
Try in the tool
What this page covers
- Switch to Desktop Mode hold the Steam button > Power > Switch to Desktop, since Gaming Mode has no browser access
- Trackpads are not axes reported through SDL's joystick touchpad API, not the standard Gamepad API axis array
- External controller wiring the Deck has one multi-purpose USB-C jack, so a hub is needed for USB-A peripherals
- Steam Input conflicts Steam can grab the raw evdev device and present a virtual Xbox controller instead
Verify with the Gamepad & Joystick Drift Tester tool.
Try it in the tool ↑- 1.
Steam Deck, "Software," steamdeck.com, accessed June 2026. https://www.steamdeck.com/en/software
- 2.
Valve, "Steam Deck Hardware," steamdeck.com, accessed June 2026. https://www.steamdeck.com/en/hardware
- 3.
MDN, "Using the Gamepad API," developer.mozilla.org, April 2026. https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API
- 4.
SDL, "SDL_hidapi_steamdeck.c," github.com/libsdl-org/SDL, accessed June 2026. https://github.com/libsdl-org/SDL/blob/main/src/joystick/hidapi/SDL_hidapi_steamdeck.c
- 5.
Steamworks Documentation, "Steam Input Gamepad Emulation: Best Practices," partner.steamgames.com, accessed June 2026. https://partner.steamgames.com/doc/features/steam_controller/steam_input_gamepad_emulation_bestpractices?language=english
- 6.
COSMIC compositor issue, "Support exclusive gamepad access (EVIOCGRAB) for Steam Input on Wayland," github.com/pop-os/cosmic-comp, 2026. https://github.com/pop-os/cosmic-comp/issues/2066
Yes, in Desktop Mode. CapyToolkit reads the browser-visible Gamepad API device, so the built-in thumbsticks, buttons, triggers, and paddles are mapped as gamepad controls. The trackpads are pointer-style inputs rather than standard thumbstick axes.
Steam Input can create an emulated Xbox-style controller for games, and on Linux desktops Steam may grab the raw evdev device while presenting the virtual controller. Close Steam or disable Steam Input for that controller, then reload the browser page and test again.
Yes. Steam Deck Desktop Mode uses Discover for Flatpak apps, and common browsers are available through that path. Use whichever browser supports the Gamepad API on your SteamOS installation.
Persistent drift in a built-in control is hardware-level. Increasing the deadzone in Steam Input can mask it temporarily, but replacement or repair is the durable fix.
Not exactly. In Gaming Mode, Steam Input can process controller input before a game sees it. In Desktop Mode through the browser, you read the browser-visible Gamepad API device, so compare both contexts if a value only appears in one place.
Gamepad Testing on Linux with Steam and Proton
Steam on Linux uses a software layer called Steam Input that intercepts controller input before it reaches any application.1 When Steam is running, your controller's raw hardware signals may be processed, remapped, and re-emitted as a virtual gamepad rather than passed through directly.2 Testing in a browser before launching Steam gives you the unmodified hardware reading that reveals whether a problem is in the hardware itself or in Steam Input's configuration. For Proton troubleshooting, record both the closed-Steam value and the in-game value so the comparison is easy to explain.34
How Steam Input intercepts controller data on Linux
On Linux, the Steam client reads raw input events directly from the kernel evdev interface and then creates a virtual gamepad device that it presents to applications whenever a game window is focused or Big Picture Mode is active.1 Applications running on the system, including your web browser, may then receive controller data from this Steam-generated virtual device rather than from the actual physical hardware, which means the values you see can differ from what the controller truly outputs.
Raw hardware readings versus Steam Input readings
The practical effect of this Steam Input interception layer is that the browser may silently display axis values that have been modified by Steam Input configurable deadzone compensation, custom calibration curves, and per-game response remapping profiles rather than the true unmodified raw hardware values you actually need to evaluate when diagnosing whether your controller has a genuine drift problem.5
To obtain a clean, unmodified hardware reading that reflects the true state of your controller sensors, close the Steam client entirely before opening the browser and running the gamepad test. Right-click the Steam icon in the Desktop Mode taskbar and select Exit Steam to ensure no background processes remain active. Once Steam has fully stopped, reload the test page completely, press a button on your controller to register it with the Gamepad API, and then read the raw axis values directly from the kernel evdev interface without any Steam Input processing layer modifying the signal.3
Disabling Steam Input for a single controller
When you need to test controller hardware without closing Steam entirely, you can disable Steam Input for one specific device. Open Steam Settings, navigate to the Controller section, and find the configuration for your controller model. Set the template to No Steam Input. After applying this change, disconnect and reconnect the controller so Steam releases exclusive hold and the kernel evdev data flows directly to the browser.5
Testing with Steam running versus closed: interpreting the difference
Compare the browser reading with Steam Input disabled against the value you saw in the game or with Steam running. That comparison separates raw hardware behavior from the software layer that Steam applies before a game receives the controller state. Recording both values side by side makes it easier to explain a support case or decide whether a hardware repair is actually needed.
When the values differ
If the browser shows a different axis value with Steam running than with Steam closed, Steam Input's deadzone or calibration is modifying the hardware signal. The value with Steam closed is the true hardware reading. The difference tells you how much correction Steam Input is applying. A tiny difference can be normal compensation; a larger difference suggests the hardware drift exceeds what Steam Input is filtering. If the values match closely, the hardware is likely fine and the in-game symptom points to a Steam Input configuration issue rather than a worn stick.
SDL gamepad database and its effect on game button layouts
SDL2, the game development library used by most native Linux games and many Proton titles, maintains a gamepad database that maps controller USB vendor and product IDs to named button layouts.62 When your controller's IDs appear in the SDL database, the game remaps the raw axis indices to expected names. When your controller is not in the database, the game treats it as a generic joystick, which can produce unexpected button assignments in the title's control mapping screen.6
Checking SDL mappings before game launch
Install sdl2-jstest through your distribution's package manager, then run sdl2-jstest with the list option to see how SDL maps your specific controller. If the output does not match your physical controls, the controller is not in the SDL database and you may need to configure button mappings manually in the game's settings. Running sdl2-jstest with the test option while pressing each button and moving each axis shows you exactly which SDL axis index corresponds to each physical control, so you can predict how most native Linux games will see the inputs before launching a title.
Notes
To isolate hardware from software: close Steam entirely before opening the browser and running the gamepad test. With Steam not running, the browser receives raw input from the kernel evdev interface without any Steam Input layer. If drift is present in the browser but not visible in games, Steam Input's deadzone or calibration settings are masking hardware drift. If drift appears in games but not in the browser, Steam Input's configuration may be applying an offset or the game's own input code is the source.
The SDL gamepad database, used by many Linux games via SDL2, also applies its own button remapping based on the controller's USB vendor and product ID. Controllers not in the SDL database may appear with non-standard axis assignments in native Linux games even when they work correctly in the browser. Run sdl2-jstest with the list option to see how SDL maps your controller, which predicts how most native Linux games will see the inputs.
Examples
Test without Steam running to get raw hardware values
Quit Steam completely → open browser → run gamepad test → compare axis readings to in-game behavior with Steam running
A difference between browser and in-game values confirms Steam Input is modifying the signal
Check SDL gamepad database mapping for your controller
sdl2-jstest --list (install via libsdl2-dev or sdl2-tools package depending on distribution)
Shows how SDL2 games will see your controller based on its USB VID/PID, useful when games show wrong button mappings
Disable Steam Input for one controller
Steam → Settings → Controller → set controller to No Steam Input template → reconnect controller
With Steam Input disabled, the device is passed through directly to all applications including the browser
Try in the tool
What this page covers
- Quit Steam for raw values right-click the Steam icon > Exit Steam, so the browser reads the kernel evdev interface directly
- Per-controller override Steam Settings > Controller > set the device template to No Steam Input
- SDL gamepad database sdl2-jstest --list shows how SDL2 games map your controller's USB vendor/product ID
- Proton scope Proton only intercepts input for Windows-native executables, not the browser's own Gamepad API access
Verify with the Gamepad & Joystick Drift Tester tool.
Try it in the tool ↑- 1.
Steamworks Documentation, "Steam Input Gamepad Emulation - Best Practices," partner.steamgames.com, accessed June 2026. https://partner.steamgames.com/doc/features/steam_controller/steam_input_gamepad_emulation_bestpractices?language=english
- 2.
ValveSoftware, "Proton/docs/CONTROLLERS.md," github.com, accessed June 2026. https://github.com/ValveSoftware/Proton/blob/proton_11.0/docs/CONTROLLERS.md
- 3.
The Linux Kernel Documentation, "Linux Input Subsystem userspace API," kernel.org, accessed June 2026. https://kernel.org/doc/Documentation/input/input.rst
- 4.
Mozilla Developer Network, "Using the Gamepad API," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API
- 5.
Steamworks Documentation, "Input Source Modes," partner.steamgames.com, accessed June 2026. https://partner.steamgames.com/doc/features/steam_controller/input_source_modes
- 6.
libsdl-org, "SDL/include/SDL_gamecontroller.h," github.com, accessed June 2026. https://github.com/libsdl-org/SDL/blob/SDL2/include/SDL_gamecontroller.h
They may not be. When Steam is running with Big Picture Mode active or a game focused, Steam Input may have taken ownership of the controller and emits a virtual device. The browser may be reading the real device or the virtual one depending on configuration. Close Steam to get guaranteed raw hardware values.
Steam Input is applying deadzone compensation in Proton that hides the drift. The browser test shows the raw hardware value before Steam Input processes it. The hardware drift is real and will worsen over time. The browser test is showing what will eventually exceed Steam Input's deadzone.
In Steam's controller settings (Steam then Settings then Controller), you can set an individual controller to a No Steam Input template. With Steam Input disabled, the device is passed through directly to applications and the browser test will show the unmodified hardware values.
No. Proton only intercepts input within the Proton game environment for Windows-native executables. It does not affect how the browser accesses hardware through the Gamepad API. The browser always uses the kernel evdev interface directly.
Both are correct in their context. CapyToolkit is showing the raw hardware value. Your Proton game is applying a deadzone through Steam Input that filters out values below its threshold. A raw reading of 0.02 will almost certainly be filtered out by Steam Input's default deadzone. If the raw value exceeds 0.08 to 0.10, it will eventually bleed through even with Steam Input active.