Track the power profile through Quickshell instead of polling busctl (#15027)

* Track the power profile through Quickshell instead of polling busctl

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Recover the power profile when the daemon was down at shell start

Addresses Codex review: Quickshell never attaches its PowerProfiles listener if the daemon failed at startup. One-off reads on startup, power source changes and an IPC refresh from omarchy-powerprofiles-set cover that, still with no timer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Don't let a stale power profile read win over a change signal or drop a refresh

Addresses Codex re-review: a busctl read in flight could overwrite a newer PowerProfiles signal, and refreshes requested while a read ran were dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Test power profile transitions and stale reads as behavior, not source text

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
David Heinemeier HanssonandClaude Opus 5.5 authored and GitHub committed 2026-10-11 23:01:49 +09:00
1 parent 3c1f7b780f
commit 1b1cc5ecb5
5 files changed
+101 -25

No files matched your search

+9 -2
View File
@@ -147,10 +147,17 @@ assert(
)
assert(
batteryService.includes('property string activePowerProfile') &&
batteryService.includes('UPower.onBattery && activePowerProfile === "power-saver"') &&
batteryService.includes('powerSaverOnBattery: BatteryModel.isPowerSaverOnBattery(UPower.onBattery, activePowerProfile)') &&
/function onProfileChanged\(\) \{\s*root\.powerProfileSignals\+\+\s*root\.activePowerProfile = root\.profileName\(PowerProfiles\.profile\)/.test(batteryService) &&
batteryService.includes('root.activePowerProfile = BatteryModel.profileAfterRead(root.activePowerProfile, text, root.powerProfileReadSignals, root.powerProfileSignals)') &&
/if \(powerProfileReadProcess\.running\) \{\s*powerProfileReadPending = true/.test(batteryService) &&
batteryService.includes('if (root.powerProfileReadPending) Qt.callLater(root.refreshPowerProfile)') &&
batteryService.includes('case PowerProfile.PowerSaver: return "power-saver"') &&
batteryService.includes('"get-property", "net.hadess.PowerProfiles", "/net/hadess/PowerProfiles", "net.hadess.PowerProfiles", "ActiveProfile"') &&
!batteryService.includes('["powerprofilesctl"') &&
batteryService.includes('interval: 2000'),
!/Timer \{[^}]*refreshPowerProfile/.test(batteryService) &&
batteryService.includes('function refreshPowerProfile(): void { root.refreshPowerProfile() }') &&
fs.readFileSync(path.join(root, 'bin/omarchy-powerprofiles-set'), 'utf8').includes('omarchy-shell -q battery refreshPowerProfile'),
'the battery service tracks the active power-saver profile'
)
assert(