From 00d66fcdb928754e5a8c69a3b4ccab7832af5b54 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Mon, 18 May 2026 20:12:20 +0800
Subject: [PATCH] Stabilize menu bar item identity for Thaw
---
Apptag/AppGridItem.swift | 46 ++++++++++++++++++++++++++++++++++++++++------
1 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/Apptag/AppGridItem.swift b/Apptag/AppGridItem.swift
index 9848d88..22c204c 100644
--- a/Apptag/AppGridItem.swift
+++ b/Apptag/AppGridItem.swift
@@ -12,9 +12,11 @@
var onDragModeChange: ((Bool) -> Void)? = nil
var onBubbleHover: ((AppInfo, CGRect, Bool) -> Void)? = nil
var onEditNote: ((AppInfo, CGRect) -> Void)? = nil
+ var bubbleDisabled: Bool = false
+ var itemID: String
+ @Binding var hoveredAppItemID: String?
let onSelect: () -> Void
- @State private var isHovered = false
@State private var wiggle = false
@State private var interactionFrame: CGRect = .zero
@AppStorage("showUncommonAppBubbles") private var showUncommonAppBubbles = AppDefaults.showUncommonAppBubbles
@@ -35,6 +37,7 @@
private var iconSlotSize: CGFloat { iconSize * Self.hoverScale }
private var labelWidth: CGFloat { iconSize + 20 }
private var labelHeight: CGFloat { Self.labelHeight }
+ private var isHovered: Bool { hoveredAppItemID == itemID }
var body: some View {
VStack(spacing: 6) {
@@ -62,7 +65,7 @@
.lineLimit(1)
.truncationMode(.tail)
.frame(width: labelWidth, height: labelHeight)
- .opacity(showName ? 1 : (isHovered ? 0.85 : 0))
+ .opacity(showName ? 1 : (shouldShowHoverName ? 0.85 : 0))
}
.padding(.vertical, 8)
.padding(.horizontal, 4)
@@ -70,12 +73,20 @@
.background(
AppGridItemHoverTracker { hovering, frame in
interactionFrame = frame
- setHoverState(hovering)
+ if bubbleDisabled || dragModeActive {
+ setHoverState(false)
+ onBubbleHover?(app, frame, false)
+ return
+ }
if hovering {
+ setHoverState(true)
guard shouldShowAppBubble else { return }
onBubbleHover?(app, frame, hovering)
- } else {
+ } else if isHovered {
+ setHoverState(false)
onBubbleHover?(app, frame, hovering)
+ } else {
+ setHoverState(false)
}
}
)
@@ -94,6 +105,22 @@
)
.onChange(of: dragModeActive) { _, active in
wiggle = active
+ if active {
+ setHoverState(false)
+ onBubbleHover?(app, interactionFrame, false)
+ }
+ }
+ .onChange(of: bubbleDisabled) { _, disabled in
+ if disabled {
+ setHoverState(false)
+ onBubbleHover?(app, interactionFrame, false)
+ }
+ }
+ .onDisappear {
+ if hoveredAppItemID == itemID {
+ hoveredAppItemID = nil
+ onBubbleHover?(app, interactionFrame, false)
+ }
}
}
@@ -101,10 +128,17 @@
!showUncommonAppBubbles || app.isUncommon
}
+ private var shouldShowHoverName: Bool {
+ !showName && !shouldShowAppBubble && isHovered
+ }
+
private func setHoverState(_ hovering: Bool) {
- guard isHovered != hovering else { return }
withAnimation(hovering ? Self.hoverInAnimation : Self.hoverOutAnimation) {
- isHovered = hovering
+ if hovering {
+ hoveredAppItemID = itemID
+ } else if hoveredAppItemID == itemID {
+ hoveredAppItemID = nil
+ }
}
}
}
--
Gitblit v1.9.3