Skip to main content

Keyhac 2

Python-scriptable keyboard customization for Windows and macOS.

Keyhac installs a system-wide keyboard hook and lets you script what your keys do in Python. You write one file, ~/.keyhac/config.py, and it runs unchanged on both OSes — remapping keys, binding keys to Python functions, and driving windows, applications and the clipboard from the keyboard.

Keyhac 2 is the successor to both Keyhac for Windows and Keyhac for macOS, rebuilt as one shared codebase. Its UI is built on PuiKit.

Features

  • Key remapping: key → key, key → key sequence, key → Python function.
  • Per-application key tables: match by app name, window title, Win32 window class, or the full accessibility focus path (AX on macOS, UI Automation on Windows) — down to "only in this app's text editor pane".
  • User modifiers: turn any key into a modifier of your own (User0–User3), invisible to applications.
  • One-shot modifiers: tap a modifier alone for one action, hold it to modify.
  • Multi-stroke key tables: Emacs-style prefix keys, with a balloon showing the armed prefix.
  • Clipboard history: persistent history in a popup chooser — type to filter, Enter pastes into the app you came from. Plus fixed snippets and scriptable clipboard-transform tools.
  • Window control: move, snap/tile, minimize, activate and launch applications, multi-monitor aware.
  • Keyboard macros: record and replay keys.
  • Mouse output: send clicks, wheel scrolls and pointer moves from key bindings.
  • Console window: live log, last-key and focus-path inspector — see exactly what to bind. Runs from the system tray (Windows) / menu-bar extra (macOS).

Screenshots

Console (macOS) Console (Windows)
Keyhac console window on macOS: keyboard-hook toggle, log level selector, live key-event log, last-key and focus-path inspector Keyhac console window on Windows: keyboard-hook toggle, log level selector, live key-event log, last-key and focus-path inspector
Menu-bar extra (macOS) Task tray (Windows)
Keyhac menu-bar extra on macOS with its menu open: Open Console, Edit Config, Reload Config, Keyboard Hook, Quit Keyhac Keyhac task-tray icon on Windows with its menu open: Open Console, Edit Config, Reload Config, Keyboard Hook, Quit Keyhac

Install

Download from Releases:

  • macOS 15+Keyhac-<version>-macos.dmg: drag Keyhac.app into Applications and launch it. Grant the Accessibility permission when prompted (required for the keyboard hook).
  • Windows 10/11 (x64)Keyhac-<version>-win64.zip: unzip anywhere and run Keyhac.exe.

Details, data locations and privacy notes: doc/installation.md.

Quick start

On first run Keyhac creates ~/.keyhac/config.py from a fully commented template. Open it from the tray / menu-bar icon ("Edit Config"), edit, then "Reload Config". A config defines one function:

from keyhac import *

def configure(keymap):
    kt = keymap.define_keytable(focus_path_pattern="*")   # active everywhere

    kt["Fn-J"] = "Left"                        # key -> key
    kt["Fn-A"] = "Home", "Shift-End"           # key -> sequence

    def hello():                               # key -> Python function
        print("Hello from config.py")
    kt["Fn-H"] = hello

    kt["Fn-V"] = ShowClipboardHistory()        # clipboard history popup

    kt_browser = keymap.define_keytable(app="chrome|Safari")   # per-app table
    kt_browser["Fn-R"] = "Cmd-R"

The full reference is doc/configuration.md; the shipped template (keyhac/_config.py) is a working tour of every feature.

Documentation

Running from source

python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytest          # engine + unit tests, no permissions needed
.venv/bin/python -m keyhac          # run (macOS: needs Accessibility permission)

python -m keyhac -d enables debug logging, --no-ui runs headless (hook + engine only), --config PATH uses an alternate config file (its data files live beside it).

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

keyhac-2.0.0.tar.gz (175.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

keyhac-2.0.0-py3-none-any.whl (188.5 kB view details)

Uploaded Python 3

File details

Details for the file keyhac-2.0.0.tar.gz.

File metadata

  • Download URL: keyhac-2.0.0.tar.gz
  • Upload date:
  • Size: 175.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.12

File hashes

Hashes for keyhac-2.0.0.tar.gz
Algorithm Hash digest
SHA256 97a6db48ec14caea291ed1c951cf34de756187021c7c23448da61d78c462e533
MD5 834ae0cee658d3e8e1c1636e47c2e217
BLAKE2b-256 cf6ad213ffe43c0608f2bfb86c0f125de076fd860bc861975ae6a257996db6c8

See more details on using hashes here.

File details

Details for the file keyhac-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: keyhac-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 188.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.12

File hashes

Hashes for keyhac-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 af6fc3c52114ed8078e552f61a6de2ef19c7475e5b45abc3e2a9108cf33ea1d1
MD5 8e5afd488f0071bee5796516208c8b8c
BLAKE2b-256 0256d9155ee95f901b96fa25158a22e6c8ee200738b2c18f9e80943eaedb8efb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page