C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 33s
Rust / build (pull_request) Successful in 48s
Python / verify (pull_request) Successful in 1m42s
Rust / fmt (pull_request) Successful in 26s
Rust / clippy (pull_request) Successful in 45s
221 lines
4.3 KiB
QML
221 lines
4.3 KiB
QML
pragma Singleton
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import ZShell.Config
|
|
import ZShell.Services
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
readonly property var columnDefs: [
|
|
{
|
|
id: "command",
|
|
title: qsTr("Command"),
|
|
width: 200,
|
|
field: 3
|
|
},
|
|
{
|
|
id: "pid",
|
|
title: qsTr("PID"),
|
|
width: 60,
|
|
field: 1
|
|
},
|
|
{
|
|
id: "cpuUsage",
|
|
title: qsTr("CPU %"),
|
|
width: 70,
|
|
field: 7
|
|
},
|
|
{
|
|
id: "memoryUsage",
|
|
title: qsTr("Memory"),
|
|
width: 90,
|
|
field: 8
|
|
},
|
|
{
|
|
id: "elapsed",
|
|
title: qsTr("Elapsed"),
|
|
width: 80,
|
|
field: 9
|
|
},
|
|
{
|
|
id: "ppid",
|
|
title: qsTr("PPID"),
|
|
width: 60,
|
|
field: 2
|
|
},
|
|
{
|
|
id: "user",
|
|
title: qsTr("User"),
|
|
width: 100,
|
|
field: 11
|
|
},
|
|
{
|
|
id: "uid",
|
|
title: qsTr("UID"),
|
|
width: 60,
|
|
field: 10
|
|
},
|
|
{
|
|
id: "state",
|
|
title: qsTr("State"),
|
|
width: 60,
|
|
field: 5
|
|
},
|
|
{
|
|
id: "sleeping",
|
|
title: qsTr("Sleeping"),
|
|
width: 80,
|
|
field: 6
|
|
},
|
|
{
|
|
id: "commandLine",
|
|
title: qsTr("Command line"),
|
|
width: 240,
|
|
field: 4
|
|
},
|
|
{
|
|
id: "ioReadBytes",
|
|
title: qsTr("IO read"),
|
|
width: 90,
|
|
field: 12
|
|
},
|
|
{
|
|
id: "ioWriteBytes",
|
|
title: qsTr("IO write"),
|
|
width: 90,
|
|
field: 13
|
|
}
|
|
]
|
|
|
|
readonly property var desktopEntries: DesktopEntries.applications.values.map(e => ({
|
|
icon: e.icon,
|
|
command: e.command
|
|
}))
|
|
|
|
Component.onCompleted: {
|
|
Processes.setDesktopEntries(root.desktopEntries);
|
|
Qt.callLater(ensurePinnedFirst);
|
|
}
|
|
|
|
onDesktopEntriesChanged: Processes.setDesktopEntries(root.desktopEntries)
|
|
|
|
readonly property string pinnedColumnId: "command"
|
|
|
|
readonly property var hiddenColumns: {
|
|
const visible = Config.dashboard.processColumns.values.map(e => e.id);
|
|
return root.columnDefs.filter(d => !visible.includes(d.id));
|
|
}
|
|
|
|
function pinnedIndex(): int {
|
|
const values = Config.dashboard.processColumns.values;
|
|
for (let i = 0; i < values.length; i++)
|
|
if (values[i].id === root.pinnedColumnId)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
function ensurePinnedFirst() {
|
|
const i = root.pinnedIndex();
|
|
if (i > 0)
|
|
Qt.callLater(() => {
|
|
const idx = root.pinnedIndex();
|
|
if (idx > 0)
|
|
Config.dashboard.processColumns.move(idx, 0);
|
|
});
|
|
}
|
|
|
|
function defFor(id: string): var {
|
|
for (const def of root.columnDefs)
|
|
if (def.id === id)
|
|
return def;
|
|
return null;
|
|
}
|
|
|
|
function addColumn(id: string) {
|
|
const def = root.defFor(id);
|
|
Config.dashboard.processColumns.insert({
|
|
id: id,
|
|
width: def ? def.width : 100
|
|
});
|
|
}
|
|
|
|
function removeColumn(index: int) {
|
|
const entry = Config.dashboard.processColumns.at(index);
|
|
if (entry && entry.id === root.pinnedColumnId)
|
|
return;
|
|
Config.dashboard.processColumns.remove(index);
|
|
}
|
|
|
|
function moveColumns(from: int, to: int) {
|
|
const list = Config.dashboard.processColumns;
|
|
const entry = list.at(from);
|
|
if (!entry)
|
|
return;
|
|
if (entry.id === root.pinnedColumnId)
|
|
return;
|
|
if (to === 0 && list.at(0)?.id === root.pinnedColumnId)
|
|
return;
|
|
|
|
list.move(from, to);
|
|
|
|
const i = root.pinnedIndex();
|
|
if (i > 0)
|
|
list.move(i, 0);
|
|
}
|
|
|
|
function resizeColumn(index: int, width: real) {
|
|
const entry = Config.dashboard.processColumns.at(index);
|
|
if (entry)
|
|
entry.width = Math.max(50, width);
|
|
}
|
|
|
|
function dampOvershoot(overshoot: real, maxOvershoot: real): real {
|
|
return overshoot / (1 + overshoot / maxOvershoot);
|
|
}
|
|
|
|
function formatCell(id: string, value: var): string {
|
|
switch (id) {
|
|
case "cpuUsage":
|
|
return value.toFixed(1) + "%";
|
|
case "memoryUsage":
|
|
return root.formatBytes(value * 1024);
|
|
case "ioReadBytes":
|
|
case "ioWriteBytes":
|
|
return root.formatBytes(value);
|
|
case "elapsed":
|
|
return root.formatElapsed(value);
|
|
case "sleeping":
|
|
return value ? qsTr("Yes") : qsTr("No");
|
|
default:
|
|
return String(value);
|
|
}
|
|
}
|
|
|
|
function formatBytes(bytes: var): string {
|
|
if (bytes === undefined || bytes === null || bytes <= 0)
|
|
return "0 B";
|
|
const units = ["B", "KiB", "MiB", "GiB", "TiB", "PiB"];
|
|
let v = Number(bytes);
|
|
let i = 0;
|
|
while (v >= 1024 && i < units.length - 1) {
|
|
v /= 1024;
|
|
++i;
|
|
}
|
|
return (i === 0 ? v.toFixed(0) : v.toFixed(1)) + " " + units[i];
|
|
}
|
|
|
|
function formatElapsed(secs: var): string {
|
|
const s = Math.max(0, Math.floor(Number(secs)));
|
|
const h = Math.floor(s / 3600);
|
|
const m = Math.floor((s % 3600) / 60);
|
|
const ss = s % 60;
|
|
if (h > 0)
|
|
return h + "h " + m + "m";
|
|
if (m > 0)
|
|
return m + "m " + ss + "s";
|
|
return ss + "s";
|
|
}
|
|
}
|