A second hotkey snapshots every display the moment it is pressed and
shows that still image as the overlay, so the pointer and hover states
(tooltips, open menus) are captured. Selection is marquee-only — no
window detection — and the result is cropped from the snapshot rather
than recaptured, keeping the frame exactly as it was.
💘 Generated with Crush
Assisted-by: Crush:deepseek-v4-flash-0731
56 lines
2.0 KiB
Swift
56 lines
2.0 KiB
Swift
import Carbon
|
|
import AppKit
|
|
|
|
final class HotkeyManager {
|
|
static let shared = HotkeyManager()
|
|
|
|
/// ⌘⇧S — live capture (ScreenCaptureKit at capture time).
|
|
var onTrigger: (() -> Void)?
|
|
/// ⌃⇧⌘S — frozen capture (snapshot at hotkey press).
|
|
var onFrozenTrigger: (() -> Void)?
|
|
|
|
private var hotKeyRefs: [EventHotKeyRef?] = []
|
|
private var eventHandlerRef: EventHandlerRef?
|
|
private let signature: OSType = 0x4B505452
|
|
|
|
private init() {}
|
|
|
|
func register() {
|
|
var eventType = EventTypeSpec(
|
|
eventClass: OSType(kEventClassKeyboard),
|
|
eventKind: UInt32(kEventHotKeyPressed)
|
|
)
|
|
InstallEventHandler(GetApplicationEventTarget(), { _, event, _ in
|
|
var hotKeyID = EventHotKeyID()
|
|
let status = GetEventParameter(
|
|
event,
|
|
EventParamName(kEventParamDirectObject),
|
|
EventParamType(typeEventHotKeyID),
|
|
nil,
|
|
MemoryLayout<EventHotKeyID>.size,
|
|
nil,
|
|
&hotKeyID
|
|
)
|
|
guard status == noErr else { return noErr }
|
|
DispatchQueue.main.async {
|
|
switch hotKeyID.id {
|
|
case 1: HotkeyManager.shared.onTrigger?()
|
|
case 2: HotkeyManager.shared.onFrozenTrigger?()
|
|
default: break
|
|
}
|
|
}
|
|
return noErr
|
|
}, 1, &eventType, nil, &eventHandlerRef)
|
|
|
|
registerHotkey(id: 1, keyCode: UInt32(kVK_ANSI_S), modifiers: UInt32(cmdKey | shiftKey))
|
|
registerHotkey(id: 2, keyCode: UInt32(kVK_ANSI_S), modifiers: UInt32(cmdKey | shiftKey | controlKey))
|
|
}
|
|
|
|
private func registerHotkey(id: UInt32, keyCode: UInt32, modifiers: UInt32) {
|
|
var ref: EventHotKeyRef?
|
|
let hotKeyID = EventHotKeyID(signature: signature, id: id)
|
|
RegisterEventHotKey(keyCode, modifiers, hotKeyID, GetApplicationEventTarget(), 0, &ref)
|
|
hotKeyRefs.append(ref)
|
|
}
|
|
}
|