A Linux GUI for gaming input devices, driven over each device's vendor (hidraw)
interface (or vendor-class USB for the G7 Pro). Currently supports the GameSir
Cyclone 2, G7 Pro, and G7 Pro 8K PC controllers and the Logitech G502 X LIGHTSPEED
mouse (see Tested hardware); the protocol modules are per-vendor
(vendors/gamesir, vendors/logitech), so other manufacturers can be added
alongside. It covers:
- Live input view — sticks, triggers, all buttons (incl. the L4/R4/M/Home/ Share extras), D-pad, battery + charging, firmware version, and a mode warning.
- Profiles — read the active profile and switch (1–4); rumble test.
- Lighting — per-light RGB, captured effect presets, brightness/speed, audio-reactive / pick-up-to-wake / sleep timeout, and a custom keyframe animation editor (add/remove keyframes, randomize, play/pause).
- Config editor — deadzones, anti-deadzones, stick trajectory, sensitivity curves (presets and a draggable custom-curve editor), trigger tuning (hair-trigger + response curve), vibration, poll rate, and button remap.
- Gamepad macros — a per-paddle (L4/R4, plus L5/R5 on the 8K) sequence editor with per-step hold/delay timing.
- Motion / gyro (G7 Pro 8K PC) — aim/tilt activation, axis setup, and curves.
- Backup / Restore — snapshot all 4 profiles + lighting to a JSON file and write it back later.
- Mouse-mode toggle — turn KDE/KWin's gamepad-drives-the-cursor behaviour off (normal gamepad) or on (sticks-as-cursor "couch mode") from the app, plus a non-KDE EVIOCGRAB fallback (Wayland; see Status).
- Logitech G502 X mouse — button remaps and keyboard bindings (with the G-Shift second layer and an assignable G-Shift trigger), 5-stage DPI + polling-rate editor, and an onboard-macro editor (build sequences or record them from your keyboard with live timing) — edits stage into a queue and apply in one verified write.
- Mouse profiles — all five onboard profiles: pick which one you're editing, name them, switch which one the mouse runs, and restore any of them to the mouse's own factory copy.
- Demo mode — preview one of each supported controller in software, no hardware connected.
- Diagnostics — a built-in doctor that pinpoints permission, udev, and hidapi-backend problems, with a copy-paste report for bug reports (see Something not working?).
Every page wears your palette — six built-in theme presets (and full custom colors). The gallery below rotates through five pages, each in a different theme; click it (or the caption link) to step through them one at a time:
Version: 0.5.0-dev — Deadband: multi-device (Cyclone 2 + G7 Pro +
G7 Pro 8K PC + Tarantula Pro 8K controllers, G502 X mouse), the full Qt/QML app (lighting + keyframe editor,
config editor, remaps, macros, backup/restore), built-in diagnostics,
one-command install, an AUR package,
and a community NixOS flake.
Tracks main (the AUR -git package builds from the latest commit); last tagged
snapshot is v0.4.0.
Going deeper? The Manual is the user guide — how to use each
feature, troubleshooting & recovery, and an FAQ. RESEARCH.md is the
developer side — protocol, architecture, the diagnostic tools, and per-controller
findings. RELEASING.md is the release checklist. See also CONTROLLER_MAP.md (what each control
reports to Linux) and TODO.md (roadmap + open questions).
This is a spare-time project. I am one person, so fixes land when they land. It isn't careless with your hardware, though: every config write is backed up first and read back to verify, and the app refuses to write to a device it can't positively identify. Fork it and customize it however you like.
Everything here has only been developed and verified on a GameSir Cyclone 2, a GameSir G7 Pro 8K PC, a GameSir Tarantula Pro 8K, and a Logitech G502 X LIGHTSPEED mouse — nothing else.
The Tarantula Pro 8K is configured in its PC mode,
3537:103d: rebinds for all nine extra buttons (L4, R4, C1–C4, T1–T3), macros, sticks, triggers, gyro and poll rate. Lighting isn't supported yet. If it shows up as3537:103cinstead, it has auto-detected a different platform; GameSir's manual switches it to PC mode with Home + X held for 2 seconds.G7 Pro support was contributed by @brcly and verified on their hardware rather than mine. It covers the Shadow Ember edition (
3537:109bwired,3537:109cdongle), the Amazon edition (3537:10bawired,3537:10bbdongle — my own pad, write-tested on both) and the White Trimode (3537:1003wired,3537:1004on its charging dock — confirmed by an owner whose settings read back exactly as set on Windows). Deadband moves the transitional3537:100aidentity to a configuration one automatically; if the pad is showing3537:1022instead, hold SHARE + MENU (☰) together — note this also resets the active profile's remaps and the Shift layer.The G7 Pro ships in editions that differ only by USB product ID. The Zenless Zone Zero edition (
3537:105e) is recognised but not configured yet; input works and the app says so rather than failing silently.White Trimode on its dock shows up as a "T4 Kaleid".
3537:1004is also the T4 Kaleid's ID in the Linux kernel'sxpaddriver, so the kernel names the pad "GameSir T4 Kaleid" and talks to it with the wrong protocol, and games get no input from it in that mode (#14). Nothing about the pad itself has changed. On the cable (3537:1003) it should work normally, since the kernel only mislabels1004. Deadband only treats1004as a G7 Pro when the device names itself one, so a real T4 Kaleid is never touched. Other GameSir controllers, other Logitech mice, other dongles, and firmware revisions I haven't seen are unsupported and untested and may misbehave. The app won't send config writes to a device it can't positively recognize, but please don't treat it as proven-safe on hardware it has never seen. Use it at your own risk.
deadband.py — the Qt/QML app (PySide6): a polished, KDE-native UI over
the reverse-engineered core, with a live controller render, per-zone RGB +
keyframes, stick/trigger curves, button remap, macros, vibration,
backup/restore, and a mouse-mode toggle. A device picker in the header switches
between your controllers and the G502 X, which gets its own Buttons / DPI /
Macros tabs.
Deadband needs Python 3 with PySide6 and
hidapi — built with its hidraw backend.
G7 Pro configuration uses Deadband's native system libusb-1.0 transport and
needs no additional Python package. Each route below takes care of the
dependencies unless noted.
Install deadband-git from
the AUR:
yay -S deadband-git # or: paru -S deadband-gitIt's a -git package, so it always builds the latest commit. To build without
an AUR helper, use the included packaging/PKGBUILD:
cd packaging && makepkg -siUse the community flake by
Epaphroditus —
gamesir-linux-tools-nix.
Its NixOS module sets up the udev permissions declaratively and builds hidapi
with the hidraw backend. To try it without installing:
nix run codeberg:Epaphroditus/gamesir-linux-tools-nixSteamOS / Steam Deck: skip step 1 and go straight to step 2 — don't use
pacmanorpiphere.install.shdetects SteamOS and sets Deadband up in a private Python environment in your home folder (it survives SteamOS updates and changes no system package). It reuses the HID library SteamOS already ships, so nothing needs compiling; the only download is the PySide6 UI toolkit.
-
Install the dependencies. On Arch:
sudo pacman -S --needed python pyside6 python-hidapi libusb. Elsewhere, install your distribution'slibusb-1.0runtime, then:pip install --user PySide6 HIDAPI_WITH_HIDRAW=1 pip install --user --no-binary :all: hidapi
HIDAPI_WITH_HIDRAW=1matters: pip's source build otherwise selects the libusb backend, which can't open the devices. Building needsgcc, the Python headers, and libudev (Fedora/Bazzite:systemd-devel; Debian/Ubuntu:build-essential python3-dev libudev-dev). If your distro packages pyhidapi (python-hidon Arch, PyPIhid) instead, that works too and needs no build. -
Clone and install:
git clone https://github.com/broroeror/gamesir-linux-tools.git cd gamesir-linux-tools ./install.sh
install.sh installs to your home directory (~/.local) and verifies your
hidapi backend. The only privileged step is the optional one-time udev rule —
the script shows the exact commands and asks first; declining still installs
the app, it just can't reach the controller until the rule is in place.
Afterwards Deadband is in your app launcher (or run deadband). To remove
it, run ./uninstall.sh. Upgrading from the old gamesir-cyclone2 install?
install.sh cleans it up, and your settings carry over on first run.
Put the controller in Xbox / XInput mode. A G7 Pro at 3537:100a is switched
automatically to its wired 3537:109b or dongle 3537:109c configuration
identity. If it is at 3537:1022, hold SHARE + MENU (☰) together — note this also resets the active profile's remaps and the Shift layer. Use the
Start / pause mode control on the other supported GameSir controllers. The app's
header warns when it detects an unsupported mode.
Grant device access (recommended, once):
-
From the repo directory, install the udev rule — it's scoped to GameSir's USB vendor id, nothing else:
sudo cp 70-gamesir.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules && sudo udevadm trigger -
Unplug and replug the controller once, then start the app:
python3 deadband.py
To configure the G502 X mouse, install its rule the same way (the app's mouse page also shows these commands):
sudo cp packaging/udev/70-deadband-g502x.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm triggerTo verify access: getfacl /dev/hidraw0 should show a user:<you>:rw- line.
How the rule works:
- It uses
TAG+="uaccess", which grants access to the user logged in at the local desktop. - The
70-filename prefix matters: udev applies theuaccessACL in73-seat-late.rules, so a rule numbered73or higher sets the tag too late and access is silently never granted. - On a headless box with no local seat,
uaccessdoesn't apply — useMODE="0660", GROUP="input"instead and add yourself to that group.
Fallback — run as root. Without the rule, the hidraw nodes are
root-owned:
sudo python3 deadband.pyUnder sudo, ~ resolves to /root, so backups land there — another reason
to prefer the udev rule.
Open Settings → Help & Diagnostics in the app, or run deadband --doctor
in a terminal (works over SSH). The doctor checks whether the app can actually
open your devices — the classic failure is a controller that's detected but
never connects — and names the exact problem: a missing or un-applied udev
rule, a Python hidapi built with the libusb backend, and so on, with fix
commands for your distro (NixOS included). Use Copy report to paste the
result into a GitHub issue. The app shows the same guidance in a banner
whenever it finds a device it can't open.
Short version: this app changes controller settings, not firmware, and everything it does is reversible and stays on your machine. The specifics:
- What it writes. Edits go to the controller's config registers — deadzones, curves, button remaps, vibration, poll rate, and lighting — over the vendor channel, the same settings the official app changes. Writes auto-persist to the controller (there's no separate "commit" step), but they're ordinary config, not firmware — nothing here touches the bootloader.
- Back up before you experiment. Backup / Restore → Export snapshots all four profiles + lighting to a JSON file; Restore writes it back. Take one before you start changing things and you can always return to a known-good state. Restore is write-verify-retry and reports a clear pass/fail. Imported backups are validated against the controller's known register map before any write, so a hand-edited or corrupt file can't drive writes to arbitrary registers.
- Reversibility. Every setting the editor exposes can be set back the same way it was changed. The worst realistic outcome of experimenting is a profile that feels wrong — fixed by Restore, re-editing, or the controller's own factory-default reset.
- Xbox / XInput mode only. The vendor protocol is inert in PS4/DS4 and Switch modes — there the app can't reach the controller, so it can't change anything. Use the Start / pause buttons for Xbox mode (the header warns you when you're not in it).
- No network. No telemetry, no account, no phone-home — it's all local USB. Even the firmware version is read straight from the USB descriptor, not fetched online.
- Permissions. Prefer the udev rule (per-user
uaccess) over running as root — see Running. Undersudo,~is/root, so backups land there. - Tested hardware. Cyclone 2, G7 Pro 8K PC, Tarantula Pro 8K (
3537:103d) and the G502 X are verified here. G7 Pro support was contributed and verified by @brcly on the Shadow Ember edition (wired3537:109b, dongle3537:109c;3537:100ais transitioned automatically — hold SHARE + MENU if the pad is showing3537:1022), plus the Amazon edition (wired3537:10ba, dongle3537:10bb), write-tested here on both. Other G7 Pro editions are recognised but not configured. Treat anything not listed as unproven and use it at your own risk.
Most supported controllers expose a vendor HID interface (USB VID 0x3537)
with a 64-byte command channel. The G7 Pro's wired and dongle configuration
identities instead use a vendor-class USB interface that Deadband temporarily
claims from xpad; use Release to
games when configuration is finished. While claimed, its report 0x10 carries
live sticks, triggers, buttons and battery alongside chunked configuration replies.
The hidraw controllers use their enhanced report 0x12. Firmware information is
read locally from either the USB descriptor or the G7's documented device-info
query — never from the network.
For what each control reports to Linux as a normal gamepad, see CONTROLLER_MAP.md. The full command set, the lighting/keyframe register encoding, the app's architecture, and the per-controller findings (including the G7 Pro) live in RESEARCH.md.
The app is split into focused modules — the connect/read loop, the shared state,
the command channel, and the lighting/config/backup domains. That structure and the
research/ diagnostic scripts are documented in RESEARCH.md
(Architecture + Methodology & tools). One-off probes and the pre-refactor monolith
live in archive/.
Working: live input, battery, firmware readout, Xbox-mode warning, profile
read/switch, rumble, full per-light RGB + effect presets + lighting power settings, a
custom keyframe animation editor (1–8 frames, play/pause), a config editor
(deadzones, anti-deadzones, stick trajectory + sensitivity curves incl. a draggable
custom-curve editor, trigger tuning, vibration, poll rate), button remap,
per-paddle gamepad macros (read-back-verified writes), 8K motion/gyro, and
backup / restore — all verified end-to-end on hardware. Restore is
write-verify-retry; only the active profile + lighting are guaranteed (banks
0x02–0x04, the stored profiles, appear read-only on this controller).
G7 Pro: contributed by @brcly and verified on
their hardware, not mine (see Tested hardware). Wired 3537:109b and dongle
3537:109c configuration identities,
with automatic transition from 3537:100a; four editable profiles, 21 default-layer
remap sources, stick/trigger shaping, resolution/inversion/sensitivity, four-motor
vibration, report rate, D-pad options, dock settings, and semantic backup/restore.
The shared Shift layer, Continuous Trigger, advanced directional/mouse stick output,
motion configuration, Bluetooth, and the native 3537:1022 protocol are not yet exposed.
Mouse (G502 X): remaps, keyboard bindings, the G-Shift layer + trigger, DPI stages, report rate, and the onboard-macro editor are verified on hardware — including keystroke recording with live timing, macros long enough to chain across several flash sectors, and the scroll / media / F13–F24 step types. Because flash can't be rewritten in place, re-assigning a macro strands its old sector; an apply now sweeps stranded sectors automatically, so editing a button's macro costs no net slots (there's a manual sweep on the Macros tab too). Macro playback runs slightly slower than recorded — the mouse's macro engine spends a little time per step, which the per-macro speed control offsets.
Mouse profiles: all five onboard profiles are verified on hardware — picking which one you're editing (which costs no device write, so you can edit a profile you aren't currently using), renaming, switching the profile the mouse runs, and restoring one to the mouse's own factory copy in ROM. A restore is around a hundred device reads and writes, so it takes a few seconds with the controls disabled while it runs; the toast says what it's doing.
Mouse-mode gotcha (KDE Plasma 6.7): after a dongle replug, the sticks may start driving the desktop cursor — that's KWin's Game Controller plugin reading the joystick node directly, not the controller emulating a mouse. Turn it off:
kwriteconfig6 --file kwinrc --group Plugins --key gamecontrollerEnabled false
qdbus6 org.kde.KWin /KWin reconfigure # or log out/inThe app also has an in-app Stop mouse mode toggle (desktop-agnostic fallback); see Troubleshooting for the full picture.
The config register map (banks, offsets, remap records, the inferred RT block) and the open items — verifying the RT block, some remap target codes, profile-switch sync, PS4/Switch input parsing — live in RESEARCH.md and TODO.md.
Released under the MIT License — use, modify, and redistribute freely.
The G7 Pro integration was informed by the hardware-tested protocol research in
questionablesyntax/g7ctl, whose
standalone pyg7 protocol package is Apache-2.0 licensed. Deadband's Qt/QML UI
and transport integration are independent; no GPL GUI code is included.
This is an independent, hobby reverse-engineering project. It is not affiliated with, endorsed by, or supported by GameSir, and "GameSir" and "Cyclone 2" are trademarks of their respective owners. The protocol was reverse-engineered for interoperability, and the repository contains no vendor firmware or USB captures. Provided as is, without warranty — you use it, and poke at your controller, at your own risk.
