features/adding_quickshell #6
@@ -116,6 +116,68 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// device.timeToFull/timeToEmpty are computed by Quickshell from
|
||||||
|
// energy/energyCapacity/changeRate — when upowerd's EnergyFull glitches
|
||||||
|
// to 0 (the same daemon flake HEALTH routes around above), that formula
|
||||||
|
// divides by a bogus capacity and comes out negative rather than a
|
||||||
|
// real estimate (confirmed live: timeToFull sat at -3751 while `upower
|
||||||
|
// -i` itself still reported a normal 26.7 minutes). This recomputes
|
||||||
|
// the same estimate straight from sysfs as a fallback, only used when
|
||||||
|
// Quickshell's own value isn't positive. Unlike cycle_count/design
|
||||||
|
// capacity above, energy_now and power_now change continuously while
|
||||||
|
// (dis)charging, so this polls on a timer instead of reading once.
|
||||||
|
property real sysfsEnergyNowWh: -1
|
||||||
|
property real sysfsPowerNowW: -1
|
||||||
|
|
||||||
|
readonly property real fallbackTimeToFullSeconds: (root.sysfsPowerNowW > 0 && root.energyFullWh > 0 && root.sysfsEnergyNowWh >= 0)
|
||||||
|
? Math.max(0, (root.energyFullWh - root.sysfsEnergyNowWh) / root.sysfsPowerNowW * 3600) : -1
|
||||||
|
readonly property real fallbackTimeToEmptySeconds: (root.sysfsPowerNowW > 0 && root.sysfsEnergyNowWh > 0)
|
||||||
|
? (root.sysfsEnergyNowWh / root.sysfsPowerNowW * 3600) : -1
|
||||||
|
|
||||||
|
// Prefers upowerd's own live estimate when it's sane; only falls back
|
||||||
|
// to the sysfs-computed one when upowerd's has gone zero/negative.
|
||||||
|
readonly property real timeRemainingSeconds: {
|
||||||
|
const primary = root.onBattery ? root.device.timeToEmpty : root.device.timeToFull
|
||||||
|
if (primary > 0) return primary
|
||||||
|
return root.onBattery ? root.fallbackTimeToEmptySeconds : root.fallbackTimeToFullSeconds
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: sysfsRateTimer
|
||||||
|
interval: 15000
|
||||||
|
repeat: true
|
||||||
|
running: root.batteryPresent
|
||||||
|
triggeredOnStart: true
|
||||||
|
onTriggered: {
|
||||||
|
if (!sysfsEnergyNowProc.running) sysfsEnergyNowProc.running = true
|
||||||
|
if (!sysfsPowerNowProc.running) sysfsPowerNowProc.running = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: sysfsEnergyNowProc
|
||||||
|
command: ["sh", "-c", "cat \"$(ls -d /sys/class/power_supply/BAT* 2>/dev/null | head -n1)/energy_now\" 2>/dev/null"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
id: sysfsEnergyNowCollector
|
||||||
|
onStreamFinished: {
|
||||||
|
const n = parseFloat(sysfsEnergyNowCollector.text.trim())
|
||||||
|
root.sysfsEnergyNowWh = (isNaN(n) || n < 0) ? -1 : (n / 1000000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: sysfsPowerNowProc
|
||||||
|
command: ["sh", "-c", "cat \"$(ls -d /sys/class/power_supply/BAT* 2>/dev/null | head -n1)/power_now\" 2>/dev/null"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
id: sysfsPowerNowCollector
|
||||||
|
onStreamFinished: {
|
||||||
|
const n = parseFloat(sysfsPowerNowCollector.text.trim())
|
||||||
|
root.sysfsPowerNowW = (isNaN(n) || n <= 0) ? -1 : (n / 1000000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Raw UPower state string (Charging/Discharging/PendingCharge/…) — more
|
// Raw UPower state string (Charging/Discharging/PendingCharge/…) — more
|
||||||
// granular than modeLabel below, which collapses those down to the
|
// granular than modeLabel below, which collapses those down to the
|
||||||
// three phrases the hero text and STATE row show.
|
// three phrases the hero text and STATE row show.
|
||||||
@@ -176,9 +238,7 @@ Item {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: root.onBattery ? "TIME LEFT" : "TIME TO FULL",
|
label: root.onBattery ? "TIME LEFT" : "TIME TO FULL",
|
||||||
value: root.batteryPresent
|
value: root.batteryPresent ? root.formatDuration(root.timeRemainingSeconds) : "—"
|
||||||
? root.formatDuration(root.onBattery ? root.device.timeToEmpty : root.device.timeToFull)
|
|
||||||
: "—"
|
|
||||||
},
|
},
|
||||||
{ label: "STATUS", value: root.rawStateLabel },
|
{ label: "STATUS", value: root.rawStateLabel },
|
||||||
{ label: "CYCLES", value: root.cycleCount > 0 ? String(root.cycleCount) : "—" }
|
{ label: "CYCLES", value: root.cycleCount > 0 ? String(root.cycleCount) : "—" }
|
||||||
|
|||||||
Reference in New Issue
Block a user