From 56993d3c00152ab387e399d80d42a9cb7177114e Mon Sep 17 00:00:00 2001 From: LemmyCook Date: Sat, 6 Sep 2025 18:16:59 -0400 Subject: [PATCH] Battery: Minimal BatteryService which only serve an appropriate icon. Trying different icons rotated 90 degrees to the left. --- Modules/Bar/Widgets/Battery.qml | 49 +++++++------------------ Modules/LockScreen/LockScreen.qml | 61 ++++++++++--------------------- Services/BatteryService.qml | 49 +++++++++++++++++++++++++ Widgets/NPill.qml | 3 ++ 4 files changed, 85 insertions(+), 77 deletions(-) create mode 100644 Services/BatteryService.qml diff --git a/Modules/Bar/Widgets/Battery.qml b/Modules/Bar/Widgets/Battery.qml index 22d8602..b4654fe 100644 --- a/Modules/Bar/Widgets/Battery.qml +++ b/Modules/Bar/Widgets/Battery.qml @@ -65,40 +65,17 @@ Item { // Test mode property bool testMode: false - property int testPercent: 20 - property bool testCharging: false + property int testPercent: 50 + property bool testCharging: true property var battery: UPower.displayDevice property bool isReady: testMode ? true : (battery && battery.ready && battery.isLaptopBattery && battery.isPresent) property real percent: testMode ? testPercent : (isReady ? (battery.percentage * 100) : 0) property bool charging: testMode ? testCharging : (isReady ? battery.state === UPowerDeviceState.Charging : false) - // Choose icon based on charge and charging state - function batteryIcon() { - if (!isReady || !battery.isLaptopBattery) - return "battery_android_alert" - if (charging) - return "battery_android_bolt" - if (percent >= 95) - return "battery_android_full" - // Hardcoded battery symbols - if (percent >= 85) - return "battery_android_6" - if (percent >= 70) - return "battery_android_5" - if (percent >= 55) - return "battery_android_4" - if (percent >= 40) - return "battery_android_3" - if (percent >= 25) - return "battery_android_2" - if (percent >= 10) - return "battery_android_1" - if (percent >= 0) - return "battery_android_0" - } - rightOpen: BarWidgetRegistry.getNPillDirection(root) - icon: batteryIcon() + icon: testMode ? BatteryService.getIcon(testPercent, testCharging, true) : BatteryService.getIcon(percent, + charging, isReady) + iconRotation: -90 text: ((isReady && battery.isLaptopBattery) || testMode) ? Math.round(percent) + "%" : "-" textColor: charging ? Color.mPrimary : Color.mOnSurface iconCircleColor: Color.mPrimary @@ -109,30 +86,30 @@ Item { tooltipText: { let lines = [] if (testMode) { - lines.push("Time left: " + Time.formatVagueHumanReadableDuration(12345)) + lines.push(`Time left: ${Time.formatVagueHumanReadableDuration(12345)}.`) return lines.join("\n") } if (!isReady || !battery.isLaptopBattery) { - return "No battery detected" + return "No battery detected." } if (battery.timeToEmpty > 0) { - lines.push("Time left: " + Time.formatVagueHumanReadableDuration(battery.timeToEmpty)) + lines.push(`Time left: ${Time.formatVagueHumanReadableDuration(battery.timeToEmpty)}.`) } if (battery.timeToFull > 0) { - lines.push("Time until full: " + Time.formatVagueHumanReadableDuration(battery.timeToFull)) + lines.push(`Time until full: ${Time.formatVagueHumanReadableDuration(battery.timeToFull)}.`) } if (battery.changeRate !== undefined) { const rate = battery.changeRate if (rate > 0) { - lines.push(charging ? "Charging rate: " + rate.toFixed(2) + " W" : "Discharging rate: " + rate.toFixed( - 2) + " W") + lines.push(charging ? "Charging rate: " + rate.toFixed(2) + " W." : "Discharging rate: " + rate.toFixed( + 2) + " W.") } else if (rate < 0) { - lines.push("Discharging rate: " + Math.abs(rate).toFixed(2) + " W") + lines.push("Discharging rate: " + Math.abs(rate).toFixed(2) + " W.") } else { lines.push("Estimating...") } } else { - lines.push(charging ? "Charging" : "Discharging") + lines.push(charging ? "Charging." : "Discharging.") } if (battery.healthPercentage !== undefined && battery.healthPercentage > 0) { lines.push("Health: " + Math.round(battery.healthPercentage) + "%") diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 3382b69..25b69b1 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -58,29 +58,6 @@ Loader { property real percent: isReady ? (battery.percentage * 100) : 0 property bool charging: isReady ? battery.state === UPowerDeviceState.Charging : false property bool batteryVisible: isReady && percent > 0 - - function getIcon() { - if (!batteryVisible) - return "" - if (charging) - return "battery_android_bolt" - if (percent >= 95) - return "battery_android_full" - if (percent >= 85) - return "battery_android_6" - if (percent >= 70) - return "battery_android_5" - if (percent >= 55) - return "battery_android_4" - if (percent >= 40) - return "battery_android_3" - if (percent >= 25) - return "battery_android_2" - if (percent >= 10) - return "battery_android_1" - if (percent >= 0) - return "battery_android_0" - } } Item { @@ -420,7 +397,7 @@ Loader { anchors.bottomMargin: Style.marginM * scaling anchors.leftMargin: Style.marginL * scaling anchors.rightMargin: Style.marginL * scaling - spacing: Style.marginM * scaling + spacing: Style.marginL * scaling NText { text: "SECURE TERMINAL" @@ -431,23 +408,6 @@ Loader { Layout.fillWidth: true } - RowLayout { - spacing: Style.marginS * scaling - visible: batteryIndicator.batteryVisible - NIcon { - text: batteryIndicator.getIcon() - font.pointSize: Style.fontSizeM * scaling - color: batteryIndicator.charging ? Color.mPrimary : Color.mOnSurface - } - NText { - text: Math.round(batteryIndicator.percent) + "%" - color: Color.mOnSurface - font.family: Settings.data.ui.fontFixed - font.pointSize: Style.fontSizeM * scaling - font.weight: Style.fontWeightBold - } - } - RowLayout { spacing: Style.marginS * scaling NText { @@ -463,6 +423,25 @@ Loader { color: Color.mOnSurface } } + + RowLayout { + spacing: Style.marginS * scaling + visible: batteryIndicator.batteryVisible + NIcon { + text: BatteryService.getIcon(batteryIndicator.percent, batteryIndicator.charging, + batteryIndicator.isReady) + font.pointSize: Style.fontSizeM * scaling + color: batteryIndicator.charging ? Color.mPrimary : Color.mOnSurface + rotation: -90 + } + NText { + text: Math.round(batteryIndicator.percent) + "%" + color: Color.mOnSurface + font.family: Settings.data.ui.fontFixed + font.pointSize: Style.fontSizeM * scaling + font.weight: Style.fontWeightBold + } + } } } diff --git a/Services/BatteryService.qml b/Services/BatteryService.qml new file mode 100644 index 0000000..6ceb872 --- /dev/null +++ b/Services/BatteryService.qml @@ -0,0 +1,49 @@ +pragma Singleton + +import Quickshell +import Quickshell.Services.UPower + +Singleton { + id: root + + // Choose icon based on charge and charging state + function getIcon(percent, charging, isReady) { + if (!isReady) { + return "battery_error" + } + + if (charging) { + if (percent >= 95) + return "battery_full" + if (percent >= 85) + return "battery_charging_90" + if (percent >= 65) + return "battery_charging_80" + if (percent >= 55) + return "battery_charging_60" + if (percent >= 45) + return "battery_charging_50" + if (percent >= 25) + return "battery_charging_30" + if (percent >= 0) + return "battery_charging_20" + } else { + if (percent >= 95) + return "battery_full" + if (percent >= 85) + return "battery_6_bar" + if (percent >= 70) + return "battery_5_bar" + if (percent >= 55) + return "battery_4_bar" + if (percent >= 40) + return "battery_3_bar" + if (percent >= 25) + return "battery_2_bar" + if (percent >= 10) + return "battery_1_bar" + if (percent >= 0) + return "battery_0_bar" + } + } +} diff --git a/Widgets/NPill.qml b/Widgets/NPill.qml index 2432544..94719b3 100644 --- a/Widgets/NPill.qml +++ b/Widgets/NPill.qml @@ -14,6 +14,8 @@ Item { property color iconCircleColor: Color.mPrimary property color iconTextColor: Color.mSurface property color collapsedIconColor: Color.mOnSurface + + property real iconRotation: 0 property real sizeRatio: 0.8 property bool autoHide: false property bool forceOpen: false @@ -110,6 +112,7 @@ Item { NIcon { text: root.icon + rotation: root.iconRotation font.pointSize: Style.fontSizeM * scaling // When forced shown, use pill text color; otherwise accent color when hovered color: forceOpen ? textColor : (showPill ? iconTextColor : Color.mOnSurface)