Skip to content

Repository files navigation

Polykeys

Status: v1.1.0-windows.2 - Fully functional on Windows, Linux support in progress

Switch your keyboard layout automatically based on which keyboard you plug in.

What is this?

You have multiple keyboards (Corne, Lily58, laptop keyboard...) and each one uses a different layout? Polykeys detects which keyboard you just connected and switches to the right layout automatically.

Current features:

  • Automatic layout switching on device connection/disconnection
  • Interactive device detection with polykeys add --detect
  • System default fallback when no device is connected
  • Real-time device monitoring
  • Lua-based configuration

Installation

From source

# Clone the repository
git clone https://github.com/0xJohnnyboy/polykeys.git
cd polykeys

# Build for your platform
make build

# Or build for all platforms
make build-all

# Install to system
make install

From Go

go install github.com/0xJohnnyboy/polykeys/cmd/polykeysd@latest
go install github.com/0xJohnnyboy/polykeys/cmd/polykeys@latest

Configuration

Create a config file with device-to-layout mappings:

-- Format: { "alias", "deviceID", "layout" }
mappings = {
    { "Corne", "4653:0004", "US International" },
    { "Lily58", "1209:bb58", "US" },
    { "Logitech K380", "046d:c52b", "US" },

    -- Fallback when no device matches
    { "System Default", "system_default", "French AZERTY" },
}

Device ID format: VID:PID (Vendor ID:Product ID in hex, lowercase) Tip: Use polykeys add --detect to automatically detect and add keyboards

⚠️ Important: Keyboard layouts must be installed on your system before Polykeys can switch to them. On Windows, go to Settings → Time & Language → Language & Region → Add a keyboard. On macOS, go to System Settings → Keyboard → Input Sources. On Linux, layouts are typically pre-installed.

Config file locations

Linux/macOS:

  • $XDG_CONFIG_HOME/polykeys/polykeys.lua (preferred)
  • ~/.config/polykeys/polykeys.lua
  • $XDG_CONFIG_HOME/polykeys.lua
  • ~/polykeys/polykeys.lua
  • ~/polykeys.lua

Windows:

  • %APPDATA%\polykeys\polykeys.lua (preferred)
  • %USERPROFILE%\.config\polykeys\polykeys.lua
  • %LOCALAPPDATA%\polykeys\polykeys.lua
  • %USERPROFILE%\polykeys\polykeys.lua
  • %USERPROFILE%\polykeys.lua

Usage

Start the daemon:

polykeysd
# use the --debug flag for more verbose output

Background application (Windows and macOS)

polykeys-app is the recommended day-to-day launcher. It runs in your user session, adds a notification-area/menu-bar icon, and starts the existing device monitor. Its menu shows the state and last applied layout, reloads the Lua configuration, opens logs with the system default application or $EDITOR, and quits cleanly.

After installing on Windows, Polykeys starts automatically. To configure a keyboard:

  1. Connect the keyboard.
  2. Open the Polykeys icon in the notification area.
  3. Open Devices, then choose a layout for the keyboard.

The selected mapping is saved and reloaded immediately. Selecting the checked layout removes that mapping. The System default keyboard entry controls the fallback layout used when no specific keyboard mapping applies. Devices are rescanned automatically; no manual refresh is needed.

Use Open configuration to edit polykeys.lua directly. If your Lua configuration contains custom comments or logic, tray changes are added as commented suggestions and the editor opens for your review instead of overwriting the file.

Enable automatic startup after sign-in:

polykeys-app --install
# or: make install-background

Disable it without deleting your configuration or logs:

polykeys-app --uninstall
# or: make uninstall-background

This is deliberately a per-user background application, not a Windows system service or a macOS LaunchDaemon: keyboard layout APIs and the tray/menu bar belong to the signed-in user. On Windows it registers under the current user's startup settings; on macOS it writes a current-user LaunchAgent.

Logs are stored under the platform user cache directory in polykeys/logs/polykeys.log.

Unsigned macOS builds

Until the project has an Apple Developer signing identity, macOS release artifacts are unsigned and not notarized. Gatekeeper may block their first launch. Open the app explicitly from Finder (or allow it in Privacy & Security) only after verifying where the artifact came from. Do not disable Gatekeeper globally.

Windows installer

For Windows releases, prefer Polykeys-Setup-<version>.exe. It installs Polykeys for the current user without administrator rights, enables automatic startup, creates a Start-menu shortcut and offers to launch Polykeys at the end. The uninstaller keeps configuration and logs by default; it asks before removing them.

The installer is currently unsigned. SmartScreen may warn on first launch: verify the installer source and checksum before choosing to continue. Do not install a self-signed certificate or disable SmartScreen globally.

To create a release, tag the commit first, then build the installer on Windows with Inno Setup:

git tag v1.2.0
make package-windows-installer

The installer name and embedded version come from git describe. A build made away from a tag includes its commit suffix (and -dirty when the working tree has changes).

Add a new keyboard (interactive):

polykeys add --detect
# Then plug in your keyboard

See what's happening (useful for debugging):

polykeys logs -f

List your mappings:

polykeys list

Supported platforms

  • ✅ Windows
  • ✅ macOS
  • 🚧 Linux - requires further testing

Platform implementation details

Windows:

  • Device detection via WMI queries
  • Layout switching using Windows Keyboard Layout API, preserving language
  • Polling-based detection (every 2 seconds)
  • Automatic switch to default layout on device disconnection

macOS:

  • Device detection via system_profiler USB enumeration
  • Layout switching using Carbon Text Input Sources API (CGO)
  • Polling-based detection (every 2 seconds)
  • Requires native compilation on macOS with CGO enabled
  • Supports standard macOS keyboard layouts and input methods

Important notes

WSL (Windows Subsystem for Linux)

Polykeys does not work on WSL due to limitations in device access:

  • WSL does not expose /dev/input for USB device monitoring
  • USB events are not propagated to the WSL environment
  • Layout switching commands may not affect the Windows host

Workarounds:

  • Run polykeys natively on Windows (use the Windows build)
  • Use a native Linux installation (dual boot or VM)
  • Use WSL2 with usbipd (complex setup, not recommended)

Permissions

On Linux, you may need appropriate permissions to access /dev/input. If the daemon fails to start, try:

  • Adding your user to the input group: sudo usermod -a -G input $USER
  • Running the daemon with sudo (not recommended for production)

Building

# Build for current platform
make build

# Build for all platforms
make build-all

# Build for specific platform
make build-linux
make build-windows
make package-windows-installer # Requires Inno Setup on Windows
make build-darwin

# Run tests
make test

# Show all available targets
make help

Troubleshooting

Having issues? Check the troubleshooting guide for common error codes and solutions.

All errors include a code (e.g., PK_100) to help identify and resolve issues quickly.

License

AGPL-3.0

About

Switch your keyboard layout automatically based on which keyboard you plug in. Multi OS Support.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages