mirror of
https://github.com/danbulant/dots-hyprland
synced 2026-05-24 12:22:09 +00:00
Added a small battery popup to show information
This commit is contained in:
parent
f8d162d995
commit
3a6c032782
5 changed files with 203 additions and 3 deletions
|
|
@ -3,8 +3,9 @@ import qs.modules.common.widgets
|
|||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
|
||||
Item {
|
||||
MouseArea {
|
||||
id: root
|
||||
property bool borderless: Config.options.bar.borderless
|
||||
readonly property var chargeState: Battery.chargeState
|
||||
|
|
@ -18,6 +19,8 @@ Item {
|
|||
implicitWidth: rowLayout.implicitWidth + rowLayout.spacing * 2
|
||||
implicitHeight: 32
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
|
||||
|
|
@ -92,4 +95,25 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: popupLoader
|
||||
active: root.containsMouse
|
||||
|
||||
component: PopupWindow {
|
||||
id: popupWindow
|
||||
visible: true
|
||||
implicitWidth: batteryPopup.implicitWidth
|
||||
implicitHeight: batteryPopup.implicitHeight
|
||||
anchor.item: root
|
||||
anchor.rect.x: (root.implicitWidth - popupWindow.implicitWidth) / 2
|
||||
anchor.rect.y: Config.options.bar.bottom
|
||||
? (-batteryPopup.implicitHeight - 15)
|
||||
: (root.implicitHeight + 15)
|
||||
color: "transparent"
|
||||
BatteryPopup {
|
||||
id: batteryPopup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
125
.config/quickshell/ii/modules/bar/BatteryPopup.qml
Normal file
125
.config/quickshell/ii/modules/bar/BatteryPopup.qml
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import qs
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
readonly property real margin: 10
|
||||
implicitWidth: columnLayout.implicitWidth + margin * 2
|
||||
implicitHeight: columnLayout.implicitHeight + margin * 2
|
||||
color: Appearance.colors.colLayer0
|
||||
radius: Appearance.rounding.small
|
||||
border.width: 1
|
||||
border.color: Appearance.colors.colLayer0Border
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.centerIn: parent
|
||||
spacing: 8
|
||||
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
Layout.fillWidth: true
|
||||
MaterialSymbol { text: "thermostat"; color: Appearance.m3colors.m3onSecondaryContainer }
|
||||
StyledText { text: Translation.tr("Temperature:"); color: Appearance.colors.colOnLayer1 }
|
||||
StyledText { Layout.fillWidth: true; horizontalAlignment: Text.AlignRight; color: Appearance.colors.colOnLayer1; text: `${Battery.temperature}°C` }
|
||||
}
|
||||
|
||||
// This row is hidden when the battery is full.
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
Layout.fillWidth: true
|
||||
property bool rowVisible: {
|
||||
let timeValue = Battery.isCharging ? Battery.timeToFull : Battery.timeToEmpty;
|
||||
let power = Battery.energyRate;
|
||||
return !(Battery.chargeState == 4 || timeValue <= 0 || power <= 0.01);
|
||||
}
|
||||
visible: rowVisible
|
||||
opacity: rowVisible ? 1 : 0
|
||||
Behavior on opacity { NumberAnimation { duration: 500 } }
|
||||
|
||||
MaterialSymbol { text: "schedule"; color: Appearance.m3colors.m3onSecondaryContainer }
|
||||
StyledText { text: Battery.isCharging ? Translation.tr("Time to full:") : Translation.tr("Time to empty:"); color: Appearance.colors.colOnLayer1 }
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
color: Appearance.colors.colOnLayer1
|
||||
text: {
|
||||
function formatTime(seconds) {
|
||||
var h = Math.floor(seconds / 3600);
|
||||
var m = Math.floor((seconds % 3600) / 60);
|
||||
if (h > 0)
|
||||
return `${h}h ${m}m`;
|
||||
else
|
||||
return `${m}m`;
|
||||
}
|
||||
if (Battery.isCharging)
|
||||
return formatTime(Battery.timeToFull);
|
||||
else
|
||||
return formatTime(Battery.timeToEmpty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
Layout.fillWidth: true
|
||||
|
||||
property bool rowVisible: !(Battery.chargeState != 4 && Battery.energyRate == 0)
|
||||
visible: rowVisible
|
||||
opacity: rowVisible ? 1 : 0
|
||||
Behavior on opacity { NumberAnimation { duration: 500 } }
|
||||
|
||||
MaterialSymbol {
|
||||
text: {
|
||||
if (Battery.isCharging) {
|
||||
return "power";
|
||||
} else if (Battery.percentage >= 0.8) {
|
||||
return "battery_full";
|
||||
} else if (Battery.percentage >= 0.6) {
|
||||
return "battery_5_bar";
|
||||
} else if (Battery.percentage >= 0.4) {
|
||||
return "battery_4_bar";
|
||||
} else if (Battery.percentage >= 0.2) {
|
||||
return "battery_2_bar";
|
||||
} else {
|
||||
return "battery_0_bar";
|
||||
}
|
||||
}
|
||||
color: Appearance.m3colors.m3onSecondaryContainer
|
||||
}
|
||||
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
if (Battery.chargeState == 4) {
|
||||
return Translation.tr("Fully charged");
|
||||
} else if (Battery.chargeState == 1) {
|
||||
return Translation.tr("Charging:");
|
||||
} else {
|
||||
return Translation.tr("Discharging:");
|
||||
}
|
||||
}
|
||||
color: Appearance.colors.colOnLayer1
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
color: Appearance.colors.colOnLayer1
|
||||
text: {
|
||||
if (Battery.chargeState == 4) {
|
||||
return "";
|
||||
} else {
|
||||
return `${Battery.energyRate.toFixed(2)}W`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import qs
|
|||
import qs.modules.common
|
||||
import Quickshell
|
||||
import Quickshell.Services.UPower
|
||||
import QtQuick
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
property bool available: UPower.displayDevice.isLaptopBattery
|
||||
|
|
@ -21,6 +23,43 @@ Singleton {
|
|||
property bool isCriticalAndNotCharging: isCritical && !isCharging
|
||||
property bool isSuspendingAndNotCharging: allowAutomaticSuspend && isSuspending && !isCharging
|
||||
|
||||
property real energyRate: UPower.displayDevice.changeRate
|
||||
property real timeToEmpty: UPower.displayDevice.timeToEmpty
|
||||
property real timeToFull: UPower.displayDevice.timeToFull
|
||||
property real temperature: 0
|
||||
|
||||
Process {
|
||||
id: tempProcess
|
||||
command: ["bash", "-c", "cat /sys/class/thermal/thermal_zone0/temp"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (text && text.trim() !== "") {
|
||||
Battery.temperature = parseInt(text.trim()) / 1000
|
||||
} else {
|
||||
Battery.temperature = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 3000
|
||||
repeat: true
|
||||
running: true
|
||||
onTriggered: {
|
||||
if (!tempProcess.running) {
|
||||
tempProcess.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!tempProcess.running) {
|
||||
tempProcess.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onIsLowAndNotChargingChanged: {
|
||||
if (available && isLowAndNotCharging) Quickshell.execDetached([
|
||||
"notify-send",
|
||||
|
|
|
|||
|
|
@ -310,5 +310,11 @@
|
|||
"Sunrise": "Sunrise",
|
||||
"Pressure": "Pressure",
|
||||
"Visibility": "Visibility",
|
||||
"Precipitation": "Precipitation"
|
||||
"Precipitation": "Precipitation",
|
||||
"Temperature:": "Temperature:",
|
||||
"Time to full:": "Time to full:",
|
||||
"Time to empty:": "Time to empty:",
|
||||
"Fully charged": "Fully charged",
|
||||
"Charging:": "Charging:",
|
||||
"Discharging:": "Discharging:"
|
||||
}
|
||||
|
|
@ -310,5 +310,11 @@
|
|||
"Sunset": "日落",
|
||||
"Humidity": "湿度",
|
||||
"Wind": "风",
|
||||
"Precipitation": "降水量"
|
||||
"Precipitation": "降水量",
|
||||
"Temperature:": "温度:",
|
||||
"Time to full:": "距离充满:",
|
||||
"Time to empty:": "距离耗尽:",
|
||||
"Fully charged": "已充满电",
|
||||
"Charging:": "充电功率:",
|
||||
"Discharging:": "放电功率:"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue