import AppKit import SwiftUI struct HotkeyRecorder: NSViewRepresentable { @Binding var shortcut: HotkeyShortcut func makeNSView(context: Context) -> HotkeyCaptureView { let view = HotkeyCaptureView() view.onShortcut = { shortcut = $0 } view.stringValue = shortcut.displayName return view } func updateNSView(_ view: HotkeyCaptureView, context: Context) { view.onShortcut = { shortcut = $0 } if view.window?.firstResponder !== view { view.stringValue = shortcut.displayName } } } final class HotkeyCaptureView: NSTextField { var onShortcut: ((HotkeyShortcut) -> Void)? override init(frame frameRect: NSRect) { super.init(frame: frameRect) isEditable = false isSelectable = false isBezeled = true bezelStyle = .roundedBezel alignment = .center font = .monospacedSystemFont(ofSize: NSFont.systemFontSize, weight: .medium) toolTip = "Click, then press a shortcut" } required init?(coder: NSCoder) { nil } override var acceptsFirstResponder: Bool { true } override func mouseDown(with event: NSEvent) { window?.makeFirstResponder(self) stringValue = "Type shortcut" } override func keyDown(with event: NSEvent) { guard let shortcut = HotkeyShortcut(event: event) else { NSSound.beep() return } stringValue = shortcut.displayName onShortcut?(shortcut) window?.makeFirstResponder(nil) } override func resignFirstResponder() -> Bool { needsDisplay = true return super.resignFirstResponder() } }