mirror of
https://github.com/belsabbagh/dotfiles.git
synced 2026-04-11 17:47:09 +00:00
137 lines
3.9 KiB
QML
137 lines
3.9 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
pragma Singleton
|
|
|
|
Item {
|
|
// I have to make such services because quickshell services like Quickshell.Services.UPower don't work and are messy.
|
|
|
|
id: root
|
|
|
|
// Battery
|
|
property int percentage: 0
|
|
property string state: "unknown"
|
|
property string iconName: ""
|
|
property bool onBattery: false
|
|
property bool charging: false
|
|
property bool batteryPresent: false
|
|
property bool rechargeable: false
|
|
// Energy metrics
|
|
property real energyWh: 0
|
|
property real energyFullWh: 0
|
|
property real energyRateW: 0
|
|
property real capacityPercent: 0
|
|
// AC / system
|
|
property bool acOnline: false
|
|
property bool lidClosed: false
|
|
property string battIcon: {
|
|
const b = percentage;
|
|
if (b > 80)
|
|
return "battery_6_bar";
|
|
|
|
if (b > 60)
|
|
return "battery_5_bar";
|
|
|
|
if (b > 50)
|
|
return "battery_4_bar";
|
|
|
|
if (b > 40)
|
|
return "battery_3_bar";
|
|
|
|
if (b > 30)
|
|
return "battery_2_bar";
|
|
|
|
if (b > 20)
|
|
return "battery_1_bar";
|
|
|
|
if (b > 10)
|
|
return "battery_alert";
|
|
|
|
return "battery_0_bar";
|
|
}
|
|
|
|
Timer {
|
|
interval: 2000
|
|
running: true
|
|
repeat: true
|
|
onTriggered: upowerProc.running = true
|
|
}
|
|
|
|
Process {
|
|
id: upowerProc
|
|
|
|
command: ["upower", "-d"]
|
|
running: true
|
|
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
// ---------- DisplayDevice (preferred) ----------
|
|
// ---------- Rechargeable ----------
|
|
// ---------- Physical battery (extra info) ----------
|
|
// ---------- Daemon / system ----------
|
|
// ---------- AC adapter ----------
|
|
|
|
const t = text;
|
|
let m;
|
|
m = t.match(/DisplayDevice[\s\S]*?present:\s+(yes|no)/);
|
|
if (m) {
|
|
root.batteryPresent = (m[1] === "yes");
|
|
} else {
|
|
// fallback: physical battery
|
|
m = t.match(/battery_BAT\d+[\s\S]*?present:\s+(yes|no)/);
|
|
if (m)
|
|
root.batteryPresent = (m[1] === "yes");
|
|
|
|
}
|
|
m = t.match(/DisplayDevice[\s\S]*?rechargeable:\s+(yes|no)/);
|
|
if (m)
|
|
root.rechargeable = (m[1] === "yes");
|
|
|
|
m = t.match(/DisplayDevice[\s\S]*?percentage:\s+(\d+)%/);
|
|
if (m)
|
|
root.percentage = parseInt(m[1]);
|
|
|
|
m = t.match(/DisplayDevice[\s\S]*?state:\s+([a-z\-]+)/);
|
|
if (m) {
|
|
root.state = m[1];
|
|
root.charging = (m[1].includes("charge"));
|
|
}
|
|
m = t.match(/DisplayDevice[\s\S]*?icon-name:\s+'([^']+)'/);
|
|
if (m)
|
|
root.iconName = m[1];
|
|
|
|
m = t.match(/DisplayDevice[\s\S]*?energy:\s+([\d.]+)\s+Wh/);
|
|
if (m)
|
|
root.energyWh = parseFloat(m[1]);
|
|
|
|
m = t.match(/DisplayDevice[\s\S]*?energy-full:\s+([\d.]+)\s+Wh/);
|
|
if (m)
|
|
root.energyFullWh = parseFloat(m[1]);
|
|
|
|
m = t.match(/DisplayDevice[\s\S]*?energy-rate:\s+([\d.]+)\s+W/);
|
|
if (m)
|
|
root.energyRateW = parseFloat(m[1]);
|
|
|
|
m = t.match(/capacity:\s+([\d.]+)%/);
|
|
if (m)
|
|
root.capacityPercent = parseFloat(m[1]);
|
|
|
|
m = t.match(/on-battery:\s+(yes|no)/);
|
|
if (m)
|
|
root.onBattery = (m[1] === "yes");
|
|
|
|
m = t.match(/lid-is-closed:\s+(yes|no)/);
|
|
if (m)
|
|
root.lidClosed = (m[1] === "yes");
|
|
|
|
m = t.match(/line-power[\s\S]*?online:\s+(yes|no)/);
|
|
if (m)
|
|
root.acOnline = (m[1] === "yes");
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|