Option + letter shortcuts stop working intermittently (Carbon RegisterEventHotKey + IME conflict)

#235 · closed · 2 comments

View on GitHub ↗

BashkaMen

## Problem Shortcuts using `option + letter` (e.g. `option + q`) stop working intermittently. `option + number` works reliably. Re-opening the app's settings window temporarily restores them. This was reported in a downstream app, [FlashSpace](https://github.com/wojciech-kulik/FlashSpace/issues/558), whose author directed me here. ## Root Cause I believe this is a fundamental conflict between Carbon's `RegisterEventHotKey` and the macOS Input Method Engine (IME). On macOS, `option + letter` combos (e.g. `option + q` → `œ`) are processed by the Text Services Manager **before** Carbon hotkey events are dispatched. As a result: - `option + 1` → no character composition → `kEventHotKeyPressed` fires reliably - `option + q` → triggers IME composition (`œ`) → the event is consumed upstream and **never reaches the Carbon event handler** This doesn't always happen — it depends on the active application's IME mode, which is why the issue appears intermittently. ## Why the Settings Window "Fixes" It Looking at `HotKey.swift`, when a menu is open, `HotKeyCenter` switches from `RegisterEventHotKey` to a `RunLoopLocalEventMonitor` with `.eventTracking` run loop mode (raw `NSEvent` key events), which intercepts events **before** the IME layer. When the window closes, it switches back to `RegisterEventHotKey`, and the issue returns. ## Connection to `isDisallowed` I also noticed `Shortcut.swift` has an `isDisallowed` check for `option + letter` on macOS 15.0/15.1 in sandboxed apps — which suggests this is a known Apple regression. However, `isDisallowed` only affects the `RecorderCocoa` UI, not the actual hotkey registration, so the shortcut can still be registered but may silently fail to fire. ## Question Is there a way to use `RunLoopLocalEventMonitor` (or a `CGEventTap`) **permanently** for shortcuts that involve `option + letter`, rather than only when a menu is open? That would allow intercepting events before the IME layer at all times. Or alternatively, could `isDisallowed` be broadened to cover more macOS versions or non-sandboxed apps, with a warning shown to users that `option + letter` shortcuts are unreliable? ## Environment - macOS version: 26.3 - Tested via FlashSpace app

Comments

BashkaMen

I've also opened a PR with a proposed fix: #236 I'm not a Swift developer — I used Claude (AI) to analyze the code and suggest the fix, so it may not be idiomatic or fully correct. But the approach seems sound: adding an `NSEvent.addGlobalMonitorForEvents` listener specifically for `option`-only shortcuts, which intercepts events before the IME layer. Happy to iterate on it if the direction makes sense.

sindresorhus

https://github.com/sindresorhus/KeyboardShortcuts/pull/236#issuecomment-4729012703