@@ -30,11 +30,21 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
3030 private let store = AppStore ( )
3131 let updateChecker = UpdateChecker ( )
3232 private var refreshTask : Task < Void , Never > ?
33+ /// Held for the lifetime of the app to opt out of App Nap and Automatic Termination.
34+ /// Without this the 15s refresh Task gets suspended whenever the user is interacting with
35+ /// another app, and the status bar label freezes until they click the menubar icon (which
36+ /// calls NSApp.activate and wakes the app back up).
37+ private var backgroundActivity : NSObjectProtocol ?
3338
3439 func applicationDidFinishLaunching( _ notification: Notification ) {
3540 // Menubar accessory -- no Dock icon, no app switcher entry.
3641 NSApp . setActivationPolicy ( . accessory)
3742
43+ backgroundActivity = ProcessInfo . processInfo. beginActivity (
44+ options: [ . userInitiated, . automaticTerminationDisabled, . suddenTerminationDisabled] ,
45+ reason: " CodeBurn menubar polls AI coding cost every 15 seconds while idle in the background. "
46+ )
47+
3848 restorePersistedCurrency ( )
3949 setupStatusItem ( )
4050 setupPopover ( )
@@ -158,6 +168,11 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
158168 attributes: [ . font: font, . foregroundColor: color]
159169 ) )
160170 button. attributedTitle = composed
171+ // Force immediate redraw. NSStatusItem sometimes defers the status bar paint for an
172+ // accessory app that is not foreground, so the label visually freezes until the user
173+ // opens the popover (which triggers NSApp.activate + a forced redraw cycle).
174+ button. needsDisplay = true
175+ button. display ( )
161176 }
162177
163178 // MARK: - Popover
0 commit comments