Compare commits

..

No commits in common. "8fdd9692e610d81a2c1c15004193166295356f2a" and "6748649033828071d18710ce045b8151ca801dae" have entirely different histories.

8 changed files with 73 additions and 83 deletions

View file

@ -31,7 +31,7 @@ M.BarSection {
NumberAnimation { NumberAnimation {
target: root target: root
property: "_blinkOpacity" property: "_blinkOpacity"
to: 0.45 to: 0.2
duration: 400 duration: 400
easing.type: Easing.InOutQuad easing.type: Easing.InOutQuad
} }

View file

@ -32,11 +32,6 @@ M.BarSection {
readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered
readonly property bool _showPanel: _anyHover || _pinned readonly property bool _showPanel: _anyHover || _pinned
property M.ProcessList _procs: M.ProcessList {
sortBy: "cpu"
active: root._showPanel
}
on_AnyHoverChanged: { on_AnyHoverChanged: {
if (_anyHover) if (_anyHover)
_unpinTimer.stop(); _unpinTimer.stop();
@ -263,7 +258,7 @@ M.BarSection {
// Top processes by CPU // Top processes by CPU
Repeater { Repeater {
model: root._procs.processes model: M.ProcessList.byCpu
delegate: Item { delegate: Item {
required property var modelData required property var modelData

View file

@ -21,11 +21,6 @@ M.BarSection {
readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered
readonly property bool _showPanel: _anyHover || _pinned readonly property bool _showPanel: _anyHover || _pinned
property M.ProcessList _procs: M.ProcessList {
sortBy: "mem"
active: root._showPanel
}
on_AnyHoverChanged: { on_AnyHoverChanged: {
if (_anyHover) if (_anyHover)
_unpinTimer.stop(); _unpinTimer.stop();
@ -228,7 +223,7 @@ M.BarSection {
// Top processes by memory // Top processes by memory
Repeater { Repeater {
model: root._procs.processes model: M.ProcessList.byMem
delegate: Item { delegate: Item {
required property var modelData required property var modelData

View file

@ -11,29 +11,6 @@ QtObject {
signal windowFocusChanged(var windowId) signal windowFocusChanged(var windowId)
signal windowOpenedOrChanged(var window) signal windowOpenedOrChanged(var window)
property string focusedTitle: ""
property string focusedAppId: ""
property bool overviewOpen: false
property var _focusedProc: Process {
running: true
command: ["niri", "msg", "--json", "focused-window"]
stdout: StdioCollector {
onStreamFinished: {
try {
const w = JSON.parse(text);
if (w) {
root.focusedTitle = w.title || "";
root.focusedAppId = w.app_id || "";
} else {
root.focusedTitle = "";
root.focusedAppId = "";
}
} catch (e) {}
}
}
}
property var _eventStream: Process { property var _eventStream: Process {
running: true running: true
command: ["niri", "msg", "--json", "event-stream"] command: ["niri", "msg", "--json", "event-stream"]
@ -46,24 +23,10 @@ QtObject {
root.workspacesChanged(ev.WorkspacesChanged.workspaces); root.workspacesChanged(ev.WorkspacesChanged.workspaces);
else if (ev.WorkspaceActivated !== undefined) else if (ev.WorkspaceActivated !== undefined)
root.workspaceActivated(ev.WorkspaceActivated.id, ev.WorkspaceActivated.focused); root.workspaceActivated(ev.WorkspaceActivated.id, ev.WorkspaceActivated.focused);
else if (ev.WindowFocusChanged !== undefined) { else if (ev.WindowFocusChanged !== undefined)
root.windowFocusChanged(ev.WindowFocusChanged.id); root.windowFocusChanged(ev.WindowFocusChanged.id);
if (ev.WindowFocusChanged.id !== null) else if (ev.WindowOpenedOrChanged !== undefined)
root._focusedProc.running = true;
else {
root.focusedTitle = "";
root.focusedAppId = "";
}
} else if (ev.OverviewOpenedOrClosed !== undefined) {
root.overviewOpen = ev.OverviewOpenedOrClosed.is_open;
} else if (ev.WindowOpenedOrChanged !== undefined) {
root.windowOpenedOrChanged(ev.WindowOpenedOrChanged.window); root.windowOpenedOrChanged(ev.WindowOpenedOrChanged.window);
const w = ev.WindowOpenedOrChanged.window;
if (w.is_focused) {
root.focusedTitle = w.title || "";
root.focusedAppId = w.app_id || "";
}
}
} catch (e) {} } catch (e) {}
} }
} }

View file

@ -37,18 +37,10 @@ PanelWindow {
property color uC1: M.Theme.base0E property color uC1: M.Theme.base0E
property color uC2: M.Theme.base09 property color uC2: M.Theme.base09
Connections { // Wave animation: 6s sweep + 8s pause
target: M.NiriIpc
function onOverviewOpenChanged() {
if (!M.NiriIpc.overviewOpen)
fx.uWavePhase = -200;
}
}
// Wave animation: 6s sweep + 8s pause, only while overview is open
SequentialAnimation on uWavePhase { SequentialAnimation on uWavePhase {
loops: Animation.Infinite loops: Animation.Infinite
running: M.NiriIpc.overviewOpen running: true
NumberAnimation { NumberAnimation {
from: -200 from: -200
to: fx.width + 200 to: fx.width + 200

View file

@ -1,43 +1,48 @@
pragma Singleton
import QtQuick import QtQuick
import Quickshell.Io import Quickshell.Io
import "." as M
QtObject { QtObject {
id: root id: root
property string sortBy: "cpu" // "cpu" or "mem" property var byCpu: []
property var byMem: []
property int maxItems: 8 property int maxItems: 8
property bool active: false
property var processes: []
property Process _proc: Process { property Process _proc: Process {
command: ["sh", "-c", "ps --no-headers -eo pid,pcpu,pmem,comm --sort=-%" + root.sortBy + " | head -" + root.maxItems] 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}'"]
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
const rows = []; const rows = [];
for (const line of text.trim().split("\n")) { for (const line of text.trim().split("\n")) {
if (!line) if (!line)
continue; continue;
const p = line.trim().split(/\s+/); const p = line.split("|");
if (p.length < 4) if (p.length < 5)
continue; continue;
const cmd = p[4].replace(/^.*\//, "");
rows.push({ rows.push({
"pid": parseInt(p[0]), "user": p[0],
"cpu": parseFloat(p[1]), "pid": parseInt(p[1]),
"mem": parseFloat(p[2]), "cpu": parseFloat(p[2]),
"cmd": p.slice(3).join(" ") "mem": parseFloat(p[3]),
"cmd": cmd || p[4]
}); });
} }
root.processes = rows; 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);
} }
} }
} }
property Timer _timer: Timer { property Timer _timer: Timer {
interval: 2000 interval: 2000
running: root.active running: true
repeat: true repeat: true
triggeredOnStart: true onTriggered: proc.running = true
onTriggered: root._proc.running = true
} }
} }

View file

@ -1,23 +1,63 @@
import QtQuick import QtQuick
import QtQuick.Effects import QtQuick.Effects
import Quickshell import Quickshell
import Quickshell.Io
import Quickshell.Widgets import Quickshell.Widgets
import "." as M import "." as M
M.BarSection { M.BarSection {
id: root id: root
spacing: M.Theme.moduleSpacing spacing: M.Theme.moduleSpacing
visible: M.Modules.windowTitle.enable && M.NiriIpc.focusedTitle !== "" visible: M.Modules.windowTitle.enable && root._title !== ""
tooltip: M.NiriIpc.focusedAppId ? M.NiriIpc.focusedAppId + "\n" + M.NiriIpc.focusedTitle : M.NiriIpc.focusedTitle tooltip: root._appId ? root._appId + "\n" + root._title : root._title
property string _title: ""
property string _appId: ""
readonly property string _iconSource: { readonly property string _iconSource: {
if (!M.NiriIpc.focusedAppId) if (!root._appId)
return ""; return "";
const entry = DesktopEntries.heuristicLookup(M.NiriIpc.focusedAppId); const entry = DesktopEntries.heuristicLookup(root._appId);
return entry ? Quickshell.iconPath(entry.icon) : ""; return entry ? Quickshell.iconPath(entry.icon) : "";
} }
// Initial state niri event-stream doesn't replay current focus
Process {
id: initProc
running: true
command: ["niri", "msg", "--json", "focused-window"]
stdout: StdioCollector {
onStreamFinished: {
try {
const w = JSON.parse(text);
if (w) {
root._title = w.title || "";
root._appId = w.app_id || "";
}
} catch (e) {}
}
}
}
// Live updates via shared NiriIpc singleton
Connections {
target: M.NiriIpc
function onWindowFocusChanged(windowId) {
if (windowId !== null)
initProc.running = true;
else {
root._title = "";
root._appId = "";
}
}
function onWindowOpenedOrChanged(window) {
if (window.is_focused) {
root._title = window.title || "";
root._appId = window.app_id || "";
}
}
}
IconImage { IconImage {
visible: root._iconSource !== "" visible: root._iconSource !== ""
source: root._iconSource source: root._iconSource
@ -31,7 +71,7 @@ M.BarSection {
} }
M.BarLabel { M.BarLabel {
label: M.NiriIpc.focusedTitle label: root._title
color: root.accentColor color: root.accentColor
elide: Text.ElideRight elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter

View file

@ -34,7 +34,7 @@ IdleInhibitor 1.0 IdleInhibitor.qml
Notifications 1.0 Notifications.qml Notifications 1.0 Notifications.qml
singleton NiriIpc 1.0 NiriIpc.qml singleton NiriIpc 1.0 NiriIpc.qml
singleton SystemStats 1.0 SystemStats.qml singleton SystemStats 1.0 SystemStats.qml
ProcessList 1.0 ProcessList.qml singleton ProcessList 1.0 ProcessList.qml
singleton NotifService 1.0 NotifService.qml singleton NotifService 1.0 NotifService.qml
NotifItem 1.0 NotifItem.qml NotifItem 1.0 NotifItem.qml
NotifPopup 1.0 NotifPopup.qml NotifPopup 1.0 NotifPopup.qml