Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/CodexBar/StatusItemController+Menu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ extension StatusItemController {
if !isPersistentMenu {
self.menuProviders.removeValue(forKey: key)
self.menuVersions.removeValue(forKey: key)
} else if self.menuNeedsRefresh(menu) {
} else if Self.isClosedMenuPreparationEnabled, self.menuNeedsRefresh(menu) {
self.rebuildClosedMenuIfNeeded(menu)
}
self.parentMenuRebuildsDeferredDuringTracking.remove(key)
Expand Down
20 changes: 20 additions & 0 deletions Sources/CodexBar/StatusItemController+MenuTracking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,27 @@ import CodexBarCore

extension StatusItemController {
private static let defaultClosedMenuPreparationDelay: Duration = .milliseconds(350)
private static let defaultClosedMenuPreparationEnabled = false // Avoid idle SwiftUI layout work.

#if DEBUG
private static var closedMenuPreparationDelayForTesting: Duration = defaultClosedMenuPreparationDelay
private static var closedMenuPreparationEnabledForTesting = defaultClosedMenuPreparationEnabled

static func setClosedMenuPreparationDelayForTesting(_ delay: Duration) {
self.closedMenuPreparationDelayForTesting = delay
}

static func resetClosedMenuPreparationDelayForTesting() {
self.closedMenuPreparationDelayForTesting = self.defaultClosedMenuPreparationDelay
}

static func setClosedMenuPreparationEnabledForTesting(_ enabled: Bool) {
self.closedMenuPreparationEnabledForTesting = enabled
}

static func resetClosedMenuPreparationEnabledForTesting() {
self.closedMenuPreparationEnabledForTesting = self.defaultClosedMenuPreparationEnabled
}
#endif

private static var closedMenuPreparationDelay: Duration {
Expand All @@ -23,6 +34,14 @@ extension StatusItemController {
#endif
}

static var isClosedMenuPreparationEnabled: Bool {
#if DEBUG
closedMenuPreparationEnabledForTesting
#else
defaultClosedMenuPreparationEnabled
#endif
}

func invalidateMenus(
refreshOpenMenus: Bool = false,
deferOpenParentMenuRebuild: Bool = false,
Expand All @@ -49,6 +68,7 @@ extension StatusItemController {

func prepareAttachedClosedMenusIfNeeded() {
guard self.isMenuRefreshEnabled else { return }
guard Self.isClosedMenuPreparationEnabled else { return }
guard self.openMenus.isEmpty else { return }
guard !self.isMenuDataRefreshInFlight else { return }
for menu in self.attachedMenusForClosedPreparation() {
Expand Down
2 changes: 1 addition & 1 deletion Tests/CodexBarTests/ProviderSettingsDescriptorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct ProviderSettingsDescriptorTests {
}

@Test
func `codex exposes open AI web extras toggle as default off opt in`() throws {
func `codex exposes open AI web extras toggle as default off with battery saver off`() throws {
let fixture = try self.makeSettingsFixture(suite: "ProviderSettingsDescriptorTests-codex-openai-toggle")
let context = fixture.settingsContext(provider: .codex)

Expand Down
6 changes: 3 additions & 3 deletions Tests/CodexBarTests/SettingsStoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1000,11 +1000,11 @@ struct SettingsStoreTests {

#expect(store.openAIWebBatterySaverEnabled == false)

store.openAIWebBatterySaverEnabled = false
#expect(defaults.bool(forKey: "openAIWebBatterySaverEnabled") == false)
store.openAIWebBatterySaverEnabled = true
#expect(defaults.bool(forKey: "openAIWebBatterySaverEnabled") == true)

store.openAIWebAccessEnabled = true
#expect(store.openAIWebBatterySaverEnabled == false)
#expect(store.openAIWebBatterySaverEnabled == true)
}

@Test
Expand Down
14 changes: 12 additions & 2 deletions Tests/CodexBarTests/StatusMenuOpenRefreshTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ extension StatusMenuTests {
}

@Test
func `closed attached menu is prepared before next open after invalidation`() async {
func `closed attached menu stays stale after invalidation until next open`() async {
self.disableMenuCardsForTesting()
let settings = self.makeSettings()
settings.statusChecksEnabled = false
Expand Down Expand Up @@ -200,11 +200,17 @@ extension StatusMenuTests {
let openedVersion = controller.menuVersions[key]

controller.invalidateMenus()
for _ in 0..<40 where controller.menuVersions[key] == openedVersion {
for _ in 0..<40 {
await Task.yield()
}

#expect(controller.openMenus.isEmpty)
#expect(controller.closedMenuRebuildTasks[key] == nil)
#expect(controller.menuVersions[key] == openedVersion)

controller.menuWillOpen(menu)
defer { controller.menuDidClose(menu) }

#expect(controller.menuVersions[key] == controller.menuContentVersion)
}

Expand All @@ -228,6 +234,8 @@ extension StatusMenuTests {
defer { controller.releaseStatusItemsForTesting() }
StatusItemController.setClosedMenuPreparationDelayForTesting(.zero)
defer { StatusItemController.resetClosedMenuPreparationDelayForTesting() }
StatusItemController.setClosedMenuPreparationEnabledForTesting(true)
defer { StatusItemController.resetClosedMenuPreparationEnabledForTesting() }

controller.menuRefreshEnabledOverrideForTesting = true
let menu = controller.makeMenu()
Expand Down Expand Up @@ -261,6 +269,8 @@ extension StatusMenuTests {
func `closed attached menu preparation waits for token refresh to finish`() async {
StatusItemController.setClosedMenuPreparationDelayForTesting(.zero)
defer { StatusItemController.resetClosedMenuPreparationDelayForTesting() }
StatusItemController.setClosedMenuPreparationEnabledForTesting(true)
defer { StatusItemController.resetClosedMenuPreparationEnabledForTesting() }

self.disableMenuCardsForTesting()
let settings = self.makeSettings()
Expand Down