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

+23 -1
View File
@@ -19,10 +19,32 @@ function shouldWarnLowBattery(device, onBattery, dischargingState, threshold, al
}
}
function parseActiveProfile(text) {
// busctl --json=short prints {"type":"s","data":"balanced"}; an empty or
// malformed reply (daemon not running) reads as no active profile.
try {
return String(JSON.parse(text).data || "").trim()
} catch (e) {
return ""
}
}
function profileAfterRead(current, replyText, signalsAtStart, signalsNow) {
// A change signal that arrived during the read is newer than its reply.
return signalsAtStart === signalsNow ? parseActiveProfile(replyText) : current
}
function isPowerSaverOnBattery(onBattery, profile) {
return !!onBattery && profile === "power-saver"
}
if (typeof module !== "undefined") {
module.exports = {
batteryPercentage: batteryPercentage,
isDischarging: isDischarging,
shouldWarnLowBattery: shouldWarnLowBattery
shouldWarnLowBattery: shouldWarnLowBattery,
parseActiveProfile: parseActiveProfile,
profileAfterRead: profileAfterRead,
isPowerSaverOnBattery: isPowerSaverOnBattery
}
}