Ariver
2026-06-25 ab59aa3a800139e2fe80f7e802dfada2258ab0f6
src/Apptag/ApptagApp.swift
@@ -342,11 +342,53 @@
        }
    }
    private func foregroundWindowForActivationPolicyRestore() -> NSWindow? {
        if let settingsWindow, settingsWindow.isVisible {
            return settingsWindow
        }
        if let overlayWindow, overlayWindow.isVisible {
            return overlayWindow
        }
        return NSApp.keyWindow
    }
    private func setLauncherActivationPolicy(_ desiredPolicy: NSApplication.ActivationPolicy) {
        guard NSApp.activationPolicy() != desiredPolicy else { return }
        let restoreWindow = desiredPolicy == .accessory && NSApp.isActive
            ? foregroundWindowForActivationPolicyRestore()
            : nil
        // Deactivate before switching regular -> accessory; otherwise Dock can
        // keep a stale running tile until Dock itself restarts.
        if desiredPolicy == .accessory && NSApp.isActive {
            NSApp.deactivate()
        }
        NSApp.setActivationPolicy(desiredPolicy)
        guard desiredPolicy == .accessory,
              let restoreWindow,
              restoreWindow.isVisible
        else { return }
        DispatchQueue.main.async { [weak self, weak restoreWindow] in
            guard let self,
                  let restoreWindow,
                  restoreWindow.isVisible,
                  self.requiresForegroundOwnership
            else { return }
            NSApp.activate(ignoringOtherApps: true)
            restoreWindow.makeKeyAndOrderFront(nil)
            restoreWindow.orderFrontRegardless()
        }
    }
    private func beginLauncherForegroundOwnership(activate: Bool = true, keyWindow: NSWindow? = nil) {
        let showDock = UserDefaults.standard.bool(forKey: Self.showDockIconKey)
        let desiredPolicy: NSApplication.ActivationPolicy = showDock ? .regular : .accessory
        if NSApp.activationPolicy() != desiredPolicy {
            NSApp.setActivationPolicy(desiredPolicy)
            setLauncherActivationPolicy(desiredPolicy)
        }
        if activate, showDock {
            claimLauncherForeground(keyWindow: keyWindow)
@@ -363,7 +405,7 @@
        overlayGeneration expectedOverlayGeneration: Int? = nil
    ) {
        if NSApp.activationPolicy() != .regular {
            NSApp.setActivationPolicy(.regular)
            setLauncherActivationPolicy(.regular)
        }
        if isOverlayVisible && !NSApp.presentationOptions.contains(.hideDock) {
@@ -425,7 +467,7 @@
            ? .regular
            : (showDock ? .regular : .accessory))))
        if NSApp.activationPolicy() != desiredPolicy {
            NSApp.setActivationPolicy(desiredPolicy)
            setLauncherActivationPolicy(desiredPolicy)
        }
        let desiredPresentation: NSApplication.PresentationOptions = isOverlayVisible ? [.hideDock] : []
@@ -1625,9 +1667,13 @@
            forName: .tagLauncherOpenPreferencesRequested,
            object: nil,
            queue: .main
        ) { [weak self] _ in
            self?.openPreferences()
        ) { [weak self] notification in
            self?.openPreferences(targetTab: Self.preferencesTabTarget(from: notification))
        }
    }
    private static func preferencesTabTarget(from notification: Notification) -> String? {
        notification.userInfo?[SettingsTabTarget.userInfoKey] as? String
    }
    private func observeExternalActivationRequests() {
@@ -1649,6 +1695,10 @@
    }
    @objc private func openPreferences(_ sender: Any? = nil) {
        openPreferences(targetTab: nil)
    }
    private func openPreferences(targetTab: String?) {
        dismissQuickSearchIfNeeded()
        TagDatabase.flushPendingCategorySchemeBackupBatch()
        if overlayAvoidsSpaceSwitch {
@@ -1664,6 +1714,7 @@
        if let settingsWindow {
            prepareSettingsWindow(settingsWindow)
            requestPreferencesTabSelection(targetTab)
            return
        }
@@ -1674,12 +1725,21 @@
            defer: false
        )
        window.title = tr("menu.preferences").replacingOccurrences(of: "…", with: "")
        window.contentView = NSHostingView(rootView: PreferencesView())
        window.contentView = NSHostingView(rootView: PreferencesView(initialTabRawValue: targetTab))
        window.isReleasedWhenClosed = false
        settingsWindow = window
        prepareSettingsWindow(window)
    }
    private func requestPreferencesTabSelection(_ targetTab: String?) {
        guard let targetTab else { return }
        NotificationCenter.default.post(
            name: .tagLauncherPreferencesTabRequested,
            object: nil,
            userInfo: [SettingsTabTarget.userInfoKey: targetTab]
        )
    }
    private func dismissQuickSearchIfNeeded() {
        guard isQuickSearchOpen else { return }
        isQuickSearchOpen = false