1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-14 17:52:10 -04:00

fix sysmon errors

This commit is contained in:
bbedward
2025-08-08 17:03:00 -04:00
parent 682a8cd7d6
commit 927dc507da

View File

@@ -1,5 +1,4 @@
pragma Singleton pragma Singleton
pragma ComponentBehavior pragma ComponentBehavior
import QtQuick import QtQuick
@@ -76,337 +75,324 @@ Singleton {
property var availableGpus: [] property var availableGpus: []
function addRef() { function addRef() {
refCount++ refCount++;
if (refCount === 1) { if (refCount === 1) {
updateAllStats() updateAllStats();
} }
} }
function removeRef() { function removeRef() {
refCount = Math.max(0, refCount - 1) refCount = Math.max(0, refCount - 1);
} }
function updateAllStats() { function updateAllStats() {
if (refCount > 0) { if (refCount > 0) {
isUpdating = true isUpdating = true;
unifiedStatsProcess.running = true unifiedStatsProcess.running = true;
} }
} }
function setSortBy(newSortBy) { function setSortBy(newSortBy) {
if (newSortBy !== sortBy) { if (newSortBy !== sortBy) {
sortBy = newSortBy sortBy = newSortBy;
sortProcessesInPlace() sortProcessesInPlace();
} }
} }
function toggleSortOrder() { function toggleSortOrder() {
sortDescending = !sortDescending sortDescending = !sortDescending;
sortProcessesInPlace() sortProcessesInPlace();
} }
function sortProcessesInPlace() { function sortProcessesInPlace() {
if (processes.length === 0) if (processes.length === 0)
return return;
const sortedProcesses = [...processes];
const sortedProcesses = [...processes]
sortedProcesses.sort((a, b) => { sortedProcesses.sort((a, b) => {
let aVal, bVal let aVal, bVal;
switch (sortBy) { switch (sortBy) {
case "cpu": case "cpu":
aVal = parseFloat(a.cpu) || 0 aVal = parseFloat(a.cpu) || 0;
bVal = parseFloat(b.cpu) || 0 bVal = parseFloat(b.cpu) || 0;
break break;
case "memory": case "memory":
aVal = parseFloat(a.memoryPercent) || 0 aVal = parseFloat(a.memoryPercent) || 0;
bVal = parseFloat(b.memoryPercent) || 0 bVal = parseFloat(b.memoryPercent) || 0;
break break;
case "name": case "name":
aVal = a.command || "" aVal = a.command || "";
bVal = b.command || "" bVal = b.command || "";
break break;
case "pid": case "pid":
aVal = parseInt(a.pid) || 0 aVal = parseInt(a.pid) || 0;
bVal = parseInt(b.pid) || 0 bVal = parseInt(b.pid) || 0;
break break;
default: default:
aVal = parseFloat(a.cpu) || 0 aVal = parseFloat(a.cpu) || 0;
bVal = parseFloat(b.cpu) || 0 bVal = parseFloat(b.cpu) || 0;
} }
if (typeof aVal === "string") { if (typeof aVal === "string") {
return sortDescending ? bVal.localeCompare( return sortDescending ? bVal.localeCompare(aVal) : aVal.localeCompare(bVal);
aVal) : aVal.localeCompare(
bVal)
} else { } else {
return sortDescending ? bVal - aVal : aVal - bVal return sortDescending ? bVal - aVal : aVal - bVal;
} }
}) });
processes = sortedProcesses processes = sortedProcesses;
} }
function killProcess(pid) { function killProcess(pid) {
if (pid > 0) { if (pid > 0) {
Quickshell.execDetached("kill", [pid.toString()]) Quickshell.execDetached("kill", [pid.toString()]);
} }
} }
function addToHistory(array, value) { function addToHistory(array, value) {
array.push(value) array.push(value);
if (array.length > historySize) if (array.length > historySize)
array.shift() array.shift();
} }
function calculateCpuUsage(currentStats, lastStats) { function calculateCpuUsage(currentStats, lastStats) {
if (!lastStats || !currentStats || currentStats.length < 4) { if (!lastStats || !currentStats || currentStats.length < 4) {
return 0 return 0;
} }
const currentTotal = currentStats.reduce((sum, val) => sum + val, 0) const currentTotal = currentStats.reduce((sum, val) => sum + val, 0);
const lastTotal = lastStats.reduce((sum, val) => sum + val, 0) const lastTotal = lastStats.reduce((sum, val) => sum + val, 0);
const totalDiff = currentTotal - lastTotal const totalDiff = currentTotal - lastTotal;
if (totalDiff <= 0) if (totalDiff <= 0)
return 0 return 0;
const currentIdle = currentStats[3] const currentIdle = currentStats[3];
const lastIdle = lastStats[3] const lastIdle = lastStats[3];
const idleDiff = currentIdle - lastIdle const idleDiff = currentIdle - lastIdle;
const usedDiff = totalDiff - idleDiff const usedDiff = totalDiff - idleDiff;
return Math.max(0, Math.min(100, (usedDiff / totalDiff) * 100)) return Math.max(0, Math.min(100, (usedDiff / totalDiff) * 100));
} }
function parseUnifiedStats(text) { function parseUnifiedStats(text) {
function num(x) { function num(x) {
return (typeof x === "number" && !isNaN(x)) ? x : 0 return (typeof x === "number" && !isNaN(x)) ? x : 0;
} }
let data let data;
try { try {
data = JSON.parse(text) data = JSON.parse(text);
} catch (error) { } catch (error) {
isUpdating = false;
isUpdating = false return;
return
} }
if (data.memory) { if (data.memory) {
const m = data.memory const m = data.memory;
totalMemoryKB = num(m.total) totalMemoryKB = num(m.total);
const free = num(m.free) const free = num(m.free);
const buf = num(m.buffers) const buf = num(m.buffers);
const cached = num(m.cached) const cached = num(m.cached);
const shared = num(m.shared) const shared = num(m.shared);
usedMemoryKB = totalMemoryKB - free - buf - cached usedMemoryKB = totalMemoryKB - free - buf - cached;
totalSwapKB = num(m.swaptotal) totalSwapKB = num(m.swaptotal);
usedSwapKB = num(m.swaptotal) - num(m.swapfree) usedSwapKB = num(m.swaptotal) - num(m.swapfree);
totalMemoryMB = totalMemoryKB / 1024 totalMemoryMB = totalMemoryKB / 1024;
usedMemoryMB = usedMemoryKB / 1024 usedMemoryMB = usedMemoryKB / 1024;
freeMemoryMB = (totalMemoryKB - usedMemoryKB) / 1024 freeMemoryMB = (totalMemoryKB - usedMemoryKB) / 1024;
availableMemoryMB = num( availableMemoryMB = num(m.available) ? num(m.available) / 1024 : (free + buf + cached) / 1024;
m.available) ? num( memoryUsage = totalMemoryKB > 0 ? (usedMemoryKB / totalMemoryKB) * 100 : 0;
m.available) / 1024 : (free + buf + cached) / 1024
memoryUsage = totalMemoryKB > 0 ? (usedMemoryKB / totalMemoryKB) * 100 : 0
} }
if (data.cpu) { if (data.cpu) {
cpuCores = data.cpu.count || 1 cpuCores = data.cpu.count || 1;
cpuCount = data.cpu.count || 1 cpuCount = data.cpu.count || 1;
cpuModel = data.cpu.model || "" cpuModel = data.cpu.model || "";
cpuFrequency = data.cpu.frequency || 0 cpuFrequency = data.cpu.frequency || 0;
cpuTemperature = data.cpu.temperature || 0 cpuTemperature = data.cpu.temperature || 0;
if (data.cpu.total && data.cpu.total.length >= 8) { if (data.cpu.total && data.cpu.total.length >= 8) {
const currentStats = data.cpu.total const currentStats = data.cpu.total;
const usage = calculateCpuUsage(currentStats, lastCpuStats) const usage = calculateCpuUsage(currentStats, lastCpuStats);
cpuUsage = usage cpuUsage = usage;
totalCpuUsage = usage totalCpuUsage = usage;
lastCpuStats = [...currentStats] lastCpuStats = [...currentStats];
} }
if (data.cpu.cores) { if (data.cpu.cores) {
const coreUsages = [] const coreUsages = [];
for (var i = 0; i < data.cpu.cores.length; i++) { for (var i = 0; i < data.cpu.cores.length; i++) {
const currentCoreStats = data.cpu.cores[i] const currentCoreStats = data.cpu.cores[i];
if (currentCoreStats && currentCoreStats.length >= 8) { if (currentCoreStats && currentCoreStats.length >= 8) {
let lastCoreStats = null let lastCoreStats = null;
if (lastPerCoreStats && lastPerCoreStats[i]) { if (lastPerCoreStats && lastPerCoreStats[i]) {
lastCoreStats = lastPerCoreStats[i] lastCoreStats = lastPerCoreStats[i];
} }
const usage = calculateCpuUsage(currentCoreStats, lastCoreStats) const usage = calculateCpuUsage(currentCoreStats, lastCoreStats);
coreUsages.push(usage) coreUsages.push(usage);
} }
} }
if (JSON.stringify(perCoreCpuUsage) !== JSON.stringify(coreUsages)) { if (JSON.stringify(perCoreCpuUsage) !== JSON.stringify(coreUsages)) {
perCoreCpuUsage = coreUsages perCoreCpuUsage = coreUsages;
} }
lastPerCoreStats = data.cpu.cores.map(core => [...core]) lastPerCoreStats = data.cpu.cores.map(core => [...core]);
} }
} }
if (data.network) { if (data.network) {
let totalRx = 0 let totalRx = 0;
let totalTx = 0 let totalTx = 0;
for (const iface of data.network) { for (const iface of data.network) {
totalRx += iface.rx totalRx += iface.rx;
totalTx += iface.tx totalTx += iface.tx;
} }
if (lastNetworkStats) { if (lastNetworkStats) {
const timeDiff = updateInterval / 1000 const timeDiff = updateInterval / 1000;
const rxDiff = totalRx - lastNetworkStats.rx const rxDiff = totalRx - lastNetworkStats.rx;
const txDiff = totalTx - lastNetworkStats.tx const txDiff = totalTx - lastNetworkStats.tx;
networkRxRate = Math.max(0, rxDiff / timeDiff) networkRxRate = Math.max(0, rxDiff / timeDiff);
networkTxRate = Math.max(0, txDiff / timeDiff) networkTxRate = Math.max(0, txDiff / timeDiff);
addToHistory(networkHistory.rx, networkRxRate / 1024) addToHistory(networkHistory.rx, networkRxRate / 1024);
addToHistory(networkHistory.tx, networkTxRate / 1024) addToHistory(networkHistory.tx, networkTxRate / 1024);
} }
lastNetworkStats = { lastNetworkStats = {
"rx": totalRx, "rx": totalRx,
"tx": totalTx "tx": totalTx
} };
} }
if (data.disk) { if (data.disk) {
let totalRead = 0 let totalRead = 0;
let totalWrite = 0 let totalWrite = 0;
for (const disk of data.disk) { for (const disk of data.disk) {
totalRead += disk.read * 512 totalRead += disk.read * 512;
totalWrite += disk.write * 512 totalWrite += disk.write * 512;
} }
if (lastDiskStats) { if (lastDiskStats) {
const timeDiff = updateInterval / 1000 const timeDiff = updateInterval / 1000;
const readDiff = totalRead - lastDiskStats.read const readDiff = totalRead - lastDiskStats.read;
const writeDiff = totalWrite - lastDiskStats.write const writeDiff = totalWrite - lastDiskStats.write;
diskReadRate = Math.max(0, readDiff / timeDiff) diskReadRate = Math.max(0, readDiff / timeDiff);
diskWriteRate = Math.max(0, writeDiff / timeDiff) diskWriteRate = Math.max(0, writeDiff / timeDiff);
addToHistory(diskHistory.read, diskReadRate / (1024 * 1024)) addToHistory(diskHistory.read, diskReadRate / (1024 * 1024));
addToHistory(diskHistory.write, diskWriteRate / (1024 * 1024)) addToHistory(diskHistory.write, diskWriteRate / (1024 * 1024));
} }
lastDiskStats = { lastDiskStats = {
"read": totalRead, "read": totalRead,
"write": totalWrite "write": totalWrite
} };
} }
let totalDiff = 0 let totalDiff = 0;
if (data.cpu && data.cpu.total && data.cpu.total.length >= 4) { if (data.cpu && data.cpu.total && data.cpu.total.length >= 4) {
const currentTotal = data.cpu.total.reduce((s, v) => s + v, 0) const currentTotal = data.cpu.total.reduce((s, v) => s + v, 0);
if (lastTotalJiffies > 0) if (lastTotalJiffies > 0)
totalDiff = currentTotal - lastTotalJiffies totalDiff = currentTotal - lastTotalJiffies;
lastTotalJiffies = currentTotal lastTotalJiffies = currentTotal;
} }
if (data.processes) { if (data.processes) {
const newProcesses = [] const newProcesses = [];
for (const proc of data.processes) { for (const proc of data.processes) {
const pid = proc.pid const pid = proc.pid;
const pticks = Number(proc.pticks) || 0 const pticks = Number(proc.pticks) || 0;
const prev = lastProcTicks[pid] ?? null const prev = lastProcTicks[pid] ?? null;
let cpuShare = 0 let cpuShare = 0;
if (prev !== null && totalDiff > 0) { if (prev !== null && totalDiff > 0) {
// Per share all CPUs (matches gnome system monitor) // Per share all CPUs (matches gnome system monitor)
cpuShare = 100 * Math.max(0, pticks - prev) / totalDiff cpuShare = 100 * Math.max(0, pticks - prev) / totalDiff;
// per-share per-core // per-share per-core
//cpuShare = 100 * cpuCores * Math.max(0, pticks - prev) / totalDiff; //cpuShare = 100 * cpuCores * Math.max(0, pticks - prev) / totalDiff;
} }
lastProcTicks[pid] = pticks // update cache lastProcTicks[pid] = pticks; // update cache
newProcesses.push({ newProcesses.push({
"pid": pid, "pid": pid,
"ppid": proc.ppid, "ppid": proc.ppid,
"cpu": cpuShare, "cpu": cpuShare,
"memoryPercent": proc.pssPercent "memoryPercent": proc.pssPercent ?? proc.memoryPercent,
?? proc.memoryPercent,
"memoryKB": proc.pssKB ?? proc.memoryKB, "memoryKB": proc.pssKB ?? proc.memoryKB,
"command": proc.command, "command": proc.command,
"fullCommand": proc.fullCommand, "fullCommand": proc.fullCommand,
"displayName": (proc.command && proc.command.length "displayName": (proc.command && proc.command.length > 15) ? proc.command.substring(0, 15) + "..." : proc.command
> 15) ? proc.command.substring( });
0,
15) + "..." : proc.command
})
} }
processes = newProcesses processes = newProcesses;
sortProcessesInPlace() sortProcessesInPlace();
} }
if (data.system) { if (data.system) {
kernelVersion = data.system.kernel || "" kernelVersion = data.system.kernel || "";
distribution = data.system.distro || "" distribution = data.system.distro || "";
hostname = data.system.hostname || "" hostname = data.system.hostname || "";
architecture = data.system.arch || "" architecture = data.system.arch || "";
loadAverage = data.system.loadavg || "" loadAverage = data.system.loadavg || "";
processCount = data.system.processes || 0 processCount = data.system.processes || 0;
threadCount = data.system.threads || 0 threadCount = data.system.threads || 0;
bootTime = data.system.boottime || "" bootTime = data.system.boottime || "";
motherboard = data.system.motherboard || "" motherboard = data.system.motherboard || "";
biosVersion = data.system.bios || "" biosVersion = data.system.bios || "";
} }
if (data.diskmounts) { if (data.diskmounts) {
diskMounts = data.diskmounts diskMounts = data.diskmounts;
} }
if (data.gpus) { if (data.gpus) {
availableGpus = data.gpus availableGpus = data.gpus;
} }
addToHistory(cpuHistory, cpuUsage) addToHistory(cpuHistory, cpuUsage);
addToHistory(memoryHistory, memoryUsage) addToHistory(memoryHistory, memoryUsage);
isUpdating = false isUpdating = false;
} }
function getProcessIcon(command) { function getProcessIcon(command) {
const cmd = command.toLowerCase() const cmd = command.toLowerCase();
if (cmd.includes("firefox") || cmd.includes("chrome") || cmd.includes( if (cmd.includes("firefox") || cmd.includes("chrome") || cmd.includes("browser"))
"browser")) return "web";
return "web"
if (cmd.includes("code") || cmd.includes("editor") || cmd.includes("vim")) if (cmd.includes("code") || cmd.includes("editor") || cmd.includes("vim"))
return "code" return "code";
if (cmd.includes("terminal") || cmd.includes("bash") || cmd.includes("zsh")) if (cmd.includes("terminal") || cmd.includes("bash") || cmd.includes("zsh"))
return "terminal" return "terminal";
if (cmd.includes("music") || cmd.includes("audio") || cmd.includes( if (cmd.includes("music") || cmd.includes("audio") || cmd.includes("spotify"))
"spotify")) return "music_note";
return "music_note"
if (cmd.includes("video") || cmd.includes("vlc") || cmd.includes("mpv")) if (cmd.includes("video") || cmd.includes("vlc") || cmd.includes("mpv"))
return "play_circle" return "play_circle";
if (cmd.includes("systemd") || cmd.includes("kernel") || cmd.includes( if (cmd.includes("systemd") || cmd.includes("kernel") || cmd.includes("kthread"))
"kthread")) return "settings";
return "settings" return "memory";
return "memory"
} }
function formatCpuUsage(cpu) { function formatCpuUsage(cpu) {
return (cpu || 0).toFixed(1) + "%" return (cpu || 0).toFixed(1) + "%";
} }
function formatMemoryUsage(memoryKB) { function formatMemoryUsage(memoryKB) {
const mem = memoryKB || 0 const mem = memoryKB || 0;
if (mem < 1024) if (mem < 1024)
return mem.toFixed(0) + " KB" return mem.toFixed(0) + " KB";
else if (mem < 1024 * 1024) else if (mem < 1024 * 1024)
return (mem / 1024).toFixed(1) + " MB" return (mem / 1024).toFixed(1) + " MB";
else else
return (mem / (1024 * 1024)).toFixed(1) + " GB" return (mem / (1024 * 1024)).toFixed(1) + " GB";
} }
function formatSystemMemory(memoryKB) { function formatSystemMemory(memoryKB) {
const mem = memoryKB || 0 const mem = memoryKB || 0;
if (mem < 1024 * 1024) if (mem < 1024 * 1024)
return (mem / 1024).toFixed(0) + " MB" return (mem / 1024).toFixed(0) + " MB";
else else
return (mem / (1024 * 1024)).toFixed(1) + " GB" return (mem / (1024 * 1024)).toFixed(1) + " GB";
} }
Timer { Timer {
@@ -418,9 +404,7 @@ Singleton {
onTriggered: root.updateAllStats() onTriggered: root.updateAllStats()
} }
readonly property string scriptBody: `set -Eeuo pipefail readonly property string scriptBody: `
trap 'echo "ERR at line $LINENO: $BASH_COMMAND (exit $?)" >&2' ERR
sort_key=\${1:-cpu} sort_key=\${1:-cpu}
max_procs=\${2:-20} max_procs=\${2:-20}
@@ -475,7 +459,23 @@ Singleton {
cpu_count=$(nproc) cpu_count=$(nproc)
cpu_model=$(grep -m1 'model name' /proc/cpuinfo | cut -d: -f2- | sed 's/^ *//' | json_escape || echo 'Unknown') cpu_model=$(grep -m1 'model name' /proc/cpuinfo | cut -d: -f2- | sed 's/^ *//' | json_escape || echo 'Unknown')
cpu_freq=$(awk -F: '/cpu MHz/{gsub(/ /,"",$2);print $2;exit}' /proc/cpuinfo || echo 0) cpu_freq=$(awk -F: '/cpu MHz/{gsub(/ /,"",$2);print $2;exit}' /proc/cpuinfo || echo 0)
cpu_temp=$(grep -l 'coretemp\\|k10temp\\|k8temp\\|cpu_thermal\\|soc_thermal' /sys/class/hwmon/hwmon*/name 2>/dev/null | sed 's/name$/temp1_input/' | xargs cat 2>/dev/null | awk '{print $1/1000}' | head -1 || echo 0) cpu_temp=0
for hwmon_dir in /sys/class/hwmon/hwmon*/; do
[ -d "$hwmon_dir" ] || continue
name_file="\${hwmon_dir}name"
[ -r "$name_file" ] || continue
# Check if this hwmon is for CPU temperature
if grep -qE 'coretemp|k10temp|k8temp|cpu_thermal|soc_thermal' "$name_file" 2>/dev/null; then
# Look for temperature files without using wildcards in quotes
for temp_file in "\${hwmon_dir}"temp*_input; do
if [ -r "$temp_file" ]; then
cpu_temp=$(awk '{printf "%.1f", $1/1000}' "$temp_file" 2>/dev/null || echo 0)
break 2 # Break both loops
fi
done
fi
done
printf '"cpu":{"count":%d,"model":"%s","frequency":%s,"temperature":%s,' \\ printf '"cpu":{"count":%d,"model":"%s","frequency":%s,"temperature":%s,' \\
"$cpu_count" "$cpu_model" "$cpu_freq" "$cpu_temp" "$cpu_count" "$cpu_model" "$cpu_freq" "$cpu_temp"
@@ -684,33 +684,32 @@ Singleton {
Process { Process {
id: unifiedStatsProcess id: unifiedStatsProcess
command: ["bash", "-c", "bash -s \"$1\" \"$2\" <<'QS_EOF'\n" command: ["bash", "-c", "bash -s \"$1\" \"$2\" <<'QS_EOF'\n" + root.scriptBody + "\nQS_EOF\n", root.sortBy, String(root.maxProcesses)]
+ root.scriptBody + "\nQS_EOF\n", root.sortBy, String(root.maxProcesses)]
running: false running: false
onExited: exitCode => { onExited: exitCode => {
if (exitCode !== 0) { if (exitCode !== 0) {
console.log("SERVICE UPDATE FAILED");
isUpdating = false isUpdating = false;
} }
} }
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
if (text.trim()) { if (text.trim()) {
const fullText = text.trim() console.log(text.trim());
const lastBraceIndex = fullText.lastIndexOf('}') const fullText = text.trim();
const lastBraceIndex = fullText.lastIndexOf('}');
if (lastBraceIndex === -1) { if (lastBraceIndex === -1) {
isUpdating = false;
isUpdating = false return;
return
} }
const jsonText = fullText.substring(0, lastBraceIndex + 1) const jsonText = fullText.substring(0, lastBraceIndex + 1);
try { try {
const data = JSON.parse(jsonText) const data = JSON.parse(jsonText);
parseUnifiedStats(jsonText) parseUnifiedStats(jsonText);
} catch (e) { } catch (e) {
isUpdating = false isUpdating = false;
return return;
} }
} }
} }