Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions shell/plugins/panels/power/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ function batteryFraction(device) {
return device && device.isPresent ? Math.max(0, Math.min(1, device.percentage)) : 0
}

// Below 20% — drives the red tint on the indicator.
function batteryIsLow(device) {
return !!(device && device.isPresent) && batteryFraction(device) < 0.2
}

// Below 5% — additionally surfaces the exclamation mark.
function batteryIsCritical(device) {
return !!(device && device.isPresent) && batteryFraction(device) < 0.05
}

function chargeThresholdActive(device, onBattery, states) {
var d = device || {}
var s = states || {}
Expand Down Expand Up @@ -97,6 +107,8 @@ if (typeof module !== "undefined") {
parseProfiles: parseProfiles,
profileIcon: profileIcon,
batteryFraction: batteryFraction,
batteryIsLow: batteryIsLow,
batteryIsCritical: batteryIsCritical,
chargeThresholdActive: chargeThresholdActive,
batteryIcon: batteryIcon,
modeLabel: modeLabel
Expand Down
33 changes: 24 additions & 9 deletions shell/plugins/panels/power/Panel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ Panel {

function batteryIcon() {
var device = UPower.displayDevice
return Model.batteryIcon(device, root.discharging, upowerStates())
var icon = Model.batteryIcon(device, root.discharging, upowerStates())
return root.batteryCritical ? icon + "!" : icon
}

function modeLabel() {
Expand Down Expand Up @@ -87,7 +88,25 @@ Panel {
return d && d.isPresent && !UPower.onBattery && !root.batteryFlowIdle
}

readonly property color batteryFillColor: {
// Percentage-only thresholds — independent of charge state, so these stay
// true even while charging (e.g. a device plugged in at 3% is still
// "critical" until it climbs back over 5%).
readonly property bool batteryLow: Model.batteryIsLow(UPower.displayDevice)
readonly property bool batteryCritical: Model.batteryIsCritical(UPower.displayDevice)

// Colors for the low/critical/charging indicator states. These are
// literal values rather than theme tokens because Color.qml lives outside
// this plugin — swap in e.g. Color.error / Color.success here if this
// shell's palette exposes semantic colors under those (or similar) names.
readonly property color batteryLowColor: "#e5484d"
readonly property color batteryChargingColor: "#30a46c"

// Shared color for every visual battery indicator (bar icon, panel hero
// icon, progress bar fill). Charging wins over low-battery red — a
// battery recovering from 3% is good news, not an alarm.
readonly property color batteryIndicatorColor: {
if (root.charging) return root.batteryChargingColor
if (root.batteryLow) return root.batteryLowColor
return root.bar ? root.bar.foreground : Color.foreground
}

Expand Down Expand Up @@ -280,6 +299,7 @@ Panel {
text: root.showPercentage && !vertical
? Math.round(root.batteryFraction * 100) + "% " + root.batteryIcon()
: root.batteryIcon()
foreground: root.batteryIndicatorColor
slotSize: Style.bar.iconSlot * (root.showPercentage && !vertical ? 2 : 1)
tooltipText: ""
onPressed: function(b) {
Expand Down Expand Up @@ -325,9 +345,8 @@ Panel {

Text {
id: heroIcon
textFormat: Text.PlainText
text: root.batteryIcon()
color: root.bar.foreground
color: root.batteryIndicatorColor
font.family: root.bar.fontFamily
font.pixelSize: Style.font.display
anchors.left: parent.left
Expand Down Expand Up @@ -357,7 +376,6 @@ Panel {

Text {
id: heroStatus
textFormat: Text.PlainText
text: root.heroStatusText.toUpperCase()
color: Qt.darker(root.bar.foreground, 1.4)
font.family: root.bar.fontFamily
Expand All @@ -371,7 +389,6 @@ Panel {

Text {
id: heroPercent
textFormat: Text.PlainText
text: root.batteryInfo.percentage || "—"
color: root.bar.foreground
font.family: root.bar.fontFamily
Expand Down Expand Up @@ -402,7 +419,7 @@ Panel {
anchors.verticalCenter: barTrack.verticalCenter
height: barTrack.height
radius: barTrack.radius
color: root.batteryFillColor
color: root.batteryIndicatorColor
width: Math.max(barTrack.height, barTrack.width * root.batteryFraction)

Behavior on width { NumberAnimation { duration: 320; easing.type: Easing.OutCubic } }
Expand Down Expand Up @@ -520,15 +537,13 @@ Panel {
}

component InfoLabel: Text {
textFormat: Text.PlainText
color: root.bar.foreground
opacity: 0.6
font.family: root.bar.fontFamily
font.pixelSize: Style.font.bodySmall
}

component InfoValue: Text {
textFormat: Text.PlainText
color: root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.bodySmall
Expand Down