From 742ec413f378574117214c9984d51252518b0ebf Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Fri, 11 Apr 2025 01:16:55 +0200 Subject: [PATCH] bar resource usage indicator --- .config/quickshell/modules/bar/Bar.qml | 5 ++ .config/quickshell/modules/bar/Battery.qml | 9 +-- .config/quickshell/modules/bar/Resource.qml | 36 ++++++++++++ .config/quickshell/modules/bar/Resources.qml | 35 ++++++++++++ .../modules/common/ConfigOptions.qml | 3 + .../quickshell/modules/common/DateTime.qml | 4 +- .../modules/common/ResourceUsage.qml | 56 +++++++++++++++++++ .../common/widgets/CircularProgress.qml | 5 +- 8 files changed, 140 insertions(+), 13 deletions(-) create mode 100644 .config/quickshell/modules/bar/Resource.qml create mode 100644 .config/quickshell/modules/bar/Resources.qml create mode 100644 .config/quickshell/modules/common/ResourceUsage.qml diff --git a/.config/quickshell/modules/bar/Bar.qml b/.config/quickshell/modules/bar/Bar.qml index 6785cb729..6871a964f 100644 --- a/.config/quickshell/modules/bar/Bar.qml +++ b/.config/quickshell/modules/bar/Bar.qml @@ -10,6 +10,7 @@ Scope { PanelWindow { id: barRoot + property var modelData screen: modelData @@ -31,6 +32,10 @@ Scope { spacing: 4 Layout.fillWidth: true Layout.fillHeight: true + + Resources { + } + } RowLayout { diff --git a/.config/quickshell/modules/bar/Battery.qml b/.config/quickshell/modules/bar/Battery.qml index c9c482003..215458ec6 100644 --- a/.config/quickshell/modules/bar/Battery.qml +++ b/.config/quickshell/modules/bar/Battery.qml @@ -12,7 +12,6 @@ Rectangle { readonly property bool isPluggedIn: isCharging || chargeState == UPowerDeviceState.PendingCharge readonly property real percentage: UPower.displayDevice.percentage readonly property bool isLow: percentage <= ConfigOptions.bar.batteryLowThreshold / 100 - readonly property int batterySlideDistance: 10 readonly property color batteryLowBackground: Appearance.m3colors.darkmode ? Appearance.m3colors.m3error : Appearance.m3colors.m3errorContainer readonly property color batteryLowOnBackground: Appearance.m3colors.darkmode ? Appearance.m3colors.m3errorContainer : Appearance.m3colors.m3error @@ -21,12 +20,6 @@ Rectangle { color: Appearance.colors.colLayer1 radius: Appearance.rounding.small - Process { - id: screenSnip - - command: ["grimblast", "copy", "area"] - } - RowLayout { id: rowLayout @@ -50,7 +43,7 @@ Rectangle { StyledText { Layout.alignment: Qt.AlignVCenter color: Appearance.colors.colOnLayer1 - text: `${percentage * 100}%` + text: `${Math.round(percentage * 100)}%` } CircularProgress { diff --git a/.config/quickshell/modules/bar/Resource.qml b/.config/quickshell/modules/bar/Resource.qml new file mode 100644 index 000000000..4f231835e --- /dev/null +++ b/.config/quickshell/modules/bar/Resource.qml @@ -0,0 +1,36 @@ +import "../common" +import "../common/widgets" +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Io + +RowLayout { + required property string iconName + required property double percentage + spacing: 4 + + CircularProgress { + Layout.alignment: Qt.AlignVCenter + lineWidth: 2 + value: percentage + size: 26 + secondaryColor: Appearance.m3colors.m3secondaryContainer + primaryColor: Appearance.m3colors.m3onSecondaryContainer + + MaterialSymbol { + anchors.centerIn: parent + text: iconName + font.pointSize: Appearance.font.pointSize.normal + color: Appearance.m3colors.m3onSecondaryContainer + } + + } + + StyledText { + Layout.alignment: Qt.AlignVCenter + color: Appearance.colors.colOnLayer1 + text: `${Math.round(percentage * 100)}%` + } + +} diff --git a/.config/quickshell/modules/bar/Resources.qml b/.config/quickshell/modules/bar/Resources.qml new file mode 100644 index 000000000..ea64c8ce6 --- /dev/null +++ b/.config/quickshell/modules/bar/Resources.qml @@ -0,0 +1,35 @@ +import "../common" +import "../common/widgets" +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Io + +Rectangle { + implicitWidth: rowLayout.implicitWidth + rowLayout.spacing * 2 + implicitHeight: 32 + color: Appearance.colors.colLayer1 + radius: Appearance.rounding.small + + RowLayout { + id: rowLayout + + spacing: 4 + anchors.centerIn: parent + + Resource { + iconName: "memory" + percentage: ResourceUsage.memoryUsedPercentage + } + Resource { + iconName: "swap_horiz" + percentage: ResourceUsage.swapUsedPercentage + } + Resource { + iconName: "settings_slow_motion" + percentage: ResourceUsage.cpuUsage + } + + } + +} diff --git a/.config/quickshell/modules/common/ConfigOptions.qml b/.config/quickshell/modules/common/ConfigOptions.qml index 4ba8f8a6b..df7f5e154 100644 --- a/.config/quickshell/modules/common/ConfigOptions.qml +++ b/.config/quickshell/modules/common/ConfigOptions.qml @@ -7,5 +7,8 @@ Singleton { property int workspacesShown: 10 property int batteryLowThreshold: 20 } + property QtObject resources: QtObject { + property int updateInterval: 3000 + } } diff --git a/.config/quickshell/modules/common/DateTime.qml b/.config/quickshell/modules/common/DateTime.qml index 6e29ec968..ddeec093e 100644 --- a/.config/quickshell/modules/common/DateTime.qml +++ b/.config/quickshell/modules/common/DateTime.qml @@ -1,13 +1,11 @@ import QtQuick import Quickshell import Quickshell.Io -// with this line our type becomes a singleton pragma Singleton -// your singletons should always have Singleton as the type Singleton { property string time: Qt.formatDateTime(clock.date, "hh:mm") - property string date: Qt.formatDateTime(clock.date, "dddd, dd/MM") + property string date: Qt.formatDateTime(clock.date, "dddd, dd/MM") SystemClock { id: clock diff --git a/.config/quickshell/modules/common/ResourceUsage.qml b/.config/quickshell/modules/common/ResourceUsage.qml new file mode 100644 index 000000000..898abbb34 --- /dev/null +++ b/.config/quickshell/modules/common/ResourceUsage.qml @@ -0,0 +1,56 @@ +pragma Singleton +import QtQuick +import Quickshell +import Quickshell.Io + +Singleton { + property double memoryTotal: 1 + property double memoryFree: 1 + property double memoryUsed: memoryTotal - memoryFree + property double memoryUsedPercentage: memoryUsed / memoryTotal + property double swapTotal: 1 + property double swapFree: 1 + property double swapUsed: swapTotal - swapFree + property double swapUsedPercentage: swapUsed / swapTotal + property double cpuUsage: 0 + property var previousCpuStats + + Timer { + interval: 50 + running: true + repeat: true + onTriggered: { + // Reload files + fileMeminfo.reload() + fileStat.reload() + + // Parse memory and swap usage + const textMeminfo = fileMeminfo.text() + memoryTotal = Number(textMeminfo.match(/MemTotal: *(\d+)/)?.[1] ?? 1) + memoryFree = Number(textMeminfo.match(/MemAvailable: *(\d+)/)?.[1] ?? 0) + swapTotal = Number(textMeminfo.match(/SwapTotal: *(\d+)/)?.[1] ?? 1) + swapFree = Number(textMeminfo.match(/SwapFree: *(\d+)/)?.[1] ?? 0) + + // Parse CPU usage + const textStat = fileStat.text() + const cpuLine = textStat.match(/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/) + if (cpuLine) { + const stats = cpuLine.slice(1).map(Number) + const total = stats.reduce((a, b) => a + b, 0) + const idle = stats[3] + + if (previousCpuStats) { + const totalDiff = total - previousCpuStats.total + const idleDiff = idle - previousCpuStats.idle + cpuUsage = totalDiff > 0 ? (1 - idleDiff / totalDiff) : 0 + } + + previousCpuStats = { total, idle } + } + interval = ConfigOptions.resources.updateInterval + } + } + + FileView { id: fileMeminfo; path: "/proc/meminfo" } + FileView { id: fileStat; path: "/proc/stat" } +} \ No newline at end of file diff --git a/.config/quickshell/modules/common/widgets/CircularProgress.qml b/.config/quickshell/modules/common/widgets/CircularProgress.qml index d72760126..62970f797 100644 --- a/.config/quickshell/modules/common/widgets/CircularProgress.qml +++ b/.config/quickshell/modules/common/widgets/CircularProgress.qml @@ -8,8 +8,8 @@ Item { property int size: 30 property int lineWidth: 2 property real value: 0 - property color primaryColor: "#29b6f6" - property color secondaryColor: "#e0e0e0" + property color primaryColor: "#70585D" + property color secondaryColor: "#FFF8F7" property bool fill: false property int fillOverflow: 2 property int animationDuration: 1000 @@ -60,6 +60,7 @@ Item { Behavior on degree { NumberAnimation { duration: root.animationDuration + easing.type: Easing.OutCubic } }