import QtQuick import Quickshell import Quickshell.Services.UPower import qs.Commons import qs.Widgets import qs.Modules.Bar.Extras import qs.Services.Hardware import qs.Services.UI Item { id: root property QtObject pluginApi: null readonly property QtObject pluginCore: pluginApi?.mainInstance property ShellScreen screen property string widgetId: "" property string section: "" property int sectionWidgetIndex: -1 property int sectionWidgetsCount: 0 // Battery state from BatteryService readonly property var selectedDevice: BatteryService.displayDevice readonly property bool isReady: BatteryService.isDeviceReady(selectedDevice) readonly property real percent: isReady ? BatteryService.getPercentage(selectedDevice) : -1 readonly property bool isCharging: isReady ? BatteryService.isCharging(selectedDevice) : false readonly property bool isPluggedIn: isReady ? BatteryService.isPluggedIn(selectedDevice) : false readonly property bool isLowBattery: isReady ? BatteryService.isLowBattery(selectedDevice) : false readonly property bool isCriticalBattery: isReady ? BatteryService.isCriticalBattery(selectedDevice) : false readonly property var tooltipContent: { let rows = []; if (isReady) { rows.push(["Battery", percent + "%"]); let timeText = BatteryService.getTimeRemainingText(selectedDevice); if (timeText) { const idx = timeText.indexOf(":"); if (idx >= 0) rows.push([timeText.substring(0, idx).trim(), timeText.substring(idx + 1).trim()]); else rows.push([timeText, ""]); } let rateText = BatteryService.getRateText(selectedDevice); if (rateText) { const idx = rateText.indexOf(":"); if (idx >= 0) rows.push([rateText.substring(0, idx).trim(), rateText.substring(idx + 1).trim()]); else rows.push([rateText, ""]); } } if (pluginCore) { if (rows.length > 0) rows.push(["---", "---"]); rows.push(["Charge limit", pluginCore.chargeLimit + "%"]); } return rows; } implicitWidth: pill.width implicitHeight: pill.height BarPill { id: pill screen: root.screen oppositeDirection: BarService.getPillDirection(root) forceClose: false icon: BatteryService.getIcon(root.percent, root.isCharging, root.isPluggedIn, root.isReady) text: root.isReady ? root.percent : "-" suffix: pluginCore && pluginCore.chargeLimit < 100 ? "% \u2193" + pluginCore.chargeLimit : "%" autoHide: false customBackgroundColor: root.isCharging ? Color.mPrimary : ((root.isLowBattery || root.isCriticalBattery) ? Color.mError : "transparent") customTextIconColor: root.isCharging ? Color.mOnPrimary : ((root.isLowBattery || root.isCriticalBattery) ? Color.mOnError : "transparent") tooltipText: root.tooltipContent onClicked: pluginCore?.toggle() onRightClicked: { PanelService.showContextMenu(contextMenu, pill, root.screen); } } NPopupContextMenu { id: contextMenu model: [ { "label": pluginCore && pluginCore.chargeLimit < 100 ? "Set charge limit to 100%" : "Set charge limit to 80%", "action": "toggle", "icon": "battery_saver", "enabled": true } ] onTriggered: action => { contextMenu.close(); PanelService.closeContextMenu(root.screen); if (action === "toggle") { pluginCore?.toggle(); } } } }