From 8fdd9692e610d81a2c1c15004193166295356f2a Mon Sep 17 00:00:00 2001 From: Damocles Date: Wed, 15 Apr 2026 18:01:49 +0200 Subject: [PATCH] refactor: ProcessList non-singleton with sortBy+active, each panel owns one instance gated on _showPanel --- modules/Cpu.qml | 7 ++++++- modules/Memory.qml | 7 ++++++- modules/ProcessList.qml | 35 +++++++++++++++-------------------- modules/qmldir | 2 +- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/modules/Cpu.qml b/modules/Cpu.qml index db88749..cfe49c1 100644 --- a/modules/Cpu.qml +++ b/modules/Cpu.qml @@ -32,6 +32,11 @@ M.BarSection { readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered readonly property bool _showPanel: _anyHover || _pinned + property M.ProcessList _procs: M.ProcessList { + sortBy: "cpu" + active: root._showPanel + } + on_AnyHoverChanged: { if (_anyHover) _unpinTimer.stop(); @@ -258,7 +263,7 @@ M.BarSection { // Top processes by CPU Repeater { - model: M.ProcessList.byCpu + model: root._procs.processes delegate: Item { required property var modelData diff --git a/modules/Memory.qml b/modules/Memory.qml index 56df098..9df3491 100644 --- a/modules/Memory.qml +++ b/modules/Memory.qml @@ -21,6 +21,11 @@ M.BarSection { readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered readonly property bool _showPanel: _anyHover || _pinned + property M.ProcessList _procs: M.ProcessList { + sortBy: "mem" + active: root._showPanel + } + on_AnyHoverChanged: { if (_anyHover) _unpinTimer.stop(); @@ -223,7 +228,7 @@ M.BarSection { // Top processes by memory Repeater { - model: M.ProcessList.byMem + model: root._procs.processes delegate: Item { required property var modelData diff --git a/modules/ProcessList.qml b/modules/ProcessList.qml index b5bfbb9..6678ab0 100644 --- a/modules/ProcessList.qml +++ b/modules/ProcessList.qml @@ -1,48 +1,43 @@ -pragma Singleton - import QtQuick import Quickshell.Io -import "." as M QtObject { id: root - property var byCpu: [] - property var byMem: [] + property string sortBy: "cpu" // "cpu" or "mem" property int maxItems: 8 + property bool active: false + + property var processes: [] property Process _proc: Process { - id: proc - running: true - command: ["sh", "-c", "ps aux --sort=-%cpu 2>/dev/null | awk 'NR>1 && NR<=50 {cmd=$11; for(i=12;i<=NF&&i<=13;i++) cmd=cmd\" \"$i; print $1\"|\"$2\"|\"$3\"|\"$4\"|\"cmd}'"] + command: ["sh", "-c", "ps --no-headers -eo pid,pcpu,pmem,comm --sort=-%" + root.sortBy + " | head -" + root.maxItems] stdout: StdioCollector { onStreamFinished: { const rows = []; for (const line of text.trim().split("\n")) { if (!line) continue; - const p = line.split("|"); - if (p.length < 5) + const p = line.trim().split(/\s+/); + if (p.length < 4) continue; - const cmd = p[4].replace(/^.*\//, ""); rows.push({ - "user": p[0], - "pid": parseInt(p[1]), - "cpu": parseFloat(p[2]), - "mem": parseFloat(p[3]), - "cmd": cmd || p[4] + "pid": parseInt(p[0]), + "cpu": parseFloat(p[1]), + "mem": parseFloat(p[2]), + "cmd": p.slice(3).join(" ") }); } - root.byCpu = rows.slice().sort((a, b) => b.cpu - a.cpu).slice(0, root.maxItems); - root.byMem = rows.slice().sort((a, b) => b.mem - a.mem).slice(0, root.maxItems); + root.processes = rows; } } } property Timer _timer: Timer { interval: 2000 - running: true + running: root.active repeat: true - onTriggered: proc.running = true + triggeredOnStart: true + onTriggered: root._proc.running = true } } diff --git a/modules/qmldir b/modules/qmldir index 327123f..705bf23 100644 --- a/modules/qmldir +++ b/modules/qmldir @@ -34,7 +34,7 @@ IdleInhibitor 1.0 IdleInhibitor.qml Notifications 1.0 Notifications.qml singleton NiriIpc 1.0 NiriIpc.qml singleton SystemStats 1.0 SystemStats.qml -singleton ProcessList 1.0 ProcessList.qml +ProcessList 1.0 ProcessList.qml singleton NotifService 1.0 NotifService.qml NotifItem 1.0 NotifItem.qml NotifPopup 1.0 NotifPopup.qml