From c8b2e8e0c59f4f584019c2eeb0465518a79d3d7c Mon Sep 17 00:00:00 2001 From: Valdemar Lorenzen Date: Fri, 16 Oct 2026 13:59:54 +0200 Subject: [PATCH] fix: trust native global shortcut registration --- README.md | 2 +- Sources/ConjureKit/GlobalShortcut.swift | 24 ------------------------ TODO.md | 2 ++ 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index f21d188..1bc3953 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Cancelling recording, changing destination, or leaving the recorder restores sav For Command-Space, select **Applications** and choose **Use ⌘Space**. If it conflicts with Spotlight, Input Sources, or another app, change that binding in System Settings first. Conjure never changes macOS shortcuts for you. Shortcuts work while Conjure is running; they do not start a quit app or require Accessibility permission. -On macOS 27, [Siri AI uses Command-Shift-Space to select a window for screen capture](https://support.apple.com/en-is/guide/mac-help/iphmk4p88mkuky/mac). That system reservation can conflict even though it is not listed under Spotlight or Input Sources. Use another binding unless you have freed the Siri shortcut. +Conjure lets macOS decide whether a global shortcut can be registered, rather than rejecting it solely because it appears in the system shortcut table. A registered shortcut can still compete with system behavior; if it does, change the conflicting system shortcut or choose another binding. Install Conjure in `/Applications`, then enable **Launch at login** in Settings to start it in the background. If macOS requires approval, use **Open Login Items Settings…** to grant it. diff --git a/Sources/ConjureKit/GlobalShortcut.swift b/Sources/ConjureKit/GlobalShortcut.swift index 31d303a..c60a565 100644 --- a/Sources/ConjureKit/GlobalShortcut.swift +++ b/Sources/ConjureKit/GlobalShortcut.swift @@ -89,36 +89,14 @@ public final class GlobalShortcut { if let registration { try registration.activate(candidate) } else { - try Self.rejectSystemConflict(candidate) try native.register(candidate) } isRegistered = true } - - private static func rejectSystemConflict(_ candidate: KeyboardShortcut) throws { - var copied: Unmanaged? - let status = CopySymbolicHotKeys(&copied) - let result = copied?.takeRetainedValue() - guard status == noErr, let result else { - throw ShortcutError.native(operation: "read macOS keyboard shortcuts", status: status) - } - let hotKeys = result as NSArray - for case let record as NSDictionary in hotKeys { - guard let enabled = record[kHISymbolicHotKeyEnabled] as? NSNumber, enabled.boolValue, - let code = record[kHISymbolicHotKeyCode] as? NSNumber, - let modifiers = record[kHISymbolicHotKeyModifiers] as? NSNumber else { continue } - let relevantModifiers = UInt32(cmdKey | optionKey | controlKey | shiftKey) - if code.uint16Value == candidate.keyCode, - modifiers.uint32Value & relevantModifiers == candidate.carbonModifiers { - throw ShortcutError.systemConflict(candidate.displayName) - } - } - } } enum ShortcutError: LocalizedError { case invalidSavedShortcut - case systemConflict(String) case inAppConflict(shortcut: String, action: String) case duplicate(shortcut: String, destination: String) case native(operation: String, status: OSStatus) @@ -127,8 +105,6 @@ enum ShortcutError: LocalizedError { switch self { case .invalidSavedShortcut: return "The saved shortcut is invalid. Choose a new shortcut or clear it in Conjure Settings." - case .systemConflict(let shortcut): - return "\(shortcut) is already an enabled macOS shortcut. Check System Settings → Keyboard → Keyboard Shortcuts, including Spotlight and Input Sources. On macOS 27, Command-Shift-Space is also reserved for Siri AI screen capture. Choose another shortcut or change the system binding; Conjure will not change your system settings." case .inAppConflict(let shortcut, let action): return "\(shortcut) is already used by Conjure for \(action). Choose another shortcut." case .duplicate(let shortcut, let destination): diff --git a/TODO.md b/TODO.md index 656df57..0d43de4 100644 --- a/TODO.md +++ b/TODO.md @@ -1,2 +1,4 @@ +- [ ] conjure should pop up quicker when launching than it currently does. +- [ ] conjure emoji selector should have an extra action (default) that both copies and tries to paste the selected emoji into the application that was focused when the conjure window was spawned. - [ ] add a notes app inspired by raycast notes - [ ] improve on the conjure translation command \ No newline at end of file