aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-17 11:57:30 +0200
committerDanilo M. <danix@danix.xyz>2026-10-17 11:57:30 +0200
commitffd6b594724d7aadd2cd08782485ece9a2aa5331 (patch)
tree872b3930239eb9229cd9738ca13fb12be67ae842
parentf73b88072b7abad720923dd32bae6a1e98bf64d5 (diff)
downloadquickshell-ffd6b594724d7aadd2cd08782485ece9a2aa5331.tar.gz
quickshell-ffd6b594724d7aadd2cd08782485ece9a2aa5331.zip
perf: sample everything always, not only while the page is open
Per-core load, the network rate, VRAM and the fan used to run only while a PerfPanel existed, and closing the page cleared them. Opening the drawer therefore always showed a fresh first sample and an empty network graph, which made the page not very useful as a glance at what just happened. Everything now samples for the whole session, so the graph opens on the last minute of history. The cost is the VRAM fdinfo scan, ~14ms every 2s, now unconditional; a ponytail note beside it says to gate it on the panel again if that shows up. The LAN address and the public IP check run once at startup instead of on each page open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--desktop/modules/perf/Perf.qml51
-rw-r--r--desktop/modules/perf/PerfPanel.qml4
-rw-r--r--desktop/modules/perf/README.md6
3 files changed, 19 insertions, 42 deletions
diff --git a/desktop/modules/perf/Perf.qml b/desktop/modules/perf/Perf.qml
index 6216959..9ebfe45 100644
--- a/desktop/modules/perf/Perf.qml
+++ b/desktop/modules/perf/Perf.qml
@@ -18,19 +18,14 @@ import QtQml
import "../.."
import "Perf.js" as P
-// The numbers behind the performance panel and the status pill's icon. CPU,
-// RAM, temperatures and disks are sampled always, so the icon can warn while
-// the panel is closed; per-core load, the network rate, VRAM and the fan only
-// while `detailed`, which is any PerfPanel existing (the drawer page).
+// The numbers behind the performance panel and the status pill's icon, all
+// sampled always: the icon warns while the panel is closed, and the panel
+// opens on history (the network graph) rather than an empty first sample.
// /proc and /sys are FileViews reloaded on a timer, no subprocess; df, the
// fdinfo scan, ip and curl are Processes.
Singleton {
id: root
- // PerfPanel instances alive; each counts itself in and out.
- property int viewers: 0
- readonly property bool detailed: viewers > 0
-
// ponytail: host constants, as conky had them. One mount per NFS server
// (Library and Slackware are one export, so are shared and backup); br0
// is a bridge, so VM-to-host copies show in the graph; xe puts no VRAM
@@ -56,13 +51,13 @@ Singleton {
property var hwmon: ({}) // chip name -> /sys/class/hwmon/hwmonN
property string cpuModel: ""
property var load: null // aggregate percent
- property var cores: [] // percent per core, while detailed
+ property var cores: [] // percent per core
property var mem: null // {total, used} bytes
property var temps: [] // [{label, value, warn, crit}], value null if unread
property var disks: [] // Perf.js df rows
- property var vram: null // bytes, while detailed
- property var fan: null // rpm, while detailed
- property var rx: [] // bytes/s, newest last, while detailed
+ property var vram: null // bytes
+ property var fan: null // rpm
+ property var rx: [] // bytes/s, newest last
property var tx: []
property string lan: ""
property var pub: null // {ip, fetched}
@@ -100,18 +95,9 @@ Singleton {
pubProc.running = true;
}
- onDetailedChanged: {
- if (detailed) {
- if (!root.lan) lanProc.running = true;
- root.fetchPubip();
- } else {
- root.cores = [];
- root.rx = [];
- root.tx = [];
- root.prevNet = null;
- root.vram = null;
- root.fan = null;
- }
+ Component.onCompleted: {
+ lanProc.running = true;
+ root.fetchPubip();
}
// --- /proc and /sys ---------------------------------------------------
@@ -162,7 +148,6 @@ Singleton {
stdout: StdioCollector { onStreamFinished: root.hwmon = P.hwmonMap(text) }
}
- // CPU, RAM and temperatures always; the fan and VRAM while detailed.
Timer {
interval: 2000
running: true
@@ -174,9 +159,7 @@ Singleton {
stat.reload();
const cur = P.cpuTimes(stat.text());
root.load = P.load(root.prevCpu[0], cur[0]);
- root.cores = root.detailed
- ? cur.slice(1).map((c, i) => P.load(root.prevCpu[i + 1], c) ?? 0)
- : [];
+ root.cores = cur.slice(1).map((c, i) => P.load(root.prevCpu[i + 1], c) ?? 0);
root.prevCpu = cur;
meminfo.reload();
@@ -196,15 +179,13 @@ Singleton {
}
root.temps = t;
- if (root.detailed) {
- if (fanView.path) { fanView.reload(); root.fan = root.num(fanView); }
- if (!vramProc.running) vramProc.running = true;
- }
+ if (fanView.path) { fanView.reload(); root.fan = root.num(fanView); }
+ if (!vramProc.running) vramProc.running = true;
}
}
- // ponytail: a shell glob over every fd on the system, ~14ms; only while
- // the panel is open. Only the user's own processes are readable, so a
+ // ponytail: a shell glob over every fd on the system, ~14ms every 2s,
+ // always; gate it on the panel again if that shows up. Only the user's own processes are readable, so a
// system service's GPU use is not counted, as in conky.
Process {
id: vramProc
@@ -217,7 +198,7 @@ Singleton {
Timer {
interval: 1000
- running: root.detailed
+ running: true
repeat: true
triggeredOnStart: true
onTriggered: {
diff --git a/desktop/modules/perf/PerfPanel.qml b/desktop/modules/perf/PerfPanel.qml
index de9021b..aa2e49f 100644
--- a/desktop/modules/perf/PerfPanel.qml
+++ b/desktop/modules/perf/PerfPanel.qml
@@ -34,10 +34,6 @@ Column {
function sensor(label) {
return Perf.temps.find(t => t.label === label) || { value: null, warn: 0, crit: 0 };
}
- // Detailed sampling (per-core, network, VRAM, fan) runs while the panel
- // exists, which is while the drawer page is shown.
- Component.onCompleted: Perf.viewers++
- Component.onDestruction: Perf.viewers--
function pct(part, whole) { return part === null || !whole ? null : 100 * part / whole; }
function last(list) { return list.length ? list[list.length - 1] : null; }
diff --git a/desktop/modules/perf/README.md b/desktop/modules/perf/README.md
index dea5a7e..bd9ebfb 100644
--- a/desktop/modules/perf/README.md
+++ b/desktop/modules/perf/README.md
@@ -26,9 +26,9 @@ into the LAN depends on the ISP's fixed address. The fetch is
`~/.cache/udt/pubip.txt`, the file conky's sampler used. A failed fetch is
never a mismatch: the old value goes stale after 4 hours and shows as a dash.
-CPU, RAM, temperatures and disks are sampled always. Per-core load, the
-network rate, VRAM (a scan of every fdinfo, ~14ms) and the fan run only while
-the page is open. The mount list, `br0`, the GPU name and the 12 GiB VRAM
+Everything is sampled always, including per-core load, the network rate,
+VRAM (a scan of every fdinfo, ~14ms every 2s) and the fan, so the page opens
+on the last minute of network history instead of an empty graph. The mount list, `br0`, the GPU name and the 12 GiB VRAM
size are constants in `Perf.qml`.
The cache card runs `du -B1 -d1` once each time the page opens, 28ms over