
"Any button, any input from any peripheral, triggers anything on your system"
Install • Commands • Configuration • Behaviors • Key Names
Errm... Akeyshually, this is NOT a keyboard remapper but an evdev-based userspace daemon configured in TOML that intercepts raw input events from any evdev hardware, performs stateful modifier tracking, and executes arbitrary shell commands through a fire-and-forget subprocess model regardless of session type or graphical environment manager. And it also does remapping.

curl -sSL https://raw.githubusercontent.com/DeprecatedLuar/the-satellite/main/satellite.sh | bash -s -- install DeprecatedLuar/akeyshually
go install github.com/DeprecatedLuar/akeyshually/cmd/akeyshually@latest
Make sure $GOPATH/bin (usually ~/go/bin) is in your PATH.
Other Install Methods
Manual Install
1. Download binary for your OS from releases
2. Make executable: chmod +x akeyshually
3. Move to PATH: mv akeyshually ~/.local/bin/
From Source (for try-harders)
git clone https://github.com/DeprecatedLuar/akeyshually.git
cd akeyshually
go build -ldflags="-s -w" -o akeyshually ./cmd/akeyshually
mv akeyshually ~/.local/bin/
[!NOTE] User must be in
inputgroup:sudo usermod -aG input $USER(logout required)[!NOTE] First run auto-generates config files in
~/.config/akeyshually/. Just runakeyshuallyand you're good.

I'd check out the Overlay System and Behaviors. That's where it gets fun.
Prerequisites:
# Add yourself to the input group (first time only)
sudo usermod -aG input $USER
# then logout and back in
Run akeyshually — config auto-generates at ~/.config/akeyshually/:
akeyshually

Open config and add this shortcut:
[shortcuts]
'super+shift+a' = "notify-send 'Errm... whassup doc?'"
Press the combo, notification pops.
Now here's how to make an auto-clicker:
"f9.repeat" = ">lclick"
Tap F9 to trigger, tap again to stop.
Config lives at ~/.config/akeyshually/:
- config.toml - All-in-one config (settings, shortcuts, command aliases)
- akeyshually.service - Systemd service file (with install instructions)
[!TIP] If you wanna see a working example vheck out my personal config at the bottom of this section.
Key combinations:
- Single key: "print", "super", "f1"
- With modifiers: "super+t", "ctrl+alt+delete", "shift+print"
- Modifiers: super, ctrl, alt, shift (lowercase)
- Use + to combine modifiers and keys
Dot notation:
- Triggers define when the command fires: .onpress, .hold, .doubletap, .pressrelease, etc.
- Modifiers change how the command executes: .switch, .repeat, .passthrough
- Chain triggers and modifiers: "key.hold.repeat", "key.doubletap(200)"
- Triggers can take parameters: .hold(500), .doubletap(200), .taphold(200, 500)
Alias syntax:
- Share command across multiple keys: "f1/f2/f3.switch" = ["cmd1", "cmd2"]
- Dot modifiers from the last key apply to all: "a/b.hold" = "a.hold" + "b.hold"
Axis syntax:
- Axis direction: "rx+", "abs_y-" (axis name + direction suffix)
- Remap to scroll: "rx+" = ">scrollup", "abs_y-" = ">scrolldown"
- Works with drawing tablets, gamepads, trackballs, any ABS device
Commands:
- Direct: "super+t" = "kitty"
- Command variable: "super+t" = "$TERMINAL" or "super+t" = "terminal" (references [command_variables])
- Arrays for specific behaviors: ".pressrelease" = ["press_cmd", "release_cmd"]
Deep Dive on triggers and modifiers:
Triggers — define when the command fires:
| Trigger | Syntax | Description |
|---|---|---|
(default) / .onpress |
"key" |
Executes on key press |
.doubletap / .doubletap(ms) |
"key.doubletap(200)" |
Executes on confirmed double-tap |
.hold / .hold(ms) |
"key.hold(500)" |
Fire once after hold threshold |
.pressrelease |
"key.pressrelease" = ["cmd", "release_cmd"] |
Execute on press and release (either can be "") |
.taphold / .taphold(tap_ms, hold_ms) |
"key.taphold(200, 500)" |
Tap once, then tap-and-hold on next press |
.longpress / .longpress(ms) |
"key.longpress(500)" |
Fire once after threshold (one-shot) |
.holdrelease / .holdrelease(ms) |
"key.holdrelease(500)" = ["hold_cmd", "release_cmd"] |
Execute at hold threshold and on release |
.taplongpress / .taplongpress(tap_ms, long_ms) |
"key.taplongpress" = ["tap_cmd", "long_cmd"] |
Tap once, or tap-then-longpress |
.tappressrelease / .tappressrelease(tap_ms) |
"key.tappressrelease(200)" = ["press_cmd", "release_cmd"] |
Tap then press fires first, release fires second |
.tapholdrelease / .tapholdrelease(tap_ms, hold_ms) |
"key.tapholdrelease" = ["hold_cmd", "release_cmd"] |
Tap then hold fires first, release fires second |
Modifiers — change how the command executes:
| Modifier | Syntax | Description |
|---|---|---|
.switch |
"key.switch" = ["cmd1", "cmd2"] |
Cycles through a command array |
.repeat |
"key.hold.repeat" |
Loops command while held |
.passthrough |
"key.passthrough" |
Ignores modifiers when matching |
Normal (default):
"super+t" = "kitty" # Executes on key press
Hold (fire once after threshold):
"super+m.hold" = "mute" # Fire once after default threshold
"super+m.hold(500)" = "mute" # Fire once after 500ms (no process management)
Repeat while held:
"f9.hold.repeat" = "xdotool click 1" # Repeat every default_interval while held
"f9.onpress.repeat" = "xdotool click 1" # Toggle: start/stop on each press
Switch (cycle through commands):
"super+tab.switch" = ["cmd1", "cmd2", "cmd3"] # Cycles on each press
Double-tap (execute on quick double-tap):
"super.doubletap(200)" = "$LAUNCHER" # Double-tap within 200ms
"print.doubletap(300)" = "screen-record" # Works on any single key
Press/Release (dual commands):
"super.pressrelease" = ["", "rofi"] # Release only (modifier tap)
"super+m.pressrelease" = ["mic-on", "mic-off"] # Both press and release
Tap-then-hold:
"super+t.taphold" = "hold-cmd" # Tap once, then tap-and-hold (default timings)
"super+t.taphold(200, 500)" = "hold-cmd" # Custom tap window (200ms) + hold threshold (500ms)
Long press:
"super+h.longpress(1000)" = "shutdown" # Fire once after 1000ms (one-shot)
Hold and release:
"mute.holdrelease" = ["enable-mic", "disable-mic"] # Push-to-talk: hold to enable, release to disable
"mute.holdrelease(500)" = ["enable-mic", "disable-mic"] # Custom hold threshold (500ms)
Tap or long press:
"super+space.taplongpress" = ["quick-cmd", "long-cmd"] # Tap fires first, longpress fires second
"super+space.taplongpress(200, 1000)" = ["tap", "longhold"] # Custom tap (200ms) + long (1000ms) windows
Configure daemon behavior in the [settings] section:
| Setting | Type | Default | Description |
|---|---|---|---|
default_interval |
number | 150 |
Default interval for .repeat behaviors in milliseconds (values < 10 treated as seconds) |
disable_media_keys |
boolean | false |
When true, forwards media keys to system instead of intercepting them |
shell |
string | $SHELL |
Shell to use for executing commands (fallback: sh) |
env_file |
string | - | File to source before executing commands (e.g., "~/.profile") |
notify_on_overlay_change |
boolean | false |
Show desktop notifications when overlays are enabled/disabled |
devices |
array | [] |
Device name substrings to explicitly grab (case-insensitive), e.g. ["Huion", "Xbox", "PlayStation", "DualShock"] |
Example:
[settings]
default_interval = 150
disable_media_keys = false
shell = "/bin/bash"
env_file = "~/.profile"
notify_on_overlay_change = true
devices = ["Huion Tablet", "Xbox Controller"]
Available Key Names
Modifiers: super, ctrl, alt, shift (can have standalone shortcuts; left/right separation planned for future release)
Letters: a-z
Numbers: 0-9
Special keys: return/enter, space, tab, esc/escape, backspace, delete, insert, home, end, pageup, pagedown, semicolon/;
Arrows: left, right, up, down
Function keys: f1-f24
Print screen: print/printscreen
Numpad: kp0-kp9, kpplus, kpminus, kpasterisk, kpslash, kpenter, kpdot
Media keys: volumeup, volumedown, mute, brightnessup, brightnessdown, playpause/play, nextsong/next, previoussong/previous, calc/calculator
CD controls (legacy): playcd, pausecd, stopcd, ejectcd, closecd, ejectclosecd
Gamepad (canonical names): btn_south, btn_north, btn_east, btn_west, btn_tl, btn_tr, btn_tl2, btn_tr2, btn_start, btn_select, btn_mode, btn_thumbl, btn_thumbr
Gamepad (Xbox aliases): gp_a, gp_b, gp_x, gp_y, gp_lb, gp_rb, gp_lt, gp_rt, gp_ls, gp_rs, gp_start, gp_select, gp_guide
Gamepad (PlayStation aliases): gp_cross, gp_circle, gp_square, gp_triangle, gp_l1, gp_r1, gp_l2, gp_r2, gp_l3, gp_r3
Note: Xbox and PlayStation names map to the same buttons. Use whichever matches your controller (e.g.,
gp_a=gp_cross=btn_south).
Tablet/generic: btn_0-btn_9, btn_tool_pen, btn_touch, btn_stylus, btn_stylus2
Mouse buttons (remap output):
- Left: btn_left, lclick, leftclick, lbutton, leftbutton, mouse1
- Right: btn_right, rclick, rightclick, rbutton, rightbutton, mouse2
- Middle: btn_middle, mclick, middleclick, mbutton, middlebutton, mouse3
- Forward: btn_forward, forward, mouse4
- Back: btn_back, back, mouse5
- Extra: btn_side, btn_extra
- Use with remap prefix: ">lclick", ">rclick", ">middleclick", etc.
Axis (absolute): x, y, z, rx, ry, rz, abs_x, abs_y, abs_z, abs_rx, abs_ry, abs_rz
- Use with direction suffix: "rx+", "abs_y-"
- Remap to scroll: ">scrollup", ">scrolldown", ">scrollleft", ">scrollright" (or ">wheelup", ">wheeldown", ">wheelleft", ">wheelright")
Other: 102nd, ro
Here is my personal config:
```toml [settings] default_interval = 150 disable_media_keys = false # Set to true to let system handle media keys (GNOME/KDE/etc.) env_file = "~/.profile"
[shortcuts] "super+k" = "edit_config" "ctrl+shift+k" = "kill_switch"
"super.pressrelease" = ["", "hotline"] "super.doubletap(270)" = "$LAUNCHER"
"super+enter" = "$TERMINAL" "super+b" = "$BROWSER" "super+shift+b" = "brave" "super+e" = "thunderbird" "super+w" = "whatsapp" "super+f" = "$FILEMANAGER" "super+v" = "copyq toggle" "shift+super+n" = "notetaker"
"super+x" = "kill_window"
"print" = "grimblast -f -n copysave area ~/Media/Pictures/screenshots/latest.png" "print.doubletap" = "last_screenshot" "super+shift+p" = "last_screenshot" "super+ctrl+p" = "grimblast -f -n copysave area" "shift+print" = "grimblast -f -n -o save area" "super+p" = "grimblast copy area"
"super+y" = "yap toggle & sleep 3 && tcpeek reconnect"
$ claude mcp add akeyshually \
-- python -m otcore.mcp_server <graph>