diff options
Diffstat (limited to 'services')
| -rw-r--r-- | services/Mpris.qml (renamed from services/SMpris.qml) | 2 | ||||
| -rw-r--r-- | services/Network.qml | 86 | ||||
| -rw-r--r-- | services/Resource.qml | 105 |
3 files changed, 192 insertions, 1 deletions
diff --git a/services/SMpris.qml b/services/Mpris.qml index 012a354..9618459 100644 --- a/services/SMpris.qml +++ b/services/Mpris.qml @@ -1,5 +1,5 @@ pragma Singleton -pragma ComponentBehavior: Bound +// pragma ComponentBehavior: Bound // From https://git.outfoxxed.me/outfoxxed/nixnew // It does not have a license, but the author is okay with redistribution. diff --git a/services/Network.qml b/services/Network.qml new file mode 100644 index 0000000..52f15fa --- /dev/null +++ b/services/Network.qml @@ -0,0 +1,86 @@ +pragma Singleton +// pragma ComponentBehavior: Bound + +import Quickshell +import Quickshell.Io +import QtQuick + +import qs.config + +Singleton { + id: root + + property bool wifi: true + property bool ethernet: false + property string networkName: "" + property int networkStrength + // property string materialSymbol: ethernet ? "lan" : (Network.networkName.length > 0 && Network.networkName != "lo") ? (Network.networkStrength > 80 ? "signal_wifi_4_bar" : Network.networkStrength > 60 ? "network_wifi_3_bar" : Network.networkStrength > 40 ? "network_wifi_2_bar" : Network.networkStrength > 20 ? "network_wifi_1_bar" : "signal_wifi_0_bar") : "signal_wifi_off" + property string state: ethernet ? Icons.resource.network.wifi : (networkName.length >= 0 && networkName !== "lo") ? (networkStrength >= 90 ? Icons.resource.network.wifi.max : networkStrength >= 80 ? Icons.resource.network.wifi.high : networkStrength >= 60 ? Icons.resource.network.wifi.mid : networkStrength >= 40 ? Icons.resource.network.wifi.low : networkStrength >= 20 ? Icons.resource.network.wifi.min : Icons.resource.network.disconnected) : Icons.resource.network.disconnected + + function update() { + updateConnectionType.startCheck(); + updateNetworkName.running = true; + updateNetworkStrength.running = true; + } + + Timer { + interval: General.resourceUpdateInterval + running: true + repeat: true + onTriggered: { + root.update(); + interval = General.resourceUpdateInterval * 1000; + } + } + + Process { + id: updateConnectionType + property string buffer + command: ["nmcli", "-t", "-f", "NAME,TYPE,DEVICE", "c", "show", "--active"] + running: true + function startCheck() { + buffer = ""; + updateConnectionType.running = true; + } + stdout: SplitParser { + onRead: data => { + updateConnectionType.buffer += data + "\n"; + } + } + onExited: (exitCode, exitStatus) => { + const lines = updateConnectionType.buffer.trim().split('\n'); + let hasEthernet = false; + let hasWifi = false; + lines.forEach(line => { + if (line.includes("ethernet")) + hasEthernet = true; + else if (line.includes("wireless")) + hasWifi = true; + }); + root.ethernet = hasEthernet; + root.wifi = hasWifi; + } + } + + Process { + id: updateNetworkName + command: ["sh", "-c", "nmcli -t -f NAME c show --active | head -1"] + running: true + stdout: SplitParser { + onRead: data => { + root.networkName = data; + } + } + } + + Process { + id: updateNetworkStrength + running: true + command: ["sh", "-c", "nmcli -f IN-USE,SIGNAL,SSID device wifi | awk '/^\*/{if (NR!=1) {print $2}}'"] + stdout: SplitParser { + onRead: data => { + root.networkStrength = parseInt(data); + } + } + } +} diff --git a/services/Resource.qml b/services/Resource.qml new file mode 100644 index 0000000..b45538b --- /dev/null +++ b/services/Resource.qml @@ -0,0 +1,105 @@ +pragma Singleton +// pragma ComponentBehavior: Bound + +import QtQuick +import Quickshell +import Quickshell.Io +import qs.config + +Singleton { + id: root + + 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: swapTotal > 0 ? (swapUsed / swapTotal) : 0 + + property double cpuUsage: 0 + property double cpuTemp: 0 + property var previousCpuStats + + property int gpuUsage: 0 + property int gpuTemp: 0 + + Timer { + interval: General.resourceUpdateInterval + running: true + repeat: true + onTriggered: { + fileMeminfo.reload(); + fileStat.reload(); + fileCpuThermal.reload(); + + const textMeminfo = fileMeminfo.text(); + memoryTotal = Number(textMeminfo.match(/MemTotal: *(\d+)/)[1] ?? 1); + memoryFree = Number(textMeminfo.match(/MemAvailable: *(\d+)/)[1] ?? 0); + memoryUsed = memoryTotal - memoryFree; + memoryUsedPercentage = memoryUsed / memoryTotal; + swapTotal = Number(textMeminfo.match(/SwapTotal: *(\d+)/)[1] ?? 1); + swapFree = Number(textMeminfo.match(/SwapFree: *(\d+)/)[1] ?? 0); + + 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 (root.previousCpuStats) { + const totalDiff = total - root.previousCpuStats.total; + const idleDiff = idle - root.previousCpuStats.idle; + cpuUsage = totalDiff > 0 ? (1 - idleDiff / totalDiff) : 0; + } + + root.previousCpuStats = { + total, + idle + }; + } + const cpuTempText = fileCpuThermal.text(); + cpuTemp = cpuTempText ? parseInt(cpuTempText.trim()) / 100000 : 0; + + gpuUsageProcess.running = true; + gpuTempProcess.running = true; + interval = General.resourceUpdateInterval * 1000; + } + } + + FileView { + id: fileMeminfo + path: "/proc/meminfo" + } + FileView { + id: fileStat + path: "/proc/stat" + } + FileView { + id: fileCpuThermal + path: General.cpuThermalPath + } + // nvidia-smi may be dead if firmware update so ABI break etc. + Process { + id: gpuUsageProcess + running: true + command: ["nvidia-smi", "--query-gpu=utilization.gpu", "--format=csv,noheader,nounits"] + stdout: StdioCollector { + onStreamFinished: { + root.gpuUsage = parseInt(this.text.trim()); + } + } + } + Process { + id: gpuTempProcess + running: true + command: ["nvidia-smi", "--query-gpu=temperature.gpu", "--format=csv,noheader,nounits"] + stdout: StdioCollector { + onStreamFinished: { + root.gpuTemp = parseInt(this.text.trim()); + } + } + } +} |
