mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-07-10 01:29:41 +00:00
Settings gains a Usage Refresh picker mirroring the quota cadence pattern. Auto keeps the adaptive default (30s active, battery and Low Power backoff); fixed cadences ignore power state but an open popover always gets the active 30s; Manual never auto-spawns, refreshing only on popover open, Refresh Now, and first launch (wake included: manual wakes run stuck-state cleanup without spawning). Stored in UserDefaults as CodeBurnMenubarRefreshSeconds (-1 auto, 0 manual, else seconds) and documented in the README with the defaults-write escape hatch. Refs #647
50 lines
2 KiB
Swift
50 lines
2 KiB
Swift
import Foundation
|
|
import IOKit.ps
|
|
|
|
/// Decides how often the background refresh loop may spawn CLI fetches. The
|
|
/// 30s timer keeps firing (cheap); this throttles the expensive part - each
|
|
/// fetch is a full Node process at 100%+ CPU for seconds (#647). With the
|
|
/// popover closed nobody is looking at anything but the status figure, so on
|
|
/// battery or in Low Power Mode the spawn cadence backs off. Opening the
|
|
/// popover always refreshes immediately via refreshPayloadForPopoverOpen, so
|
|
/// the backoff never shows a user stale data they are actually looking at.
|
|
enum RefreshCadence {
|
|
static let activeSeconds: TimeInterval = 30
|
|
static let batteryIdleSeconds: TimeInterval = 150
|
|
static let lowPowerIdleSeconds: TimeInterval = 300
|
|
|
|
/// nil means "never auto-spawn" (manual mode): usage refreshes only on
|
|
/// popover open, Refresh Now, and first launch.
|
|
static func interval(
|
|
mode: UsageRefreshCadence,
|
|
popoverOpen: Bool,
|
|
onBattery: Bool,
|
|
lowPowerMode: Bool
|
|
) -> TimeInterval? {
|
|
switch mode {
|
|
case .manual:
|
|
return nil
|
|
case .auto:
|
|
if popoverOpen { return activeSeconds }
|
|
if lowPowerMode { return lowPowerIdleSeconds }
|
|
if onBattery { return batteryIdleSeconds }
|
|
return activeSeconds
|
|
case .oneMinute, .fiveMinutes, .fifteenMinutes:
|
|
// A fixed user-chosen cadence, except an open popover always gets
|
|
// the active cadence: the user is looking at the numbers.
|
|
return popoverOpen
|
|
? min(activeSeconds, TimeInterval(mode.rawValue))
|
|
: TimeInterval(mode.rawValue)
|
|
}
|
|
}
|
|
}
|
|
|
|
enum PowerSource {
|
|
static func isOnBattery() -> Bool {
|
|
// Copy function -> retained; Get function -> borrowed (unretained).
|
|
guard let snapshot = IOPSCopyPowerSourcesInfo()?.takeRetainedValue(),
|
|
let type = IOPSGetProvidingPowerSourceType(snapshot)?.takeUnretainedValue() as String?
|
|
else { return false }
|
|
return type == kIOPMBatteryPowerKey
|
|
}
|
|
}
|