Skip to content

argenkiwi/keydo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

keydo

A powerful, cross-platform keyboard remapping daemon ported from keyd, written in Rust.

Release License: MIT Rust Platform

⭐ If you find this project useful, please star it on GitHub!

FeaturesPrerequisitesInstallationConfigurationUsagePlatform SpecificsAcknowledgments


keydo captures keyboard input at a low level to perform complex stateful transformations, such as multi-purpose keys (e.g., Caps Lock as Escape when tapped, Control when held), custom layers, and shortcuts.

Unlike simple key-swappers, keydo runs as a system daemon and interfaces directly with input systems across Linux, macOS, and Windows.

Note

What does keydo mean?

  • keyd oxidised: A tribute to its roots in keyd, reimagined in Rust.
  • key do: A direct command, ordering your keys to perform exactly as you wish.
  • The Way of the Key: Inspired by the Japanese (道), signifying the path or discipline of mastering your input.

Features

  • 🎯 Layer Support – Create custom keyboard layers triggered by any key.
  • Overloads – Assign different behaviors to a key when tapped vs. held.
  • 🤝 Chords – Trigger actions by pressing multiple keys simultaneously.
  • 📜 Macros – Execute complex sequences of keys and text.
  • 🔌 IPC Protocol – Interact with the running daemon to reload configurations, inject input, or monitor state.
  • 💻 Cross-Platform Backends:
    • Linux: Integrates natively with uinput and /dev/input.
    • macOS: Uses CGEventTap for capture and CGEventPost for injection (no kernel extensions needed).
    • Windows: Uses a WH_KEYBOARD_LL hook for capture and SendInput for injection (no drivers needed).

Prerequisites

  • OS Support: Linux, macOS 13.0 or later, or Windows 10/11.
  • Rust Toolchain: Rust 2024 Edition.
    • Windows: Build requires the MSVC toolchain (default) and Visual Studio Build Tools 2019 (or later) with the "Desktop development with C++" workload installed.
  • Permissions:
    • macOS: Accessibility permissions are required to capture and inject keys.
    • Windows: Requires an elevated terminal/daemon to remap input inside admin/elevated windows.
    • Linux: Root access is required to access input devices and the system IPC socket.

Installation

1. Build the Binary

Compile and install the binary using Cargo:

cargo install --path .

Ensure that ~/.cargo/bin (Linux/macOS) or %USERPROFILE%\.cargo\bin (Windows) is added to your system PATH.

2. Register the Service

Configure keydo to run automatically as a system or user service:

Linux

  1. Copy the binary to your system path:
    sudo cp ~/.cargo/bin/keydo /usr/local/bin/
  2. Automatically register and start the daemon (supports systemd and runit):
    sudo /usr/local/bin/keydo install
  3. Add your user to the keydo group to use the CLI without root (requires logging out and back in to apply):
    sudo usermod -aG keydo $USER

macOS

Register the daemon as a user-level launchd service:

keydo install

Important

You must grant keydo Accessibility permissions. Go to System SettingsPrivacy & SecurityAccessibility and add the keydo binary (~/.cargo/bin/keydo).

Windows

Register the daemon to start automatically at logon:

keydo install

Configuration

keydo uses the same configuration language as keyd. By default, it reads configuration files from:

  • Linux: /etc/keyd/ (system-wide configuration files only)
  • macOS: ~/.config/keydo/ (user-local configurations)
  • Windows: %APPDATA%\keydo\ (user-local) or C:\ProgramData\keyd\ (system-wide)

Tip

Refer to the official keyd configuration documentation for a full reference of the syntax.

Basic Example

Create a configuration file (e.g., default.conf) in your platform's configuration directory:

[ids]
*

[main]
# Maps capslock to escape when tapped, and the 'nav' layer when held
capslock = overload(nav, esc)

[nav]
h = left
j = down
k = up
l = right

Usage

Start the daemon manually or use the CLI to interact with a running instance.

Daemon Commands

# Start the daemon in the foreground
keydo daemon

# Run the daemon with a specific configuration file
keydo daemon --config path/to/config.conf

# Check configuration files for syntax errors
keydo check path/to/config.conf

# Reload configurations without restarting the daemon
keydo reload

Monitoring & Debugging

# Monitor key events in real-time
keydo monitor

# Stream live layer state changes
keydo listen

# List all valid key names for configuration files
keydo list-keys

Input & Macro Injection

# Inject raw text
keydo input "Hello, World!"

# Execute a macro sequence (e.g., Control+C, then Control+V)
keydo do "C-c C-v"

# Bind a key temporarily
keydo bind "main.j=down"

Platform Specifics

Linux Permissions

When running as a service, the keydo daemon runs as root to interface with /dev/input and /dev/uinput. The IPC socket /run/keydo/socket is owned by the keydo system group with 0660 permissions.

If setting permissions manually without the installer:

  1. Create the socket directory with setgid group permissions:
    sudo mkdir -p /run/keydo
    sudo groupadd -f keydo
    sudo chown root:keydo /run/keydo
    sudo chmod 2750 /run/keydo
  2. Add your user to the group:
    sudo usermod -aG keydo $USER
  3. Log out and log back in to apply the group changes.

Windows Details

On Windows, a system-wide low-level keyboard hook (WH_KEYBOARD_LL) captures events and SendInput injects them. Input is translated by scancode, making remappings layout-independent. IPC uses the named pipe \\.\pipe\keydo.

Warning

Windows Limitations & Safety Hooks

  • Elevated Windows: Hook input is not captured inside admin/elevated programs unless the daemon itself runs in an elevated command prompt.
  • Anti-Cheat & Games: Some games/anti-cheat systems block or flag SendInput-injected events.
  • Console Window: The daemon currently runs in a visible console window when started.
  • Unicode Macros: Unicode composition sequences are currently macOS-only.
  • No Device Matching: All keyboards appear as a single device; per-device matching via [ids] is not supported.
  • Emergency Panic Sequence: If input locks up or remapping stops under heavy load, press and hold Backspace + Enter + Escape to instantly terminate the daemon and restore default keyboard behavior.

Acknowledgments

This project is a port of keyd created by Raheman Vaiya. We are incredibly grateful for his work on the design and configuration syntax.

About

Keyd oxydised

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages