Skip to content

Repository files navigation

cmd-hanyoung

Tap left ⌘ for English, right ⌘ for Korean — instant input-source switching for macOS

English | 한국어

Release License Platform


Highlights

  • Left/right ⌘ solo-tap detection — CGEventTap (listen-only) intercepts bare ⌘ taps without consuming the key event.
  • Command combos 100% preserved — ⌘C, ⌘V, ⌘Z, ⌘Tab, ⌘Space, cmd+click/drag all work normally.
  • Force input source — switches directly to ABC or 2-Set Korean via TISSelectInputSource, bypassing the CJKV bounce bug.
  • Menu-bar control — globe icon in the status bar; per-side source picker, login-item toggle, quit.
  • Sleep/wake recovery — CGEventTap is automatically restored after system sleep.
  • Single instance — launching a second copy terminates the previous one automatically.

Install

Homebrew (recommended)

brew tap temeraire97/tap
brew trust temeraire97/tap
brew install --cask cmd-hanyoung

brew trust is required because Homebrew (2026) blocks casks from third-party taps until trusted.

Manual

Download the .zip from the Releases page, unzip, and move cmd-hanyoung.app to /Applications.

First launch — quarantine bypass

The app is self-signed and not notarized by Apple. macOS will block it on first open. Choose one of:

xattr -dr com.apple.quarantine /Applications/cmd-hanyoung.app

Or on macOS 15 Sequoia: after the blocked-launch alert, go to System Settings ▸ Privacy & Security and click Open Anyway. (The Finder right-click "Open" bypass was removed on Sequoia.)


Usage

  1. Grant Accessibility permission — System Settings ▸ Privacy & Security ▸ Accessibility ▸ add cmd-hanyoung.app and enable it.
  2. Relaunch the app if prompted.
  3. Left ⌘ tap → switches to ABC (English).
    Right ⌘ tap → switches to 2-Set Korean.
  4. Menu-bar globe icon — use submenus to change the input source assigned to each side, toggle launch-at-login, or quit.

Requirements

  • macOS 14 Sonoma or later
  • Both ABC and 2-Set Korean input sources added in System Settings ▸ Keyboard ▸ Input Sources
  • Non-sandboxed environment (Accessibility permission required)

Build from source

./Scripts/bundle.sh

This produces cmd-hanyoung.app at the repo root. The script attempts to sign with the cmd-hanyoung-dev self-signed certificate and falls back to ad-hoc signing if that codesign call fails — it branches on the actual signing result, not on whether the certificate is present. A certificate that exists but is expired or damaged therefore falls back to ad-hoc instead of failing the build. Check which one was used in the script's output:

    'cmd-hanyoung-dev' 인증서로 서명 (권한 영속)     ← certificate
⚠️  경고: ... → ad-hoc 서명으로 폴백합니다.          ← ad-hoc (permission resets on rebuild)

A universal (arm64 + x86_64) build requires Xcode.app. Without it, bundle.sh falls back to a native single-architecture build and prints a large "not for distribution" warning banner — that build is fine to run and develop against locally, but ./Scripts/release.sh will refuse to package it.


Signing & permission persistence

macOS TCC keys the Accessibility permission on the app's designated requirement (csreq), not the binary path. Ad-hoc signing (codesign --sign -) generates a new cdhash on every rebuild, causing a csreq mismatch and resetting the permission each time. Signing with a fixed-CN self-signed certificate keeps the csreq stable so the permission survives rebuilds.

One-time setup

./Scripts/make-signing-cert.sh

Or manually in Keychain Access: menu ▸ Certificate Assistant ▸ Create a Certificate — name cmd-hanyoung-dev, category Code Signing, type Self Signed Root. Create it once in your login Keychain; ./Scripts/bundle.sh auto-detects it and signs with it on every subsequent build.

Situation Signing Permission after rebuild
cmd-hanyoung-dev cert present self-signed cert persists
No cert ad-hoc fallback must re-grant each time

Notes:

  • The cert may appear "not trusted" in Keychain — this does not affect codesign or TCC. Allow keychain access when prompted on the first build.
  • Self-signed vs. Developer ID. Released builds are shipped to other Macs signed with this self-signed cmd-hanyoung-dev certificate — that is exactly what keeps the Accessibility permission alive across updates, and it is why the certificate must be backed up (see docs/RELEASING.md). What a self-signed certificate does not buy you is Gatekeeper trust: macOS quarantines the download, so users must clear the quarantine attribute (or use Open Anyway) on first launch — see Install. An Apple Developer ID certificate + notarization is what's needed for warning-free first launch and for submission to the official homebrew/cask repository; that is planned for a future release.

Reset permission for testing

tccutil reset Accessibility com.cmdhanyoung.app

FAQ

"App is damaged and can't be opened" / "Apple cannot verify"

Run the quarantine-clear command above, or use System Settings ▸ Privacy & Security ▸ Open Anyway.

Accessibility permission resets after every rebuild

macOS TCC keys Accessibility by designated requirement (csreq). Ad-hoc signing (--sign -) changes the cdhash on every build, breaking the csreq match and resetting the permission. Fix: create the cmd-hanyoung-dev self-signed certificate once (see Signing & permission persistence above; 한국어: README.ko.md). With that certificate, csreq stays stable across rebuilds and the permission persists.

macOS 15 Sequoia — left/right ⌘ shortcut conflict

Sequoia may assign system-level actions to bare left/right ⌘ taps. If detection is unreliable, go to System Settings ▸ Keyboard ▸ Keyboard Shortcuts, find the conflicting shortcut, and disable it, then relaunch the app.


Contributing

Issues and PRs welcome. Please open an issue before starting substantial changes.

License

MIT — see LICENSE.

About

왼/오 cmd로 한/영 전환. 각각.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages