Skip to content

Commit b2d5129

Browse files
committed
fix: skip unchanged quota indicator constraints
1 parent de55f48 commit b2d5129

3 files changed

Lines changed: 59 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Fixed
66
- Menu bar: defer merged-menu close rebuilds and cache repeated menu-card height measurements so dismissing or rapidly switching the merged dropdown avoids rebuilding SwiftUI-backed cards on the main thread (#1274, #1286). Thanks @hhh2210!
77
- Menu bar: observe a compact icon-state signature so merged status icons no longer redraw for provider snapshot changes that cannot affect the visible icon (#1297). Thanks @hhh2210!
8+
- Menu bar: keep provider-switcher quota bars from replacing Auto Layout constraints when the visible ratio is unchanged, making tab switches responsive with many providers enabled (#1303, #1315). Thanks @juanjoseluisgarcia!
89

910
## 0.32.4 — 2026-06-02
1011

Sources/CodexBar/StatusItemController+SwitcherViews.swift

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -613,11 +613,14 @@ final class ProviderSwitcherView: NSView {
613613
let key = ObjectIdentifier(button)
614614
if let remaining {
615615
if var indicator = self.quotaIndicators[key] {
616-
Self.updateQuotaIndicatorFill(
617-
indicator: &indicator,
618-
remainingPercent: remaining,
619-
selection: segment.selection)
620-
self.quotaIndicators[key] = indicator
616+
let newRatio = Self.quotaIndicatorRatio(remainingPercent: remaining)
617+
if newRatio != indicator.fillRatio {
618+
Self.updateQuotaIndicatorFill(
619+
indicator: &indicator,
620+
remainingPercent: remaining,
621+
selection: segment.selection)
622+
self.quotaIndicators[key] = indicator
623+
}
621624
} else {
622625
self.addQuotaIndicator(to: button, selection: segment.selection, remainingPercent: remaining)
623626
}
@@ -691,6 +694,12 @@ final class ProviderSwitcherView: NSView {
691694
self.quotaIndicators[ObjectIdentifier(button)]?.fill.frame
692695
}
693696
}
697+
698+
func _test_quotaIndicatorConstraintIdentifiers() -> [ObjectIdentifier] {
699+
self.buttons.compactMap { button in
700+
self.quotaIndicators[ObjectIdentifier(button)].map { ObjectIdentifier($0.fillWidthConstraint) }
701+
}
702+
}
694703
#endif
695704

696705
private func isLightMode() -> Bool {

Tests/CodexBarTests/StatusMenuSwitcherRefreshTests.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,50 @@ struct StatusMenuSwitcherRefreshTests {
7373
#expect(Self.switcherButtons(in: menu).first { $0.tag == nextProviderButton.tag }?.state == .on)
7474
}
7575

76+
@Test
77+
func `tab switch does not replace quota indicator constraints`() {
78+
let switcher = ProviderSwitcherView(
79+
providers: [.codex, .claude],
80+
selected: .provider(.codex),
81+
includesOverview: false,
82+
width: 310,
83+
showsIcons: false,
84+
iconProvider: { _ in NSImage() },
85+
weeklyRemainingProvider: { _ in 75.0 },
86+
onSelect: { _ in })
87+
88+
let initialConstraints = switcher._test_quotaIndicatorConstraintIdentifiers()
89+
#expect(initialConstraints.count == 2, "both providers should have quota indicators")
90+
91+
switcher.updateQuotaIndicators()
92+
93+
let afterFirstCall = switcher._test_quotaIndicatorConstraintIdentifiers()
94+
#expect(afterFirstCall == initialConstraints, "same ratio: constraints must not be replaced")
95+
}
96+
97+
@Test
98+
func `quota indicator constraints are replaced when ratio changes`() {
99+
var currentRemaining = 75.0
100+
let switcher = ProviderSwitcherView(
101+
providers: [.codex, .claude],
102+
selected: .provider(.codex),
103+
includesOverview: false,
104+
width: 310,
105+
showsIcons: false,
106+
iconProvider: { _ in NSImage() },
107+
weeklyRemainingProvider: { _ in currentRemaining },
108+
onSelect: { _ in })
109+
110+
let initialConstraints = switcher._test_quotaIndicatorConstraintIdentifiers()
111+
#expect(initialConstraints.count == 2)
112+
113+
currentRemaining = 40.0
114+
switcher.updateQuotaIndicators()
115+
116+
let afterDataChange = switcher._test_quotaIndicatorConstraintIdentifiers()
117+
#expect(afterDataChange != initialConstraints, "changed ratio: constraints should be replaced")
118+
}
119+
76120
private static func makeSettings() -> SettingsStore {
77121
let suite = "StatusMenuSwitcherRefreshTests-\(UUID().uuidString)"
78122
let defaults = UserDefaults(suiteName: suite)!

0 commit comments

Comments
 (0)