Files
illogical-impulse/dots/.config/quickshell/ii/services/Battery.qml
T
2025-11-01 20:50:39 +01:00

110 lines
3.9 KiB
QML

pragma Singleton
import qs.services
import qs.modules.common
import Quickshell
import Quickshell.Services.UPower
import QtQuick
import Quickshell.Io
Singleton {
id: root
property bool available: UPower.displayDevice.isLaptopBattery
property var chargeState: UPower.displayDevice.state
property bool isCharging: chargeState == UPowerDeviceState.Charging
property bool isPluggedIn: isCharging || chargeState == UPowerDeviceState.PendingCharge
property real percentage: UPower.displayDevice?.percentage ?? 1
readonly property bool allowAutomaticSuspend: Config.options.battery.automaticSuspend
readonly property bool soundEnabled: Config.options.sounds.battery
property bool isLow: available && (percentage <= Config.options.battery.low / 100)
property bool isCritical: available && (percentage <= Config.options.battery.critical / 100)
property bool isSuspending: available && (percentage <= Config.options.battery.suspend / 100)
property bool isFull: available && (percentage >= Config.options.battery.full / 100)
property bool isLowAndNotCharging: isLow && !isCharging
property bool isCriticalAndNotCharging: isCritical && !isCharging
property bool isSuspendingAndNotCharging: allowAutomaticSuspend && isSuspending && !isCharging
property bool isFullAndCharging: isFull && isCharging
property real energyRate: UPower.displayDevice.changeRate
property real timeToEmpty: UPower.displayDevice.timeToEmpty
property real timeToFull: UPower.displayDevice.timeToFull
property real health: 0
Process {
id: batteryProcess
running: Config.options.battery.showHealth
command: [
"bash",
`${FileUtils.trimFileProtocol(Directories.scriptPath)}/battery/calculate-health.sh`
]
stdout: StdioCollector {
onStreamFinished: {
const output = text.trim()
const value = Number(output)
if (!isNaN(value)) {
root.health = value
console.log("Battery health:", value)
} else {
console.warn("Battery script output invalid:", output)
}
}
}
}
onIsLowAndNotChargingChanged: {
if (!root.available || !isLowAndNotCharging) return;
Quickshell.execDetached([
"notify-send",
Translation.tr("Low battery"),
Translation.tr("Consider plugging in your device"),
"-u", "critical",
"-a", "Shell"
])
if (root.soundEnabled) Audio.playSystemSound("dialog-warning");
}
onIsCriticalAndNotChargingChanged: {
if (!root.available || !isCriticalAndNotCharging) return;
Quickshell.execDetached([
"notify-send",
Translation.tr("Critically low battery"),
Translation.tr("Please charge!\nAutomatic suspend triggers at %1%").arg(Config.options.battery.suspend),
"-u", "critical",
"-a", "Shell"
]);
if (root.soundEnabled) Audio.playSystemSound("suspend-error");
}
onIsSuspendingAndNotChargingChanged: {
if (root.available && isSuspendingAndNotCharging) {
Quickshell.execDetached(["bash", "-c", `systemctl suspend || loginctl suspend`]);
}
}
onIsFullAndChargingChanged: {
if (!root.available || !isFullAndCharging) return;
Quickshell.execDetached([
"notify-send",
Translation.tr("Battery full"),
Translation.tr("Please unplug the charger"),
"-a", "Shell"
]);
if (root.soundEnabled) Audio.playSystemSound("complete");
}
onIsPluggedInChanged: {
if (!root.available || !root.soundEnabled) return;
if (isPluggedIn) {
Audio.playSystemSound("power-plug")
} else {
Audio.playSystemSound("power-unplug")
}
}
}