Ariver
2026-07-02 b2a06ec5ebc86c0241e635782ae5a032ab5aad0a
src/Apptag/ContentView.swift
@@ -456,6 +456,7 @@
    @State private var quickSearchOpenedAt: Date? = nil
    @State private var quickSearchErrorMessage: String? = nil
    @State private var initialQuickSearchConsumed = false
    @State private var quickSearchCompositionActive = false
    init(hideOverlay: @escaping () -> Void, initialQuickSearchSource: String? = nil) {
        self.hideOverlay = hideOverlay
@@ -588,6 +589,7 @@
            .onReceive(NotificationCenter.default.publisher(for: .tagLauncherOverlayDidHide), perform: handleOverlayDidHide)
            .onReceive(NotificationCenter.default.publisher(for: .tagLauncherQuickSearchRequested), perform: handleQuickSearchRequested)
            .onReceive(NotificationCenter.default.publisher(for: .tagLauncherQuickSearchDismissRequested), perform: handleQuickSearchDismissRequested)
            .onReceive(NotificationCenter.default.publisher(for: .tagLauncherQuickSearchCompositionChanged), perform: handleQuickSearchCompositionChanged)
            .onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification), perform: handleApplicationDidBecomeActive)
            .onReceive(NotificationCenter.default.publisher(for: .tagLauncherDataDidChange), perform: handleDataDidChange)
            .onReceive(NotificationCenter.default.publisher(for: .appLanguageDidChange), perform: handleAppLanguageDidChange)
@@ -864,6 +866,7 @@
        quickSearchVisible = true
        quickSearchOpenedAt = Date()
        quickSearchQuery = ""
        quickSearchCompositionActive = false
        quickSearchManualSelection = false
        quickSearchErrorMessage = nil
        quickSearchFocusToken &+= 1
@@ -907,10 +910,14 @@
        if shouldIgnoreEarlyQuickSearchDismiss(from: dismissalSource) {
            return
        }
        if shouldIgnoreQuickSearchDismissDuringComposition(from: dismissalSource) {
            return
        }
        let shouldHideOverlay = quickSearchVisible && quickSearchCloseHidesOverlay && hideOverlayIfNeeded
        guard quickSearchVisible else { return }
        quickSearchVisible = false
        quickSearchOpenedAt = nil
        quickSearchCompositionActive = false
        quickSearchQuery = ""
        quickSearchResults = []
        quickSearchSelectedID = nil
@@ -946,6 +953,16 @@
            "source": source,
            "age": String(format: "%.3f", age),
            "gracePeriod": String(format: "%.2f", gracePeriod)
        ])
        return true
    }
    private func shouldIgnoreQuickSearchDismissDuringComposition(from source: String?) -> Bool {
        guard quickSearchCompositionActive,
              source == QuickSearchDismissSource.mouse || source == QuickSearchDismissSource.backdrop
        else { return false }
        Diagnostics.log("content.quickSearch.ignoredCompositionDismiss", [
            "source": source
        ])
        return true
    }
@@ -2441,6 +2458,14 @@
        closeQuickSearch(dismissalSource: source)
    }
    private func handleQuickSearchCompositionChanged(_ notification: Notification) {
        guard quickSearchVisible else {
            quickSearchCompositionActive = false
            return
        }
        quickSearchCompositionActive = (notification.userInfo?["active"] as? Bool) ?? false
    }
    private func handleApplicationDidBecomeActive(_ notification: Notification) {
        _ = notification
        guard allApps.isEmpty, !refreshInProgress else { return }