From 9d87dbed3f81d07a81b1484a1317d7f7c0258610 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Thu, 28 May 2026 19:58:24 +0800
Subject: [PATCH] Stabilize tag navigation hover highlighting
---
Apptag/TagNavigationView.swift | 32 +++++++++++++++++++++-----------
1 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/Apptag/TagNavigationView.swift b/Apptag/TagNavigationView.swift
index 95f7915..2736f53 100644
--- a/Apptag/TagNavigationView.swift
+++ b/Apptag/TagNavigationView.swift
@@ -17,7 +17,7 @@
let orientation: Orientation
let contentInsets: NSEdgeInsets
let onActivate: (String) -> Void
- let onHover: (String) -> Void
+ let onHoverChange: (String, Bool) -> Void
func makeNSView(context: Context) -> TagNavigationHostView {
let view = TagNavigationHostView()
@@ -26,7 +26,7 @@
orientation: orientation,
contentInsets: contentInsets,
onActivate: onActivate,
- onHover: onHover
+ onHoverChange: onHoverChange
)
return view
}
@@ -37,7 +37,7 @@
orientation: orientation,
contentInsets: contentInsets,
onActivate: onActivate,
- onHover: onHover
+ onHoverChange: onHoverChange
)
}
}
@@ -63,14 +63,14 @@
orientation: TagNavigationView.Orientation,
contentInsets: NSEdgeInsets,
onActivate: @escaping (String) -> Void,
- onHover: @escaping (String) -> Void
+ onHoverChange: @escaping (String, Bool) -> Void
) {
documentView.update(
items: items,
orientation: orientation,
contentInsets: contentInsets,
onActivate: onActivate,
- onHover: onHover
+ onHoverChange: onHoverChange
)
scrollView.hasHorizontalScroller = orientation == .horizontal
scrollView.hasVerticalScroller = orientation == .vertical
@@ -109,7 +109,7 @@
private var contentInsets = NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
private var buttons: [TagNavigationButton] = []
private var onActivate: (String) -> Void = { _ in }
- private var onHover: (String) -> Void = { _ in }
+ private var onHoverChange: (String, Bool) -> Void = { _, _ in }
override var isFlipped: Bool { true }
@@ -118,14 +118,14 @@
orientation: TagNavigationView.Orientation,
contentInsets: NSEdgeInsets,
onActivate: @escaping (String) -> Void,
- onHover: @escaping (String) -> Void
+ onHoverChange: @escaping (String, Bool) -> Void
) {
let needsRebuild = self.items != items || self.orientation != orientation
self.items = items
self.orientation = orientation
self.contentInsets = contentInsets
self.onActivate = onActivate
- self.onHover = onHover
+ self.onHoverChange = onHoverChange
if needsRebuild {
rebuildButtons()
@@ -170,7 +170,7 @@
buttons = items.map { item in
let button = TagNavigationButton(item: item, orientation: orientation)
button.onActivate = { [weak self] tagID in self?.onActivate(tagID) }
- button.onHover = { [weak self] tagID in self?.onHover(tagID) }
+ button.onHoverChange = { [weak self] tagID, active in self?.onHoverChange(tagID, active) }
addSubview(button)
return button
}
@@ -200,11 +200,12 @@
final class TagNavigationButton: NSButton {
var onActivate: (String) -> Void = { _ in }
- var onHover: (String) -> Void = { _ in }
+ var onHoverChange: (String, Bool) -> Void = { _, _ in }
private var item: TagNavigationItem
private var orientation: TagNavigationView.Orientation
private var trackingAreaRef: NSTrackingArea?
+ private var isMouseInside = false
var preferredSize: NSSize {
let font = NSFont.systemFont(ofSize: 13, weight: .medium)
@@ -262,7 +263,16 @@
override func mouseEntered(with event: NSEvent) {
super.mouseEntered(with: event)
- onHover(item.id)
+ guard !isMouseInside else { return }
+ isMouseInside = true
+ onHoverChange(item.id, true)
+ }
+
+ override func mouseExited(with event: NSEvent) {
+ super.mouseExited(with: event)
+ guard isMouseInside else { return }
+ isMouseInside = false
+ onHoverChange(item.id, false)
}
@objc private func performActivation() {
--
Gitblit v1.9.3