diff options
Diffstat (limited to 'desktop/modules/perf/PerfPanel.qml')
| -rw-r--r-- | desktop/modules/perf/PerfPanel.qml | 153 |
1 files changed, 99 insertions, 54 deletions
diff --git a/desktop/modules/perf/PerfPanel.qml b/desktop/modules/perf/PerfPanel.qml index f149d82..de9021b 100644 --- a/desktop/modules/perf/PerfPanel.qml +++ b/desktop/modules/perf/PerfPanel.qml @@ -10,24 +10,21 @@ // GNU General Public License for more details. import Quickshell +import Quickshell.Io import QtQuick -import QtQuick.Layouts import "../.." import "Perf.js" as P -// CPU, GPU, network and disks as cards in three columns: CPU down the left, -// GPU and network beside it, disks under those two. Numbers come from Perf; -// colours follow conky's bands, so they read as they did there. -GridLayout { +// CPU, temperatures, GPU, network, disks and ~/.cache as cards, one per row: +// the drawer page scrolls, so nothing has to share a line. Numbers come from +// Perf; colours follow conky's bands, so they read as they did there. +Column { id: panel - columns: 3 - columnSpacing: 8 - rowSpacing: 8 + spacing: 12 - readonly property real col: (width - 2 * columnSpacing) / 3 + readonly property int fs: Theme.fontSize - 2 readonly property var gpuTemp: sensor("GPU") - readonly property var vramTemp: sensor("VRAM") function tone(v, warn, crit) { const b = P.band(v, warn, crit); @@ -37,10 +34,8 @@ GridLayout { 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 any panel - // exists. The island loads one only while open and the drawer page only - // while shown, so counting instances is the whole gate, and two of them - // never clear it under each other. + // 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-- @@ -53,7 +48,7 @@ GridLayout { } component Label: Text { - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } + font { family: Theme.fontFamily; pixelSize: panel.fs } color: Theme.text } @@ -72,7 +67,7 @@ GridLayout { Text { visible: text !== "" text: parent.parent.glyph - font { family: Theme.iconFamily; pixelSize: Theme.fontSize - 2 } + font { family: Theme.iconFamily; pixelSize: panel.fs + 2 } color: parent.parent.labelColor } Label { text: parent.parent.label; color: parent.parent.labelColor } @@ -89,7 +84,7 @@ GridLayout { property real frac: 0 property color fill: Theme.green width: parent ? parent.width : 0 - height: 5 + height: 6 radius: 3 color: Theme.surfaceAlt Rectangle { @@ -105,17 +100,17 @@ GridLayout { property string title: "" property string headline: "" property color headlineColor: Theme.text + width: panel.width radius: 10 color: Qt.alpha(Theme.surface, 0.6) - implicitHeight: body.implicitHeight + 20 - Layout.fillHeight: true + implicitHeight: body.implicitHeight + 28 Column { id: body - x: 10 - y: 10 - width: parent.width - 20 - spacing: 5 + x: 14 + y: 14 + width: parent.width - 28 + spacing: 8 Item { width: parent.width @@ -124,7 +119,7 @@ GridLayout { id: titleText anchors.verticalCenter: parent.verticalCenter text: parent.parent.parent.title - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4; bold: true } + font { family: Theme.fontFamily; pixelSize: panel.fs; bold: true } color: Theme.subtext } Text { @@ -141,10 +136,6 @@ GridLayout { // --- CPU ---------------------------------------------------------------- Card { - Layout.row: 0 - Layout.column: 0 - Layout.rowSpan: 2 - Layout.preferredWidth: panel.col title: "CPU" headline: Perf.load === null ? "--" : Math.round(Perf.load) + "%" headlineColor: panel.tone(Perf.load, 25, 75) @@ -160,7 +151,7 @@ GridLayout { Row { id: eq width: parent.width - height: 40 + height: 64 spacing: 2 Repeater { model: Perf.cores @@ -187,14 +178,42 @@ GridLayout { frac: Perf.mem ? Perf.mem.used / Perf.mem.total : 0 fill: panel.tone(panel.pct(Perf.mem ? Perf.mem.used : null, Perf.mem ? Perf.mem.total : 0), 25, 75) } + } - Repeater { - model: Perf.temps.filter(t => t.label !== "GPU" && t.label !== "VRAM") - delegate: Pair { - required property var modelData - label: modelData.label - value: panel.deg(modelData.value) - valueColor: panel.tone(modelData.value, modelData.warn, modelData.crit) + // --- temperatures ------------------------------------------------------- + + Card { + title: "TEMPERATURES" + + Flow { + id: temps + width: parent.width + spacing: 8 + Repeater { + model: Perf.temps + delegate: Rectangle { + required property var modelData + width: (temps.width - 3 * temps.spacing) / 4 + height: tempCol.implicitHeight + 16 + radius: 8 + color: Qt.alpha(Theme.surfaceAlt, 0.5) + Column { + id: tempCol + anchors.centerIn: parent + spacing: 2 + Label { + anchors.horizontalCenter: parent.horizontalCenter + text: modelData.label + color: Theme.subtext + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: panel.deg(modelData.value) + font { family: Theme.fontFamily; pixelSize: panel.fs + 6; bold: true } + color: panel.tone(modelData.value, modelData.warn, modelData.crit) + } + } + } } } } @@ -203,9 +222,6 @@ GridLayout { // No utilisation: xe exposes no busy percentage. Card { - Layout.row: 0 - Layout.column: 1 - Layout.preferredWidth: panel.col title: "GPU · " + Perf.gpuName headline: panel.deg(panel.gpuTemp.value) headlineColor: panel.tone(panel.gpuTemp.value, panel.gpuTemp.warn, panel.gpuTemp.crit) @@ -219,11 +235,6 @@ GridLayout { fill: panel.tone(panel.pct(Perf.vram, Perf.vramTotal), 25, 75) } Pair { - label: "VRAM temp" - value: panel.deg(panel.vramTemp.value) - valueColor: panel.tone(panel.vramTemp.value, panel.vramTemp.warn, panel.vramTemp.crit) - } - Pair { label: "Fan" value: Perf.fan === null ? "--" : Perf.fan + " rpm" } @@ -232,15 +243,12 @@ GridLayout { // --- network ------------------------------------------------------------ Card { - Layout.row: 0 - Layout.column: 2 - Layout.preferredWidth: panel.col title: "NET · " + Perf.iface Canvas { id: graph width: parent.width - height: 44 + height: 80 onPaint: { const ctx = getContext("2d"); ctx.reset(); @@ -291,7 +299,7 @@ GridLayout { id: pin anchors { right: parent.right; verticalCenter: pubText.verticalCenter } text: String.fromCodePoint(0xF0403) - font { family: Theme.iconFamily; pixelSize: Theme.fontSize - 2 } + font { family: Theme.iconFamily; pixelSize: panel.fs + 2 } color: Perf.ip.ip !== "" && Perf.ip.ip === Prefs.pinnedIp ? Theme.text : Theme.overlay MouseArea { @@ -308,10 +316,6 @@ GridLayout { // --- disks -------------------------------------------------------------- Card { - Layout.row: 1 - Layout.column: 1 - Layout.columnSpan: 2 - Layout.preferredWidth: 2 * panel.col + panel.columnSpacing title: "DISKS" Repeater { @@ -319,7 +323,7 @@ GridLayout { delegate: Column { required property var modelData width: parent.width - spacing: 2 + spacing: 4 Pair { glyph: panel.glyph(modelData) label: modelData.host || modelData.mount @@ -333,4 +337,45 @@ GridLayout { } } } + + // --- cache -------------------------------------------------------------- + + // ~/.cache and its five largest children, measured once per page open: + // du over the tree took 28ms, so conky's 15-minute sampler file is not + // needed. The largest is coloured by its share of the total, as conky + // did, so the eye lands on the one worth deleting. + property var cache: null // {total, items: [{name, bytes}]} + + Process { + running: true + command: ["du", "-B1", "-d1", (Quickshell.env("XDG_CACHE_HOME") || Quickshell.env("HOME") + "/.cache")] + stdout: StdioCollector { + onStreamFinished: panel.cache = P.du(text) + } + } + + Card { + title: "CACHE" + headline: panel.cache ? P.bytes(panel.cache.total) : "--" + + Repeater { + model: panel.cache ? panel.cache.items.slice(0, 5) : [] + delegate: Column { + required property var modelData + required property int index + readonly property real share: modelData.bytes / panel.cache.total + width: parent.width + spacing: 4 + Pair { + label: modelData.name + value: P.bytes(modelData.bytes) + valueColor: index === 0 ? (share > 0.5 ? Theme.red : Theme.yellow) : Theme.text + } + Bar { + frac: share + fill: index === 0 ? (share > 0.5 ? Theme.red : Theme.yellow) : Theme.overlay + } + } + } + } } |
