import AppKit import Carbon.HIToolbox final class HotKeyManager { private var hotKeyRef: EventHotKeyRef? enum Key: UInt32 { case p = 35 /* US keyboard virtual keycode for P */ } struct Modifiers: OptionSet { let rawValue: UInt32 static let command = Modifiers(rawValue: UInt32(cmdKey)) static let option = Modifiers(rawValue: UInt32(optionKey)) static let shift = Modifiers(rawValue: UInt32(shiftKey)) } func registerGlobalHotKey(modifiers: Modifiers, key: Key, handler: @escaping () -> Void) { var eventSpec = EventTypeSpec(eventClass: OSType(kEventClassKeyboard), eventKind: UInt32(kEventHotKeyPressed)) InstallEventHandler(GetApplicationEventTarget(), { (_, _, userData) -> OSStatus in let handler = Unmanaged.fromOpaque(userData!).takeUnretainedValue() handler.handler() return noErr }, 1, &eventSpec, Unmanaged.passRetained(HotKeyHandlerWrapper(handler: handler)).toOpaque(), nil) let hotKeyID = EventHotKeyID(signature: OSType(UInt32(bitPattern: Int32(bitPattern: 0x50524F4C))), id: 1) // 'PROL' RegisterEventHotKey(UInt32(key.rawValue), modifiers.rawValue, hotKeyID, GetApplicationEventTarget(), 0, &hotKeyRef) } deinit { if let ref = hotKeyRef { UnregisterEventHotKey(ref) } } } private final class HotKeyHandlerWrapper { let handler: () -> Void init(handler: @escaping () -> Void) { self.handler = handler } }