summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/ProcessList/PerformanceView.qml
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/ProcessList/PerformanceView.qml')
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/ProcessList/PerformanceView.qml304
1 files changed, 304 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/ProcessList/PerformanceView.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/ProcessList/PerformanceView.qml
new file mode 100644
index 0000000..c793d92
--- /dev/null
+++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/ProcessList/PerformanceView.qml
@@ -0,0 +1,304 @@
+import QtQuick
+import QtQuick.Layouts
+import Quickshell
+import qs.Common
+import qs.Services
+import qs.Widgets
+
+Item {
+ id: root
+
+ readonly property int historySize: 60
+
+ property var cpuHistory: []
+ property var memoryHistory: []
+ property var networkRxHistory: []
+ property var networkTxHistory: []
+ property var diskReadHistory: []
+ property var diskWriteHistory: []
+
+ function formatBytes(bytes) {
+ if (bytes < 1024)
+ return bytes.toFixed(0) + " B/s";
+ if (bytes < 1024 * 1024)
+ return (bytes / 1024).toFixed(1) + " KB/s";
+ if (bytes < 1024 * 1024 * 1024)
+ return (bytes / (1024 * 1024)).toFixed(1) + " MB/s";
+ return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB/s";
+ }
+
+ function addToHistory(arr, val) {
+ const newArr = arr.slice();
+ newArr.push(val);
+ if (newArr.length > historySize)
+ newArr.shift();
+ return newArr;
+ }
+
+ function sampleData() {
+ cpuHistory = addToHistory(cpuHistory, DgopService.cpuUsage);
+ memoryHistory = addToHistory(memoryHistory, DgopService.memoryUsage);
+ networkRxHistory = addToHistory(networkRxHistory, DgopService.networkRxRate);
+ networkTxHistory = addToHistory(networkTxHistory, DgopService.networkTxRate);
+ diskReadHistory = addToHistory(diskReadHistory, DgopService.diskReadRate);
+ diskWriteHistory = addToHistory(diskWriteHistory, DgopService.diskWriteRate);
+ }
+
+ Component.onCompleted: {
+ DgopService.addRef(["cpu", "memory", "network", "disk", "diskmounts", "system"]);
+ }
+
+ Component.onDestruction: {
+ DgopService.removeRef(["cpu", "memory", "network", "disk", "diskmounts", "system"]);
+ }
+
+ SystemClock {
+ id: sampleClock
+ precision: SystemClock.Seconds
+ onDateChanged: {
+ if (date.getSeconds() % 1 === 0)
+ root.sampleData();
+ }
+ }
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: Theme.spacingM
+
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.preferredHeight: (root.height - Theme.spacingM * 2) / 2
+ spacing: Theme.spacingM
+
+ PerformanceCard {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ title: "CPU"
+ icon: "memory"
+ value: DgopService.cpuUsage.toFixed(1) + "%"
+ subtitle: DgopService.cpuModel || (DgopService.cpuCores + " cores")
+ accentColor: Theme.primary
+ history: root.cpuHistory
+ maxValue: 100
+ showSecondary: false
+ extraInfo: DgopService.cpuTemperature > 0 ? (DgopService.cpuTemperature.toFixed(0) + "°C") : ""
+ extraInfoColor: DgopService.cpuTemperature > 80 ? Theme.error : (DgopService.cpuTemperature > 60 ? Theme.warning : Theme.surfaceVariantText)
+ }
+
+ PerformanceCard {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ title: I18n.tr("Memory")
+ icon: "sd_card"
+ value: DgopService.memoryUsage.toFixed(1) + "%"
+ subtitle: DgopService.formatSystemMemory(DgopService.usedMemoryKB) + " / " + DgopService.formatSystemMemory(DgopService.totalMemoryKB)
+ accentColor: Theme.secondary
+ history: root.memoryHistory
+ maxValue: 100
+ showSecondary: false
+ extraInfo: DgopService.totalSwapKB > 0 ? ("Swap: " + DgopService.formatSystemMemory(DgopService.usedSwapKB)) : ""
+ extraInfoColor: Theme.surfaceVariantText
+ }
+ }
+
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.preferredHeight: (root.height - Theme.spacingM * 2) / 2
+ spacing: Theme.spacingM
+
+ PerformanceCard {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ title: I18n.tr("Network")
+ icon: "swap_horiz"
+ value: "↓ " + root.formatBytes(DgopService.networkRxRate)
+ subtitle: "↑ " + root.formatBytes(DgopService.networkTxRate)
+ accentColor: Theme.info
+ history: root.networkRxHistory
+ history2: root.networkTxHistory
+ maxValue: 0
+ showSecondary: true
+ extraInfo: ""
+ extraInfoColor: Theme.surfaceVariantText
+ }
+
+ PerformanceCard {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ title: I18n.tr("Disk")
+ icon: "storage"
+ value: "R: " + root.formatBytes(DgopService.diskReadRate)
+ subtitle: "W: " + root.formatBytes(DgopService.diskWriteRate)
+ accentColor: Theme.warning
+ history: root.diskReadHistory
+ history2: root.diskWriteHistory
+ maxValue: 0
+ showSecondary: true
+ extraInfo: {
+ const rootMount = DgopService.diskMounts.find(m => m.mountpoint === "/");
+ if (rootMount) {
+ const usedPct = ((rootMount.used || 0) / Math.max(1, rootMount.total || 1) * 100).toFixed(0);
+ return "/ " + usedPct + "% used";
+ }
+ return "";
+ }
+ extraInfoColor: Theme.surfaceVariantText
+ }
+ }
+ }
+
+ component PerformanceCard: Rectangle {
+ id: card
+
+ property string title: ""
+ property string icon: ""
+ property string value: ""
+ property string subtitle: ""
+ property color accentColor: Theme.primary
+ property var history: []
+ property var history2: null
+ property real maxValue: 100
+ property bool showSecondary: false
+ property string extraInfo: ""
+ property color extraInfoColor: Theme.surfaceVariantText
+
+ radius: Theme.cornerRadius
+ color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
+ border.color: Theme.outlineLight
+ border.width: 1
+
+ Canvas {
+ id: graphCanvas
+ anchors.fill: parent
+ anchors.margins: 4
+ renderStrategy: Canvas.Cooperative
+
+ property var hist: card.history
+ property var hist2: card.history2
+
+ onHistChanged: requestPaint()
+ onHist2Changed: requestPaint()
+ onWidthChanged: requestPaint()
+ onHeightChanged: requestPaint()
+
+ onPaint: {
+ const ctx = getContext("2d");
+ ctx.reset();
+ ctx.clearRect(0, 0, width, height);
+
+ if (!hist || hist.length < 2)
+ return;
+
+ let max = card.maxValue;
+ if (max <= 0) {
+ max = 1;
+ for (let k = 0; k < hist.length; k++)
+ max = Math.max(max, hist[k]);
+ if (hist2) {
+ for (let l = 0; l < hist2.length; l++)
+ max = Math.max(max, hist2[l]);
+ }
+ max *= 1.1;
+ }
+
+ const c = card.accentColor;
+ const grad = ctx.createLinearGradient(0, 0, 0, height);
+ grad.addColorStop(0, Qt.rgba(c.r, c.g, c.b, 0.25));
+ grad.addColorStop(1, Qt.rgba(c.r, c.g, c.b, 0.02));
+
+ ctx.fillStyle = grad;
+ ctx.beginPath();
+ ctx.moveTo(0, height);
+ for (let i = 0; i < hist.length; i++) {
+ const x = (width / (root.historySize - 1)) * i;
+ const y = height - (hist[i] / max) * height * 0.8;
+ ctx.lineTo(x, y);
+ }
+ ctx.lineTo((width / (root.historySize - 1)) * (hist.length - 1), height);
+ ctx.closePath();
+ ctx.fill();
+
+ ctx.strokeStyle = Qt.rgba(c.r, c.g, c.b, 0.8);
+ ctx.lineWidth = 2;
+ ctx.beginPath();
+ for (let j = 0; j < hist.length; j++) {
+ const px = (width / (root.historySize - 1)) * j;
+ const py = height - (hist[j] / max) * height * 0.8;
+ j === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py);
+ }
+ ctx.stroke();
+
+ if (hist2 && hist2.length >= 2 && card.showSecondary) {
+ ctx.strokeStyle = Qt.rgba(c.r, c.g, c.b, 0.4);
+ ctx.lineWidth = 1.5;
+ ctx.setLineDash([4, 4]);
+ ctx.beginPath();
+ for (let m = 0; m < hist2.length; m++) {
+ const sx = (width / (root.historySize - 1)) * m;
+ const sy = height - (hist2[m] / max) * height * 0.8;
+ m === 0 ? ctx.moveTo(sx, sy) : ctx.lineTo(sx, sy);
+ }
+ ctx.stroke();
+ ctx.setLineDash([]);
+ }
+ }
+ }
+
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: Theme.spacingM
+ spacing: Theme.spacingXS
+
+ RowLayout {
+ Layout.fillWidth: true
+ spacing: Theme.spacingS
+
+ DankIcon {
+ name: card.icon
+ size: Theme.iconSize
+ color: card.accentColor
+ }
+
+ StyledText {
+ text: card.title
+ font.pixelSize: Theme.fontSizeLarge
+ font.weight: Font.Bold
+ color: Theme.surfaceText
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ StyledText {
+ text: card.extraInfo
+ font.pixelSize: Theme.fontSizeSmall
+ font.family: SettingsData.monoFontFamily
+ color: card.extraInfoColor
+ visible: card.extraInfo.length > 0
+ }
+ }
+
+ Item {
+ Layout.fillHeight: true
+ }
+
+ StyledText {
+ text: card.value
+ font.pixelSize: Theme.fontSizeXLarge
+ font.family: SettingsData.monoFontFamily
+ font.weight: Font.Bold
+ color: Theme.surfaceText
+ }
+
+ StyledText {
+ text: card.subtitle
+ font.pixelSize: Theme.fontSizeSmall
+ font.family: SettingsData.monoFontFamily
+ color: Theme.surfaceVariantText
+ elide: Text.ElideRight
+ Layout.fillWidth: true
+ }
+ }
+ }
+}