From 01bab5422712299b49f656e6b4c42a3bf314f519 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Thu, 02 Jul 2026 11:02:42 +0800
Subject: [PATCH] Release 8.3.5 free tag order persistence

---
 src/Apptag/TagNavigationView.swift |   45 +++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/src/Apptag/TagNavigationView.swift b/src/Apptag/TagNavigationView.swift
index 449895d..551eaa1 100644
--- a/src/Apptag/TagNavigationView.swift
+++ b/src/Apptag/TagNavigationView.swift
@@ -5,6 +5,7 @@
     var id: String { name }
     let name: String
     let colorIndex: Int
+    let customColor: TagCustomColor?
 }
 
 struct TagNavigationView: NSViewRepresentable {
@@ -21,6 +22,7 @@
     let appDragModeActive: Bool
     let appDropTargetID: String?
     let onActivate: (String) -> Void
+    let onDoubleActivate: (String) -> Void
     let onHoverChange: (String, Bool) -> Void
     let canReorder: (String) -> Bool
     let canAcceptAppDrop: (String) -> Bool
@@ -41,6 +43,7 @@
             appDragModeActive: appDragModeActive,
             appDropTargetID: appDropTargetID,
             onActivate: onActivate,
+            onDoubleActivate: onDoubleActivate,
             onHoverChange: onHoverChange,
             canReorder: canReorder,
             canAcceptAppDrop: canAcceptAppDrop,
@@ -63,6 +66,7 @@
             appDragModeActive: appDragModeActive,
             appDropTargetID: appDropTargetID,
             onActivate: onActivate,
+            onDoubleActivate: onDoubleActivate,
             onHoverChange: onHoverChange,
             canReorder: canReorder,
             canAcceptAppDrop: canAcceptAppDrop,
@@ -100,6 +104,7 @@
         appDragModeActive: Bool,
         appDropTargetID: String?,
         onActivate: @escaping (String) -> Void,
+        onDoubleActivate: @escaping (String) -> Void,
         onHoverChange: @escaping (String, Bool) -> Void,
         canReorder: @escaping (String) -> Bool,
         canAcceptAppDrop: @escaping (String) -> Bool,
@@ -118,6 +123,7 @@
             appDragModeActive: appDragModeActive,
             appDropTargetID: appDropTargetID,
             onActivate: onActivate,
+            onDoubleActivate: onDoubleActivate,
             onHoverChange: onHoverChange,
             canReorder: canReorder,
             canAcceptAppDrop: canAcceptAppDrop,
@@ -170,6 +176,7 @@
     private var appDragModeActive = false
     private var appDropTargetID: String?
     private var onActivate: (String) -> Void = { _ in }
+    private var onDoubleActivate: (String) -> Void = { _ in }
     private var onHoverChange: (String, Bool) -> Void = { _, _ in }
     private var canReorder: (String) -> Bool = { _ in false }
     private var canAcceptAppDrop: (String) -> Bool = { _ in false }
@@ -190,6 +197,7 @@
         appDragModeActive: Bool,
         appDropTargetID: String?,
         onActivate: @escaping (String) -> Void,
+        onDoubleActivate: @escaping (String) -> Void,
         onHoverChange: @escaping (String, Bool) -> Void,
         canReorder: @escaping (String) -> Bool,
         canAcceptAppDrop: @escaping (String) -> Bool,
@@ -210,6 +218,7 @@
         self.appDragModeActive = appDragModeActive
         self.appDropTargetID = appDropTargetID
         self.onActivate = onActivate
+        self.onDoubleActivate = onDoubleActivate
         self.onHoverChange = onHoverChange
         self.canReorder = canReorder
         self.canAcceptAppDrop = canAcceptAppDrop
@@ -261,6 +270,7 @@
         buttons = items.map { item in
             let button = TagNavigationButton(item: item, orientation: orientation)
             button.onActivate = { [weak self] tagID in self?.onActivate(tagID) }
+            button.onDoubleActivate = { [weak self] tagID in self?.onDoubleActivate(tagID) }
             button.onHoverChange = { [weak self] tagID, active in self?.onHoverChange(tagID, active) }
             button.canReorder = { [weak self] tagID in self?.canReorder(tagID) ?? false }
             button.onReorderBegan = { [weak self] tagID in self?.onReorderBegan(tagID) }
@@ -348,6 +358,7 @@
 
 final class TagNavigationButton: NSButton, AppDropTargetReceivingView {
     var onActivate: (String) -> Void = { _ in }
+    var onDoubleActivate: (String) -> Void = { _ in }
     var onHoverChange: (String, Bool) -> Void = { _, _ in }
     var canReorder: (String) -> Bool = { _ in false }
     var onReorderBegan: (String) -> Void = { _ in }
@@ -392,7 +403,7 @@
     }
 
     required init?(coder: NSCoder) {
-        self.item = TagNavigationItem(name: "", colorIndex: 0)
+        self.item = TagNavigationItem(name: "", colorIndex: 0, customColor: nil)
         self.orientation = .horizontal
         super.init(coder: coder)
     }
@@ -475,6 +486,11 @@
     }
 
     override func mouseDown(with event: NSEvent) {
+        if event.clickCount >= 2 {
+            onDoubleActivate(item.id)
+            return
+        }
+
         guard canReorder(item.id) else {
             onActivate(item.id)
             return
@@ -482,16 +498,37 @@
 
         let start = Date()
         let longPressDuration: TimeInterval = 0.35
+        let maxTrackingDuration: TimeInterval = 8
         var reorderActive = false
         var finished = false
 
         while !finished {
+            guard let window,
+                  window.isVisible,
+                  NSApp.isActive,
+                  Date().timeIntervalSince(start) < maxTrackingDuration
+            else {
+                if reorderActive {
+                    onReorderEnded()
+                }
+                break
+            }
+
             if !reorderActive && Date().timeIntervalSince(start) >= longPressDuration {
                 reorderActive = true
                 onReorderBegan(item.id)
             }
 
-            let nextEvent = window?.nextEvent(
+            if NSEvent.pressedMouseButtons & (1 << 0) == 0 {
+                if reorderActive {
+                    onReorderEnded()
+                } else {
+                    onActivate(item.id)
+                }
+                break
+            }
+
+            let nextEvent = window.nextEvent(
                 matching: [.leftMouseDragged, .leftMouseUp],
                 until: Date().addingTimeInterval(0.04),
                 inMode: .eventTracking,
@@ -528,7 +565,7 @@
     }
 
     private func updateAppearance() {
-        let background = TagColor.nsColor(for: item.colorIndex)
+        let background = TagColor.nsColor(for: item.colorIndex, customColor: item.customColor)
         let dragScale: CGFloat = isDragging ? 1.04 : 1.0
         layer?.backgroundColor = background.cgColor
         layer?.cornerRadius = orientation == .horizontal ? 7 : 6
@@ -540,7 +577,7 @@
         layer?.setAffineTransform(CGAffineTransform(scaleX: dragScale, y: dragScale))
         alphaValue = dragModeActive ? (isDragging ? 1.0 : 0.62) : 1.0
 
-        let textColor: NSColor = (item.colorIndex == 0 || item.colorIndex == 5) ? .labelColor : .white
+        let textColor: NSColor = TagColor.prefersDarkText(for: background) ? .labelColor : .white
         let paragraph = NSMutableParagraphStyle()
         paragraph.alignment = alignment
         if orientation == .vertical {

--
Gitblit v1.9.3