Ariver
2026-06-28 0badb998147135c75187a0c48f926b665af734c5
src/Apptag/ApptagApp.swift
@@ -39,7 +39,10 @@
    private static let downloadHelpMenuItemIdentifier = NSUserInterfaceItemIdentifier("TagLauncherDownloadHelpMenuItem")
    private static let externalActivationNotification = Notification.Name("TagLauncherExternalActivationRequested")
    private static let externalActivationObject = AppIdentity.bundleIdentifier
    private static let externalInvocationScheme = "taglauncher"
    private static let externalInvocationShowHost = "show"
    private static let duplicateLaunchSuppressReopenKey = "duplicateLaunchSuppressReopenAt"
    private static let overlaySpaceHotkeyID: UInt32 = 3
    private static let launcherOverlayLevel = NSWindow.Level(rawValue: NSWindow.Level.mainMenu.rawValue - 1)
    private static let overlayDefaultLevel = launcherOverlayLevel
    private static let overlayTextInputLevel = launcherOverlayLevel
@@ -50,8 +53,10 @@
    private var quickSearchLocalMouseMonitor: Any?
    private var quickSearchExternalMouseMonitor: Any?
    private var settingsWindow: NSWindow?    // Track Settings window to keep it above overlay
    private var explicitPreferencesOpenRequestedAt = Date.distantPast
    private var mainHotkeyRef: EventHotKeyRef?
    private var quickSearchHotkeyRef: EventHotKeyRef?
    private var overlaySpaceHotkeyRef: EventHotKeyRef?
    private var hotkeyEventHandlerInstalled = false
    private var isQuickSearchOpen = false
    private var quickSearchShouldHideOverlayOnClose = false
@@ -65,6 +70,8 @@
    private var statusMenuScreenForNextOverlay: NSScreen?
    private var suppressReopenUntil = Date.distantPast
    private var overlayOpenedByQuickSearchOnly = false
    private var didFinishLaunching = false
    private var pendingShowOverlayInvocation = false
    private lazy var overlayController = OverlayWindowController(
        dependencies: OverlayWindowController.Dependencies(
@@ -127,14 +134,16 @@
            refreshChromeState: { [weak self] activate, avoidSpaceSwitch in
                self?.refreshLauncherChromeState(activate: activate, avoidSpaceSwitch: avoidSpaceSwitch)
            },
            onWillHide: {
            onWillHide: { [weak self] in
                self?.unregisterOverlaySpaceHotkey()
                TagDatabase.flushPendingCategorySchemeBackupBatch()
            },
            onDidHide: { [weak self] in
                self?.overlayOpenedByQuickSearchOnly = false
                NotificationCenter.default.post(name: .tagLauncherOverlayDidHide, object: nil)
            },
            onDidShow: {
            onDidShow: { [weak self] in
                self?.refreshOverlaySpaceHotkeyRegistration()
                NotificationCenter.default.post(name: .tagLauncherOverlayDidShow, object: nil)
            }
        )
@@ -213,6 +222,9 @@
        observeLanguageChanges()
        setupLaunchAtLogin()
        suppressReopenUntil = Date().addingTimeInterval(1.0)
        didFinishLaunching = true
        closeRestoredPreferencesWindowsDuringLaunch()
        consumePendingShowOverlayInvocationIfNeeded()
        configureApplicationMenuWhenAvailable(retries: 200)
        warmAppIndexInBackground()
        relocalizeDefaultAppNotesForCurrentLanguageAsync()
@@ -243,6 +255,54 @@
        guard isRecentUserClickNearDockArea() else { return false }
        showOrFocusOverlay()
        return false  // Suppress default "unhide all windows" behavior
    }
    func application(_ application: NSApplication, open urls: [URL]) {
        for url in urls {
            handleExternalInvocationURL(url)
        }
    }
    private enum ExternalInvocationRoute {
        case showOverlay
    }
    private func handleExternalInvocationURL(_ url: URL) {
        guard externalInvocationRoute(for: url) == .showOverlay else {
            Diagnostics.log("app.externalInvocation.ignored", [
                "url": url.absoluteString
            ])
            return
        }
        requestShowOverlayFromExternalInvocation()
    }
    private func externalInvocationRoute(for url: URL) -> ExternalInvocationRoute? {
        guard url.scheme?.lowercased() == Self.externalInvocationScheme else {
            return nil
        }
        let host = url.host?.lowercased()
        let path = url.path
        if host == Self.externalInvocationShowHost, path.isEmpty || path == "/" {
            return .showOverlay
        }
        return nil
    }
    private func requestShowOverlayFromExternalInvocation() {
        guard didFinishLaunching else {
            pendingShowOverlayInvocation = true
            return
        }
        pendingShowOverlayInvocation = false
        suppressReopenUntil = Date().addingTimeInterval(1.0)
        dismissQuickSearchIfNeeded()
        showOrFocusOverlay()
    }
    private func consumePendingShowOverlayInvocationIfNeeded() {
        guard pendingShowOverlayInvocation else { return }
        requestShowOverlayFromExternalInvocation()
    }
    private func isRecentUserClickNearDockArea() -> Bool {
@@ -293,6 +353,7 @@
        hideOverlay(force: true, discardWindow: true)
        unregisterHotkey(for: .main)
        unregisterHotkey(for: .quickSearch)
        unregisterOverlaySpaceHotkey()
        TagDatabase.flushPendingCategorySchemeBackupBatch()
        removeOverlayKeyMonitor()
        removeQuickSearchExternalMouseMonitor()
@@ -480,14 +541,17 @@
        if activate && requiresForegroundOwnership
            && !shouldStayAccessoryForCurrentFullscreenSpace
            && !shouldStayAccessoryForHiddenDockChrome
            && !shouldStayAccessoryForQuickOnlySearch {
            let keyWindow = isSettingsVisible ? settingsWindow : (isOverlayVisible ? overlayWindow : nil)
            claimLauncherForeground(
                keyWindow: keyWindow,
                retries: isOverlayVisible && !isSettingsVisible ? 5 : 0,
                overlayGeneration: isOverlayVisible ? overlayGeneration : nil
            )
            if shouldStayAccessoryForHiddenDockChrome {
                beginLauncherForegroundOwnership(activate: true, keyWindow: keyWindow)
            } else {
                claimLauncherForeground(
                    keyWindow: keyWindow,
                    retries: isOverlayVisible && !isSettingsVisible ? 5 : 0,
                    overlayGeneration: isOverlayVisible ? overlayGeneration : nil
                )
            }
        }
    }
@@ -1298,9 +1362,27 @@
        ])
        if id == LauncherHotkeyKind.quickSearch.eventID {
            showQuickSearchFromGlobalHotkey()
        } else if id == Self.overlaySpaceHotkeyID {
            handleOverlaySpaceHotkey()
        } else {
            performToggleOverlay(preferredScreen: nil)
        }
    }
    private func handleOverlaySpaceHotkey() {
        guard canUseOverlaySpaceHotkey else { return }
        unregisterOverlaySpaceHotkey()
        requestQuickSearch(source: QuickSearchOpenSource.mainOverlay)
    }
    private var canUseOverlaySpaceHotkey: Bool {
        overlayWindow?.isVisible == true
            && !isSettingsVisible
            && !isQuickSearchOpen
            && !quickSearchOnlyOverlaySession
            && !isInEditMode
            && !isEditingAppNote
            && !isModalInteractionActive
    }
    private func showQuickSearchFromGlobalHotkey() {
@@ -1358,6 +1440,46 @@
        }
    }
    private func refreshOverlaySpaceHotkeyRegistration() {
        if canUseOverlaySpaceHotkey {
            registerOverlaySpaceHotkeyIfNeeded()
        } else {
            unregisterOverlaySpaceHotkey()
        }
    }
    private func registerOverlaySpaceHotkeyIfNeeded() {
        guard overlaySpaceHotkeyRef == nil else { return }
        var hotkeyID = EventHotKeyID()
        hotkeyID.signature = OSType(0x41505447) // 'APTG'
        hotkeyID.id = Self.overlaySpaceHotkeyID
        var newRef: EventHotKeyRef?
        let status = RegisterEventHotKey(
            UInt32(kVK_Space),
            0,
            hotkeyID,
            GetApplicationEventTarget(),
            0,
            &newRef
        )
        if status == noErr, let newRef {
            overlaySpaceHotkeyRef = newRef
        } else {
            overlaySpaceHotkeyRef = nil
            Diagnostics.log("app.overlay.spaceHotkey.failed", ["status": status])
        }
    }
    private func unregisterOverlaySpaceHotkey() {
        if let overlaySpaceHotkeyRef {
            UnregisterEventHotKey(overlaySpaceHotkeyRef)
            self.overlaySpaceHotkeyRef = nil
        }
    }
    // MARK: - Preferences
    /// Hide overlay when any other window becomes key (catches Cmd+, via SwiftUI Settings).
@@ -1409,6 +1531,9 @@
            forContentRect: NSRect(origin: .zero, size: settingsSize)
        ).size
        window.identifier = NSUserInterfaceItemIdentifier("TagLauncherPreferencesWindow")
        window.isRestorable = false
        window.restorationClass = nil
        _ = window.setFrameAutosaveName("")
        window.contentMinSize = settingsSize
        window.contentMaxSize = settingsSize
        window.minSize = settingsFrameSize
@@ -1441,6 +1566,7 @@
        window.makeKeyAndOrderFront(nil)
        window.orderFrontRegardless()
        settingsWindow = window
        refreshOverlaySpaceHotkeyRegistration()
        refreshLauncherChromeState(
            activate: !overlayAvoidsSpaceSwitch,
            avoidSpaceSwitch: overlayAvoidsSpaceSwitch
@@ -1545,6 +1671,7 @@
                activate: shouldRefocusOverlay && !self.overlayAvoidsSpaceSwitch,
                avoidSpaceSwitch: self.overlayAvoidsSpaceSwitch
            )
            self.refreshOverlaySpaceHotkeyRegistration()
            guard shouldRefocusOverlay else { return }
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.12) { [weak self] in
                self?.showOrFocusOverlay(preferredScreen: preferredScreen)
@@ -1559,7 +1686,9 @@
            object: nil,
            queue: .main
        ) { [weak self] notification in
            self?.isInEditMode = (notification.userInfo?["active"] as? Bool) ?? false
            guard let self else { return }
            self.isInEditMode = (notification.userInfo?["active"] as? Bool) ?? false
            self.refreshOverlaySpaceHotkeyRegistration()
        }
    }
@@ -1576,6 +1705,7 @@
                self.promoteOverlayToForegroundInput()
            }
            self.updateOverlayLevelForTextInput()
            self.refreshOverlaySpaceHotkeyRegistration()
        }
    }
@@ -1642,6 +1772,7 @@
                    self.hideOverlay(force: true, discardWindow: wasQuickSearchOnlyOverlay)
                }
            }
            self.refreshOverlaySpaceHotkeyRegistration()
        }
        NotificationCenter.default.addObserver(
@@ -1649,7 +1780,9 @@
            object: nil,
            queue: .main
        ) { [weak self] notification in
            self?.isModalInteractionActive = (notification.userInfo?["active"] as? Bool) ?? false
            guard let self else { return }
            self.isModalInteractionActive = (notification.userInfo?["active"] as? Bool) ?? false
            self.refreshOverlaySpaceHotkeyRegistration()
        }
        NotificationCenter.default.addObserver(
@@ -1757,6 +1890,7 @@
    }
    private func openPreferences(targetTab: String?) {
        explicitPreferencesOpenRequestedAt = Date()
        dismissQuickSearchIfNeeded()
        TagDatabase.flushPendingCategorySchemeBackupBatch()
        if overlayAvoidsSpaceSwitch {
@@ -1789,6 +1923,25 @@
        prepareSettingsWindow(window)
    }
    private func closeRestoredPreferencesWindowsDuringLaunch() {
        for delay in [0.25, 0.8, 1.6, 2.6] {
            DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
                self?.closeRestoredPreferencesWindowIfNeeded()
            }
        }
    }
    private func closeRestoredPreferencesWindowIfNeeded() {
        guard Date().timeIntervalSince(explicitPreferencesOpenRequestedAt) > 3.0 else { return }
        for window in NSApp.windows where isSettingsWindowCandidate(window) {
            detachSettingsWindow(window)
            window.close()
            if settingsWindow == window {
                settingsWindow = nil
            }
        }
    }
    private func requestPreferencesTabSelection(_ targetTab: String?) {
        guard let targetTab else { return }
        NotificationCenter.default.post(