1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
.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 default sink's icon name. Thresholds in thirds, as waybar's wb-icon did.
function volumeIcon(volume, muted) {
// !(> 0) also catches a volume not populated yet (undefined, NaN), which
// would otherwise fall through every test and read as high.
if (muted || !(volume > 0)) return "audio-volume-muted";
if (volume < 0.33) return "audio-volume-low";
if (volume < 0.66) return "audio-volume-medium";
return "audio-volume-high";
}
// A VM's dot colour as a Theme property name, or "" for no dot. States are
// the names Virsh._stateName gives libvirt's enum: "blocked" is what virsh
// list prints as idle, "suspended" is pmsuspended. A shut-off VM only gets a
// dot when it carries a managed save, because starting it is then a restore.
function vmRole(vm) {
if (!vm || !vm.state) return "";
if (vm.state === "shut off") return vm.saved ? "blue" : "";
return ({
"running": "green",
"paused": "yellow",
"blocked": "yellow",
"shutting down": "yellow",
"suspended": "accent",
"crashed": "red",
})[vm.state] || "";
}
// Flag image for a Hyprland active_keymap string, wb-lang's mapping.
function flagFor(keymap) {
if (!keymap || keymap.startsWith("Italian")) return "flag-it.svg";
return "burger.svg";
}
// Active capture kinds as Theme property names, in a fixed order so the
// sliver's segments do not shuffle.
function privacyRoles(mic, cam, loc, scr) {
const out = [];
if (mic) out.push("green");
if (cam) out.push("yellow");
if (loc) out.push("blue");
if (scr) out.push("red");
return out;
}
// Hyprland's openwindow event data: "address,workspace,class,title". The
// title is last and may contain commas, so only the first three fields are
// read.
function parseOpenWindow(data) {
const p = String(data || "").split(",");
return { address: p[0] || "", workspace: p[1] || "", appClass: p[2] || "" };
}
// OBS's outputDuration (ms) as mm:ss, or h:mm:ss past an hour.
function obsElapsed(ms) {
const s = Math.floor((ms > 0 ? ms : 0) / 1000);
const two = n => String(n).padStart(2, "0");
const h = Math.floor(s / 3600);
const mmss = `${two(Math.floor(s / 60) % 60)}:${two(s % 60)}`;
return h ? `${h}:${mmss}` : mmss;
}
// Top-left position for a w x h source on a W x H canvas with margin m, in one
// of the four corners. Anything unrecognised reads as top-left.
function cornerPos(corner, W, H, w, h, m) {
const right = corner === "tr" || corner === "br";
const bottom = corner === "bl" || corner === "br";
return { x: right ? W - w - m : m, y: bottom ? H - h - m : m };
}
|