From 406c5898d103427193e589b4bbe615d0c739b2c5 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Tue, 02 Jun 2026 19:36:31 +0800
Subject: [PATCH] Prepare 7.8.9 tag navigation drop test package
---
Apptag/ContentView.swift | 75 ++++++++++++++++++++++++++++++++++++-
1 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/Apptag/ContentView.swift b/Apptag/ContentView.swift
index 9b6ce7c..f29d986 100644
--- a/Apptag/ContentView.swift
+++ b/Apptag/ContentView.swift
@@ -318,6 +318,7 @@
var appDragResetToken = 0
var bubbleDraftNote = ""
var tagNavigationHoveredGroupName: String? = nil
+ var tagNavigationAppDropTargetName: String? = nil
var tagNavigationLastHoverScrollID: String? = nil
var tagNavigationLastHoverScrollAt: Date? = nil
}
@@ -948,6 +949,7 @@
private func appKitTagNavigation(orientation: TagNavigationView.Orientation) -> some View {
let isHorizontal = orientation == .horizontal
+ let appDropTargetID = appGridInteraction.tagNavigationAppDropTargetName
return TagNavigationView(
items: tagLabels,
orientation: orientation,
@@ -956,6 +958,8 @@
: NSEdgeInsets(top: 12, left: 12, bottom: 12, right: 12),
dragModeActive: tagNavDragModeActive,
draggingItemID: tagNavDragItem,
+ appDragModeActive: appGridInteraction.appDragModeActive,
+ appDropTargetID: appDropTargetID,
onActivate: { tagID in
activateTagNavigation(tagID)
},
@@ -965,6 +969,9 @@
canReorder: { tagID in
canReorderTag(tagID)
},
+ canAcceptAppDrop: { tagID in
+ canAssignDroppedAppToTag(tagID)
+ },
onReorderBegan: { tagID in
beginTagNavReorder(tagID)
},
@@ -973,6 +980,12 @@
},
onReorderEnded: {
endTagNavReorder()
+ },
+ onAppDropHoverChange: { tagID, active in
+ handleTagNavigationAppDropHover(tagID, active: active)
+ },
+ onAppDrop: { path, source, targetTag, copy in
+ dropAppOnTagNavigation(path: path, sourceTag: source, targetTag: targetTag, copy: copy)
}
)
}
@@ -1903,6 +1916,13 @@
}
private func handleTagNavigationHover(_ id: String, active: Bool) {
+ if appGridInteraction.appDragModeActive {
+ if !active, appGridInteraction.tagNavigationHoveredGroupName == id {
+ appGridInteraction.tagNavigationHoveredGroupName = nil
+ }
+ return
+ }
+
guard active else {
if appGridInteraction.tagNavigationHoveredGroupName == id {
appGridInteraction.tagNavigationHoveredGroupName = nil
@@ -1913,6 +1933,24 @@
appGridInteraction.tagNavigationHoveredGroupName = id
fillColorlessContainer(id)
scrollToTagFromHover(id)
+ }
+
+ private func handleTagNavigationAppDropHover(_ id: String, active: Bool) {
+ guard appGridInteraction.appDragModeActive else {
+ if appGridInteraction.tagNavigationAppDropTargetName == id {
+ appGridInteraction.tagNavigationAppDropTargetName = nil
+ }
+ return
+ }
+
+ guard active, canAssignDroppedAppToTag(id) else {
+ if appGridInteraction.tagNavigationAppDropTargetName == id {
+ appGridInteraction.tagNavigationAppDropTargetName = nil
+ }
+ return
+ }
+
+ appGridInteraction.tagNavigationAppDropTargetName = id
}
private func scrollToTagFromHover(_ id: String) {
@@ -2050,6 +2088,22 @@
)
showDropRefresh()
refreshApps(forceLayoutRefresh: true)
+ }
+
+ private func dropAppOnTagNavigation(path: String, sourceTag: String, targetTag: String, copy: Bool) {
+ resetTransientDragState()
+ guard canAssignDroppedAppToTag(targetTag) else { return }
+ guard let app = allApps.first(where: { $0.path.path == path }) else { return }
+ guard !appHasTag(app, tagName: targetTag) else { return }
+ TagEditor.appendTags([targetTag], to: [path])
+ showDropRefresh()
+ refreshApps(forceLayoutRefresh: true)
+ }
+
+ private func canAssignDroppedAppToTag(_ tagName: String) -> Bool {
+ tagColors[tagName] != nil
+ && !isAppleBuiltInDropTarget(tagName)
+ && !isUncategorizedDropTarget(tagName)
}
private func dropAppOutsideGroup(path: String, sourceTag: String, copy: Bool) {
@@ -2263,12 +2317,17 @@
if active {
endTagNavReorder()
clearAppBubbleState()
+ appGridInteraction.tagNavigationAppDropTargetName = nil
}
appGridInteraction.appDragModeActive = active
+ if !active {
+ appGridInteraction.tagNavigationAppDropTargetName = nil
+ }
if active {
DispatchQueue.main.asyncAfter(deadline: .now() + 8) {
if appGridInteraction.appDragModeActive && !AppDragCoordinator.shared.hasActiveDrag {
appGridInteraction.appDragModeActive = false
+ appGridInteraction.tagNavigationAppDropTargetName = nil
}
}
}
@@ -2282,6 +2341,9 @@
AppDragCoordinator.shared.cancelDrag()
if appGridInteraction.appDragModeActive {
appGridInteraction.appDragModeActive = false
+ }
+ if appGridInteraction.tagNavigationAppDropTargetName != nil {
+ appGridInteraction.tagNavigationAppDropTargetName = nil
}
if hadAppDragState {
appGridInteraction.appDragResetToken &+= 1
@@ -2355,6 +2417,13 @@
) {
appGridInteraction.appDragModeActive = false
endTagNavReorder()
+ let closeQuickSearchAndOverlayBeforeOpening = closeQuickSearchOnSuccess
+ && closeOverlayOnSuccess
+ && (quickSearchCloseHidesOverlay || quickSearchOnlySession)
+ if closeQuickSearchAndOverlayBeforeOpening {
+ closeQuickSearch(hideOverlayIfNeeded: true)
+ hideOverlay()
+ }
let configuration = NSWorkspace.OpenConfiguration()
NSWorkspace.shared.openApplication(at: app.path, configuration: configuration) { _, error in
DispatchQueue.main.async {
@@ -2366,10 +2435,10 @@
DispatchQueue.global(qos: .utility).async {
TagEditor.recordLauncherOpen(for: app.path.path)
}
- if closeQuickSearchOnSuccess {
- closeQuickSearch(hideOverlayIfNeeded: false)
+ if closeQuickSearchOnSuccess && !closeQuickSearchAndOverlayBeforeOpening {
+ closeQuickSearch(hideOverlayIfNeeded: closeOverlayOnSuccess)
}
- if closeOverlayOnSuccess {
+ if closeOverlayOnSuccess && !closeQuickSearchAndOverlayBeforeOpening {
hideOverlay()
}
}
--
Gitblit v1.9.3