Skip to content

cuongquachc88/key-modifier

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Key Modifier

A macOS menu-bar app that remaps keys using custom, user-defined rules — e.g. ⌥ + Numpad 5 → ↓ Down Arrow, or a key sequence like A , S , D → ↑. Rules are created by recording the physical keys you press, persist to disk, and are applied system-wide via a CGEvent tap.

Proof-of-concept. Ad-hoc signed, not notarized. macOS 13+.

Features

  • Chord remaps — modifier + key (⌥ + Numpad 5) → any other key.
  • Sequence triggers — type keys in order (A → S → D within 1s) to fire one output.
  • Record to capture — press the keys instead of guessing key codes; held modifiers show live while recording.
  • Global toggle shortcut — record a hotkey (e.g. ⌃⌥⌘R) that turns remapping on/off from anywhere, even while it's off.
  • Persists rules and shortcut to ~/Library/Application Support/KeyModifier/rules.json.
  • Menu-bar only (no dock icon).

Install (from a release)

  1. Download KeyModifier-*.zip from the Releases page and unzip.
  2. Move Key Modifier.app to /Applications.
  3. Because the build is ad-hoc signed (not notarized), clear the quarantine flag once:
    xattr -dr com.apple.quarantine "/Applications/Key Modifier.app"
  4. Open the app. A ⌨ icon appears in the menu bar.

First-time setup: Accessibility permission

The event tap cannot run without Accessibility permission. On first enable, the app opens System Settings → Privacy & Security → Accessibility — toggle Key Modifier on there. The app auto-starts the tap within ~1.5s of the grant (no restart needed). The menu shows a ⚠︎ warning until granted.

Creating a rule

  1. Menu bar ⌨ → Edit Rules…
  2. Add Rule → next to Trigger click Record, then press your trigger.
    • Single chord: hold ⌥ and press Numpad 5 → Done.
    • Key sequence: press keys in order (e.g. A S D) — each is added automatically — then Done.
  3. Next to Output click Record, then press the target key (e.g. ↓ Down).
  4. Save. Toggle Remapping: On from the menu.

Global toggle shortcut

In Edit Rules…, the Toggle shortcut row records a system-wide hotkey. Once set, pressing it anywhere flips remapping on/off — handy to disable quickly without opening the menu.

Build from source

Requires the Swift toolchain (Command Line Tools is enough).

# Build the .app bundle (stable bundle identity for Accessibility permission)
./scripts/build-app.sh release
open "build/Key Modifier.app"

# Verify the pure engine (no Xcode required)
swift run kmverify

Releasing

Push a tag matching release-v*.*.* and the GitHub Action in .github/workflows/release.yml builds the app, zips it, and publishes a downloadable GitHub Release:

git tag release-v0.1.0
git push origin release-v0.1.0

How it works

Physical keypress
      │
      ▼
CGEvent tap (EventTapController) ── reads keyCode + modifier flags
      │
      ▼
SequenceMatcher.feed(key)
   ├─ toggle shortcut → flip remapping (always, even when off)
   ├─ passThrough → let the key reach the app
   ├─ swallow      → part of an in-progress sequence
   └─ fire(output) → swallow the trigger, post the output key
  • KeyModifierCore (library, verified): KeyEvent (normalized keystroke), RemapRule, RuleStore (JSON persistence + active-rule set), and the pure SequenceMatcher state machine.
  • KeyModifier (executable): the SwiftUI menu-bar app, the live CGEvent tap, Accessibility handling, and the key-recording editor.
  • kmverify: a standalone check harness (full Xcode not required).

Known limitations

  • Fn is not usable as a chord modifier — it's handled in keyboard firmware and doesn't surface reliably through a CGEvent tap. Use ⌘/⌥/⌃/⇧.
  • Output is a single key(+modifiers), not a macro. (Trigger sequences are supported; sequence output is not.)
  • Prefix shadowing: if one trigger is a prefix of another (A and A , S), typing just A waits for the sequence window before firing the short rule.
  • Ad-hoc signed: rebuilding changes the code identity, so macOS may re-ask for Accessibility. Reset during development with tccutil reset Accessibility com.poc.keymodifier.

Project layout

Sources/
  KeyModifierCore/   KeyEvent, KeyCodes, RemapRule, RuleStore, SequenceMatcher
  KeyModifier/       App, MenuBar, EventTap, Permission, Recorder, Views
  kmverify/          standalone engine check harness
scripts/
  build-app.sh       assembles Key Modifier.app
  make-icon.swift    renders the app icon
.github/workflows/
  release.yml        builds + publishes a release on release-v*.*.* tags
docs/                landing page

About

macOS menu-bar app that remaps keys using custom, user-defined rules

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages