The CH57x macro pad stores its key mappings in firmware. It sends the same keystrokes no matter what is on screen — it has no concept of the "active application". MacroPad Studio works around this by letting you flash a different preset per task, but switching is manual and a full re-flash.
KaraPad splits the job in two:
-
The pad sends neutral signals. It is flashed once with
triggers/pad-triggers.yaml, which maps the three keys to F13 / F14 / F15 and the knob to F16 / F17 / F18. These are real keys almost nothing uses, so they make perfect "triggers". -
The Mac decides what they mean. Karabiner-Elements intercepts F13–F18 and, using a
frontmost_application_ifcondition, rewrites each trigger into the real shortcut taken from the preset you assigned to that app.
config/app-map.yaml vendor/MacroPadStudio/presets/**.yaml
│ │
└────────────┬───────────────────┘
▼
karapad generate → output/karapad.json (Karabiner rules)
│
▼
karapad install → ~/.config/karabiner/assets/complex_modifications/
│
▼
F13 in Photoshop → cmd-shift-n | F13 in Premiere → cmd-k | F13 elsewhere → default
| Re-flash on app switch | KaraPad (Karabiner routing) | |
|---|---|---|
| Latency | ~1 s, pad re-enumerates | instant |
sudo at runtime |
yes (raw USB) | no |
| Wear / fragility | re-writes firmware constantly | firmware written once |
| App awareness | external watcher needed | native Karabiner condition |
For each app in config/app-map.yaml, KaraPad builds one Karabiner rule with
six manipulators (F13→button 1 … F15→button 3, F16→knob ccw, F17→press,
F18→knob cw). Each manipulator carries a frontmost_application_if condition
matching the app's bundle id (a regex, so ^com\.adobe\.Photoshop covers every
Photoshop version). A final default rule with no condition is appended last,
so unmapped apps still get a useful layout.
Token conversion lives in karapad/tokens.py: ch57x tokens (cmd-shift-z,
leftbracket, volumeup, wheelup, comma sequences) become Karabiner to
events (key_code + modifiers, consumer_key_code, mouse_key, …).
- Delays dropped.
<100>style millisecond delays inside a sequence are removed — Karabiner has no inline per-step delay. The keys still fire in order. - Knob. Per-app knob behaviour requires the knob to send F16/F17/F18 (set by the trigger preset). If you flash a "volume knob" preset instead, the knob stays global.
- Bundle ids. Provided for ~50 common apps in
data/bundle-ids.yaml; add or override any inconfig/app-map.yaml.