diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-16 09:34:51 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-16 09:35:05 +0200 |
| commit | cb936e93be75bae93fbd5a81f39376cd31142e71 (patch) | |
| tree | 89df0e88f53b87170c6f1e4e24236c68b87ee20e /desktop/island/perf/Perf.js | |
| parent | cf89a5d88fb738883e9663b9e44afcc7b7f98807 (diff) | |
| download | quickshell-cb936e93be75bae93fbd5a81f39376cd31142e71.tar.gz quickshell-cb936e93be75bae93fbd5a81f39376cd31142e71.zip | |
docs(spec): user details in the drawer
A drawer row greets the login user and opens a page that edits name,
email, avatar, language and location, written where other programs
already read them: AccountsService (and through it the passwd GECOS
LibreOffice reads), KDE's emaildefaults and the global git config, with
the surname shortened to an initial for git.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/island/perf/Perf.js')
| -rw-r--r-- | desktop/island/perf/Perf.js | 187 |
1 files changed, 0 insertions, 187 deletions
diff --git a/desktop/island/perf/Perf.js b/desktop/island/perf/Perf.js deleted file mode 100644 index b853f50..0000000 --- a/desktop/island/perf/Perf.js +++ /dev/null @@ -1,187 +0,0 @@ -.pragma library - -// Copyright (C) 2026 Danilo M. <danix@danix.xyz> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// The performance panel's parsing and arithmetic, kept pure so it runs under -// node (test_perf.js). Perf.qml does the reading; everything here takes text -// or numbers and returns values. A reading that cannot be made is null, and -// the panel draws null as a dash. - -const UNITS = { "": 1, B: 1, KiB: 1024, MiB: 1024 ** 2, GiB: 1024 ** 3 }; - -// A public IP older than this is not shown: by then the fetch has failed -// for hours, and an address that may no longer be ours is worse than a dash. -const STALE = 4 * 3600; - -// One {total, idle} per cpu line of /proc/stat; index 0 is the aggregate, -// then the cores in file order. idle counts iowait, as conky did. Only the -// first eight fields are summed: guest and guest_nice are already inside -// user and nice, and adding them again overstates load while VMs run. -function cpuTimes(stat) { - const out = []; - for (const line of stat.split("\n")) { - const m = /^cpu\d*\s+(.*)$/.exec(line); - if (!m) continue; - const v = m[1].trim().split(/\s+/).map(Number); - if (v.length < 5) continue; - out.push({ total: v.slice(0, 8).reduce((a, b) => a + b, 0), idle: v[3] + v[4] }); - } - return out; -} - -// Percent busy between two samples. -function load(prev, cur) { - if (!prev || !cur) return null; - const dt = cur.total - prev.total; - if (dt <= 0) return null; - return Math.max(0, Math.min(100, 100 * (1 - (cur.idle - prev.idle) / dt))); -} - -// {total, used} in bytes; used is MemTotal - MemAvailable. -function meminfo(text) { - const kb = key => { - const m = new RegExp("^" + key + ":\\s+(\\d+)", "m").exec(text); - return m ? Number(m[1]) * 1024 : null; - }; - const total = kb("MemTotal"), avail = kb("MemAvailable"); - if (total === null || avail === null) return null; - return { total: total, used: total - avail }; -} - -// Rows of `df -P -B1`. The header fails the percent match and is skipped. -// host is the NFS server from the device field, "" for a local disk, so the -// panel labels shares without an address in the repo. -function df(text) { - const out = []; - for (const line of text.split("\n")) { - const m = /^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)%\s+(\S+)\s*$/.exec(line); - if (!m) continue; - const h = /^([^/:]+):/.exec(m[1]); - out.push({ mount: m[6], host: h ? h[1] : "", size: Number(m[2]), - used: Number(m[3]), pct: Number(m[5]) }); - } - return out; -} - -// VRAM in bytes from the fdinfo scan: drm-resident-vram0 of every xe fd, -// counted once per drm-client-id because a client holds several fds. -function vram(text) { - const fds = {}; - for (const line of text.split("\n")) { - const m = /^([^:]*):(drm-[\w-]+):\s*(.*)$/.exec(line); - if (!m) continue; - (fds[m[1]] = fds[m[1]] || {})[m[2]] = m[3]; - } - const seen = {}; - let total = null; - for (const path in fds) { - const fd = fds[path]; - const id = fd["drm-client-id"]; - const n = /^(\d+)\s*(\w*)/.exec(fd["drm-resident-vram0"] || ""); - if (fd["drm-driver"] !== "xe" || !id || !n || seen[id]) continue; - seen[id] = true; - total = (total || 0) + Number(n[1]) * (UNITS[n[2]] || 1); - } - return total; -} - -// Bytes per second between two counter readings. A counter that went -// backwards (interface reset) gives null rather than a negative spike. -function rate(prev, cur, secs) { - if (prev === null || cur === null || !(secs > 0) || cur < prev) return null; - return (cur - prev) / secs; -} - -// `grep -H . /sys/class/hwmon/hwmon*/name` -> {chip: dir}. hwmonN numbers -// change across boots, so chips are found by name. -function hwmonMap(text) { - const map = {}; - for (const line of text.split("\n")) { - const m = /^(.*)\/name:(.+)$/.exec(line); - if (m && !(m[2] in map)) map[m[2]] = m[1]; - } - return map; -} - -// `ip -4 -o addr show <iface>` -> the first address, without its prefix. -function lanAddr(text) { - const m = /\binet (\d+\.\d+\.\d+\.\d+)\//.exec(text); - return m ? m[1] : ""; -} - -// The first model name in /proc/cpuinfo, trimmed the way conky trimmed it. -function cpuModel(cpuinfo) { - const m = /^model name\s*:\s*(.+)$/m.exec(cpuinfo); - if (!m) return ""; - return m[1].replace(/\((R|TM|tm)\)/g, "") - .replace(/^\s*\d+th Gen\s+/, "") - .replace(/^\s*(AMD|Intel)\s+/, "") - .replace(/\s+\d+-Core Processor.*$/, "") - .replace(/\s+/g, " ").trim(); -} - -// "ok", "warn", "crit", or "" for a value that could not be read. -function band(v, warn, crit) { - if (v === null || v === undefined) return ""; - return v >= crit ? "crit" : v >= warn ? "warn" : "ok"; -} - -// The worst of a list of bands; unknowns never raise it. -function worst(bands) { - if (bands.indexOf("crit") >= 0) return "crit"; - if (bands.indexOf("warn") >= 0) return "warn"; - return "ok"; -} - -function isIPv4(s) { - return /^(\d{1,3}\.){3}\d{1,3}$/.test(s) && s.split(".").every(o => Number(o) <= 255); -} - -// conky's cache format: "ip <addr>" and "fetched <epoch>" lines. -function parsePubip(text) { - const ip = /^ip (\S+)$/m.exec(text), at = /^fetched (\d+)$/m.exec(text); - return ip && at && isIPv4(ip[1]) ? { ip: ip[1], fetched: Number(at[1]) } : null; -} - -function formatPubip(ip, fetched) { - return "ip " + ip + "\nfetched " + fetched + "\n"; -} - -// What the panel shows and whether the icon warns. Only a fresh value can -// mismatch: a failed fetch leaves the old one to go stale, never to alarm. -function ipCheck(pub, now, pin) { - const fresh = !!pub && now - pub.fetched < STALE; - return { ip: fresh ? pub.ip : "", mismatch: fresh && !!pin && pub.ip !== pin }; -} - -// Whether a fetch is due: no value yet, or one at least `every` seconds old. -function due(pub, now, every) { - return !pub || now - pub.fetched >= every; -} - -// A history with v appended, oldest dropped past n. -function push(list, v, n) { - const out = list.concat([v]); - return out.length > n ? out.slice(out.length - n) : out; -} - -function bytes(n) { - if (n === null || n === undefined) return "--"; - const u = ["B", "K", "M", "G", "T"]; - let i = 0; - while (n >= 1024 && i < u.length - 1) { n /= 1024; i++; } - return (i ? n.toFixed(1) : String(Math.round(n))) + u[i]; -} - -function speed(n) { - return n === null || n === undefined ? "--" : bytes(n) + "/s"; -} |
