An open API service indexing awesome lists of open source software.

https://github.com/jagbhandal/keyzer

Visual key-remapper for Razer Tartarus Pro & Naga Pro on Linux — a Razer Synapse-style UI on top of input-remapper.
https://github.com/jagbhandal/keyzer

chroma input-remapper key-remapping keybind keybinding keypad linux-app naga-pro openrazer razer razer-peripherals razer-synapse synapse tartarus-pro

Last synced: 7 days ago
JSON representation

Visual key-remapper for Razer Tartarus Pro & Naga Pro on Linux — a Razer Synapse-style UI on top of input-remapper.

Awesome Lists containing this project

README

          


KEYZER


Linux
MIT licensed
Built on input-remapper
Wayland ready
No telemetry

The Razer Synapse experience Linux never had — click your device, set a key.

![KEYZER — click a key on a picture of your device and bind it](docs/screenshots/keyzer.png)

> Razer Synapse doesn't run on Linux, and [input-remapper](https://github.com/sezanzeb/input-remapper)'s stock editor makes you map raw event codes by hand. **KEYZER gives you the workflow you actually want: see your real device, click a key, pick a binding — and it's live instantly, no Apply step.** Free, open source, no account, no telemetry.


KEYZER in action — keypad, calibration, 4-way thumb mode, profile compare, Chroma lighting


In-app calibration
Calibrate in the app — click a key, press it, done. No terminal.
Compare two profiles
Compare profiles — green = same, amber = changed, at a glance


Naga Pro side view
Naga Pro — the 12-button thumb grid, face-on
Per-zone Chroma lighting
Lighting — per-zone Chroma effects + a full colour wheel


Tartarus thumb pad in 4-way movement mode
4-way thumb (movement) — diagonals auto-blend from the cardinals: buttery WASD strafing, zero stutter
Tartarus thumb pad in 8-way mode
8-way thumb (discrete) — bind all eight directions independently for abilities

## Supported devices

| Device | USB ID | Views |
|---|---|---|
| Razer Tartarus Pro (keypad) | `1532:0244` | keypad |
| Razer Naga Pro (mouse) | `1532:008f` | top (L/R click · wheel + tilt · sensitivity) · side (12-button thumb grid) |

Adding a device is just an entry in [`layouts.json`](layouts.json) — no code change. PRs welcome for more Razer gear.

## KEYZER vs Razer Synapse

KEYZER isn't trying to out-feature Synapse — it fills the gap Synapse leaves on
Linux, where Synapse simply doesn't run. Here's the honest picture, including where
Synapse is more capable:

| | KEYZER | Razer Synapse |
|---|---|---|
| **Runs on Linux** | ✅ Yes (Wayland + X11) | ❌ Windows / macOS only |
| **Price & account** | ✅ Free, open source, no account | Free, but requires a Razer account |
| **Telemetry** | ✅ None | ❌ Collects usage data |
| **Click-the-device remapping** | ✅ Yes | ✅ Yes |
| **Key / combo / mouse-button bindings** | ✅ Yes | ✅ Yes |
| **Macros** | ⚠️ Basic chords (full macros via input-remapper presets) | ✅ Full recorder with timing |
| **Profiles** | ✅ Yes — plain JSON, import/export, version-control friendly | ✅ Yes — with cloud sync |
| **Per-app / per-game auto-switch** | ❌ Not yet ([roadmap](#roadmap)) | ✅ Yes |
| **RGB / Chroma lighting** | ⚠️ Per-zone colour, brightness & effects (needs OpenRazer) | ✅ Full Chroma Studio (per-key, animations, app sync) |
| **DPI / sensitivity stages** | ❌ No (a hardware function) | ✅ Yes |
| **Hypershift / second layer** | ✅ Yes — hold a key for a whole second layer | ✅ Yes |
| **8-way thumb-pad modes (4-way / 8-way)** | ✅ Yes — per device, per profile | ✅ Yes |
| **Visual calibration** | ✅ In-app (click a key, press it) | ✅ N/A (knows its own devices) |
| **Profile compare / diff** | ✅ Yes — see what changed between profiles | ❌ No |
| **On-board memory (profile saved on the device)** | ❌ No — applies live through the OS, so it works system-wide | ✅ Yes — travels with the device |
| **Supported devices** | ⚠️ Tartarus Pro + Naga Pro (more via a JSON entry) | ✅ The full Razer lineup |
| **Support** | Community / unofficial | Official (Razer) |

**The takeaway:** if you're on Windows, use Synapse. If you're on Linux and want
your Razer keypad or mouse to actually be remappable — with a UI instead of raw
event codes — that's what KEYZER is for.

## Install

KEYZER needs two things, both packaged on Ubuntu/Debian: the **input-remapper** engine and **PySide6** (the Qt6 UI). OpenRazer is **optional** (lighting only).

**TL;DR** (Ubuntu/Debian) — clone, run the installer, launch:

```bash
git clone https://github.com/jagbhandal/keyzer.git && cd keyzer && ./install.sh && python3 app/main.py
```

**Just want to look first?** `python3 app/main.py --demo` runs the whole UI with sample devices — no Razer hardware, input-remapper, or OpenRazer needed.

### Ubuntu / Debian (recommended)

```bash
# required: engine + UI
sudo apt install input-remapper \
python3-pyside6.qtquick python3-pyside6.qtquickcontrols2 \
python3-pyside6.qtsvg python3-pyside6.qtdbus

# get KEYZER
git clone https://github.com/jagbhandal/keyzer.git
cd keyzer
python3 app/main.py
```

Or just run the helper — it installs anything missing **and adds KEYZER to your
application menu** (icon + launcher), so you can open it from your app grid like
any other app instead of the terminal:

```bash
./install.sh
```

Then search **KEYZER** in your activities/app grid (right-click → pin to favourites
for one-click launch).

### Optional — Chroma lighting (OpenRazer)

Lighting control needs [OpenRazer](https://openrazer.github.io/). Without it, KEYZER works fully for remapping; the Lighting toggle simply stays disabled.

```bash
sudo add-apt-repository ppa:openrazer/stable
sudo apt install openrazer-meta python3-openrazer
# then add yourself to the 'plugdev' group and re-log
```

### Other distros (pip)

```bash
pip install --user PySide6 # if your distro lacks a PySide6 package
# install input-remapper from https://github.com/sezanzeb/input-remapper
python3 app/main.py
```

## Dependencies at a glance

| | Package | Purpose |
|---|---|---|
| **Required** | `input-remapper` (≥ 2.0) | does the actual remapping (evdev → uinput) |
| **Required** | PySide6 (`python3-pyside6.*` or `pip install PySide6`) | the UI |
| Optional | `openrazer-meta`, `python3-openrazer` | per-key Chroma lighting |

KEYZER detects what's present at startup and adapts (the footer shows engine status; the Lighting toggle disables itself without OpenRazer).

## Setting up keybinds

You don't need to know anything about input-remapper. The flow:

**Once per machine — calibrate.** Click **Calibrate** in the toolbar, then click a key on the device and press it; repeat for each highlighted key. This teaches KEYZER the real code each physical key sends. (Prefer the terminal? `python3 app/capture.py` does the same. A default map ships so you can click around before calibrating.)

**To bind a key:**
1. Pick your device, then click the key on the picture.
2. Set what it should do — three ways:
- **Listen** — click it, then press a key or shortcut (e.g. `F5`, `Ctrl+1`).
- **Quick pick** — tap a common key from the row.
- **Type it** — type the output in the binding box. This is the most powerful — it's how you set held combos like `W+A`.
3. Hit **Bind** — it's live on the device instantly. **Clear** removes it.

**What you can bind** — type any of these in the box (or use Listen / Quick pick):

| You want… | Type | Result |
|---|---|---|
| A single key | `W` · `Space` · `F5` · `Esc` · `5` | that key |
| **Diagonal movement** (two keys held together) | `W+A` | holds **W and A** while you hold the key — strafe / diagonal |
| Sprint or crouch held down | `Shift` · `Ctrl` | holds the modifier while pressed |
| A shortcut | `Ctrl+C` · `Alt+F4` · `Ctrl+Shift+1` | the combo, tapped |
| A named action | `Copy` · `Paste` · `Undo` · `Save` | the matching shortcut |
| A mouse button | `LMB` · `RMB` · `MMB` | mouse click |
| Volume / media | `Vol+` · `Vol-` · `Mute` · `Play` | media key |
| Punctuation | `-` · `=` · `/` · `Ctrl+-` | that symbol |
| Disable the key | `Disable` | the key does nothing |

**The one gamers want:** bind a thumb key to `W+A` (or `W+D`, `S+A`, `S+D`) and that single key walks you diagonally — it holds both directions for as long as you hold it.

> **Held, not tapped:** anything joined with `+` is *held down together* for as long as you hold the trigger key, then released — perfect for movement (`W+A`) and modifiers (`Shift`). The same syntax covers shortcuts like `Ctrl+C` — just tap the key and the combo fires once.

**Tartarus thumb pad — 4-way vs 8-way.** The Tartarus Pro's directional thumb pad has a mode toggle in the thumb view. **4-way** binds the four cardinals and lets diagonals happen *automatically* by holding two neighbours at once — so WASD movement stays buttery smooth, with no stutter when you roll between a strafe and straight. It's the one to use for games. **8-way** instead lets you bind all eight directions independently — ideal for mapping eight distinct abilities, at the cost of blended movement. The choice is saved per device, per profile.

Profiles (e.g. **Gaming** vs **Work**) live in the header menu — switching one applies it live instantly (there's no separate Apply step). **Compare** shows what differs between two profiles at a glance, and **Hypershift** gives each device a hold-key second layer: hold one key and every other key does something else. Export/import to share a setup. Timed/recorded macro sequences aren't in the UI yet; for those you can edit the input-remapper preset directly.

## How it works

KEYZER is a friendly front-end; the remapping is done by a proven engine.

```
┌─ KEYZER (this app) ───────────────────────────────────┐
│ device image + clickable hotspots (from layouts.json) │
│ assign panel · profiles · views · lighting │
│ │ writes preset JSON / drives the daemon │
└────────────▼──────────────────────────────────────────┘
┌─ input-remapper (engine) ─────────────────────────────┐
│ evdev → uinput remapping, runs as a system service │
└────────────────────────────────────────────────────────┘
```

KEYZER talks to input-remapper only through its CLI / preset files / DBus — never its internals — so an engine update can't break the UI. See [ARCHITECTURE.md](ARCHITECTURE.md).

## Roadmap

- [x] Visual UI: device images + clickable hotspots, assign panel, profiles, views, theme
- [x] Dependency-aware startup (engine + OpenRazer detection)
- [x] In-app click-to-calibrate (capture evdev codes from the UI; `capture.py` CLI still available)
- [x] Generate input-remapper presets from a profile and reload the daemon (`engine.py`)
- [x] Bindings persist across reboot & device reconnect (input-remapper autoload), applied automatically — no Apply button
- [x] OpenRazer lighting control (per-zone Chroma effects + brightness)
- [x] Hypershift second layer (hold-key combinations)
- [x] Per-device 4-way/8-way thumb-pad mode (smooth movement vs eight discrete binds)
- [x] Profile compare/diff + honest apply-health readout
- [x] Demo mode (`--demo`) — try KEYZER with no hardware
- [ ] App-aware profile switching (GNOME/Wayland active-window)
- [ ] Timed/recorded macros in the UI
- [ ] `.deb` package (`Depends: input-remapper, python3-pyside6.*`, `Recommends: openrazer-meta`)

## Disclaimer

KEYZER is an independent, unofficial project — **not affiliated with Razer Inc.**
"Razer", "Tartarus", "Naga", "Chroma" and related marks are trademarks of Razer Inc.,
used here only to identify compatible hardware. See [NOTICE](NOTICE) for details on
trademarks and the bundled device images.

## License

See [LICENSE](LICENSE). (KEYZER's own code; bundled device images are © Razer Inc. — see NOTICE.)