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/AppDragCoordinator.swift | 51 ++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/Apptag/AppDragCoordinator.swift b/Apptag/AppDragCoordinator.swift
index e767f95..2dff55b 100644
--- a/Apptag/AppDragCoordinator.swift
+++ b/Apptag/AppDragCoordinator.swift
@@ -25,6 +25,7 @@
private var dragWindow: NSWindow?
private var dragImageSize: NSSize = .zero
private var activePayload = ""
+ private weak var hoveredTarget: AppDropTargetReceivingView?
private init() {}
@@ -129,15 +130,20 @@
CATransaction.setDisableActions(true)
dragLayer.position = contentPoint
CATransaction.commit()
+ updateHoverTarget(at: screenPoint)
return
}
- guard let dragWindow else { return }
+ guard let dragWindow else {
+ updateHoverTarget(at: screenPoint)
+ return
+ }
let origin = NSPoint(
x: screenPoint.x - dragImageSize.width / 2,
y: screenPoint.y - dragImageSize.height / 2
)
dragWindow.setFrameOrigin(origin)
+ updateHoverTarget(at: screenPoint)
}
func finishDrag(at screenPoint: NSPoint, copy: Bool) {
@@ -147,18 +153,7 @@
let source = parts.dropFirst().first ?? ""
pruneDeadTargets()
- let hitTarget = targets.values
- .compactMap { target -> (AppDropTargetReceivingView, CGFloat)? in
- guard let view = target.view,
- let frame = view.screenFrame(),
- frame.contains(screenPoint)
- else { return nil }
- return (view, frame.width * frame.height)
- }
- .sorted { $0.1 < $1.1 }
- .first?.0
-
- if let hitTarget {
+ if let hitTarget = dropTarget(at: screenPoint) {
hitTarget.performDrop(path: path, source: source, copy: copy)
return
}
@@ -191,6 +186,8 @@
}
private func endDragVisuals() {
+ hoveredTarget?.appDragHoverChanged(active: false)
+ hoveredTarget = nil
dragLayer?.removeFromSuperlayer()
dragLayer = nil
dragLayerHostView = nil
@@ -207,6 +204,29 @@
private func pruneDeadTargets() {
targets = targets.filter { $0.value.view != nil }
emptyTargets = emptyTargets.filter { $0.value.view != nil }
+ }
+
+ private func updateHoverTarget(at screenPoint: NSPoint) {
+ guard hasActiveDrag else { return }
+ pruneDeadTargets()
+ let nextTarget = dropTarget(at: screenPoint)
+ guard nextTarget !== hoveredTarget else { return }
+ hoveredTarget?.appDragHoverChanged(active: false)
+ nextTarget?.appDragHoverChanged(active: true)
+ hoveredTarget = nextTarget
+ }
+
+ private func dropTarget(at screenPoint: NSPoint) -> AppDropTargetReceivingView? {
+ targets.values
+ .compactMap { target -> (AppDropTargetReceivingView, CGFloat)? in
+ guard let view = target.view,
+ let frame = view.screenFrame(),
+ frame.contains(screenPoint)
+ else { return nil }
+ return (view, frame.width * frame.height)
+ }
+ .sorted { $0.1 < $1.1 }
+ .first?.0
}
private static func cgImage(from image: NSImage) -> CGImage? {
@@ -261,6 +281,7 @@
protocol AppDropTargetReceivingView: AnyObject {
func screenFrame() -> NSRect?
+ func appDragHoverChanged(active: Bool)
func performDrop(path: String, source: String, copy: Bool)
}
@@ -277,6 +298,10 @@
}
}
+extension AppDropTargetReceivingView {
+ func appDragHoverChanged(active: Bool) {}
+}
+
extension AppEmptyDropReceivingView where Self: NSView {
func screenFrame() -> NSRect? {
guard let window else { return nil }
--
Gitblit v1.9.3