From b2a06ec5ebc86c0241e635782ae5a032ab5aad0a Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Thu, 02 Jul 2026 02:43:51 +0800
Subject: [PATCH] Prepare TagLauncher 8.3.2 App Store candidate

---
 src/Apptag/ContentView.swift |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/src/Apptag/ContentView.swift b/src/Apptag/ContentView.swift
index 3fede8e..9f2802e 100644
--- a/src/Apptag/ContentView.swift
+++ b/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 }

--
Gitblit v1.9.3