Skip to content

argenkiwi/keydo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 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

2 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages