window.craft.shortcuts.register() round-trips successfully and native records the registration — but no keystroke will ever arrive. setupGlobalMonitor in bridge_shortcuts.zig:152-175 gives up with a comment ("requires creating an Objective-C block, which is complex in Zig"), discards the event mask, and only stores the bridge in global state. The matcher checkKeyEvent (:179) is reachable solely through handleGlobalKeyEvent (:449), which has no callers anywhere in the tree.
This is the same declared-in-JS/dead-in-native shape as the old menu bug (#29), one layer deeper: an app registers Cmd+Shift+H, gets a success reply, and silently never hears the key. stacksjs/harness has live code depending on this today (shortcuts.register('harness.summon', 'Cmd+Shift+H')).
Two viable fix shapes, no ObjC blocks required:
CGEventTap(CGEventTapCreatewith a plain C callback) — pure C API, no blocks, and it's the canonical mechanism for global hotkeys. Needs Accessibility/Input Monitoring permission, whichpermissionscan surface.- Registered-class trampoline — same pattern #29 used for the menu target:
objc_allocateClassPaira responder,class_addMethoda plaincallconv(.c)function, and useaddGlobalMonitorForEventsMatchingMask:handler:'s older non-block sibling, or a CarbonRegisterEventHotKey(still fully supported, no permissions prompt, and exactly scoped to hotkeys).
Carbon RegisterEventHotKey is probably the right call: it's what most Mac apps use for global shortcuts, takes a C callback, and avoids the Accessibility prompt entirely.
Until one of these lands, register() should reply with an honest error rather than success — a registration that can never fire is the worst of the three outcomes.
🤖 Generated with Claude Code