// ── violet-chaton v2 — OSD widget ─────────────────────────────────────────── // Overlay volume / brightness avec gradient Mitsuri const audio = Service.import("audio"); // ── OSD reveal timer ──────────────────────────────────────────────────────── let osdTimeout = null; const showOSD = (window) => { window.visible = true; if (osdTimeout) clearTimeout(osdTimeout); osdTimeout = setTimeout(() => { window.visible = false; }, 1500); }; // ── Volume OSD ────────────────────────────────────────────────────────────── const VolumeOSD = () => { const icon = Widget.Label({ className: "icon" }); const progress = Widget.ProgressBar(); const label = Widget.Label({ className: "label" }); const box = Widget.Box({ className: "osd", children: [icon, progress, label], connections: [[audio, (self) => { const vol = audio.speaker?.volume || 0; const muted = audio.speaker?.isMuted; icon.label = muted ? "󰝟" : vol > 0.66 ? "󰕾" : vol > 0.33 ? "󰖀" : "󰕿"; progress.value = vol; label.label = `${Math.round(vol * 100)}%`; }, "speaker-changed"]], }); return box; }; // ── Brightness OSD ────────────────────────────────────────────────────────── const BrightnessOSD = () => { const icon = Widget.Label({ className: "icon", label: "󰃞" }); const progress = Widget.ProgressBar(); const label = Widget.Label({ className: "label" }); const getBrightness = () => { try { const max = Number(Utils.exec("brightnessctl max")); const cur = Number(Utils.exec("brightnessctl get")); return max > 0 ? cur / max : 0; } catch { return 0; } }; const box = Widget.Box({ className: "osd", children: [icon, progress, label], connections: [[500, (self) => { const val = getBrightness(); progress.value = val; label.label = `${Math.round(val * 100)}%`; }]], }); return box; }; // ── OSD windows ───────────────────────────────────────────────────────────── export const OSD = (monitor) => { const volumeWin = Widget.Window({ name: `osd-volume-${monitor}`, monitor, anchor: ["bottom"], layer: "overlay", visible: false, child: VolumeOSD(), }); const brightnessWin = Widget.Window({ name: `osd-brightness-${monitor}`, monitor, anchor: ["bottom"], layer: "overlay", visible: false, child: BrightnessOSD(), }); // Auto-show on volume change Utils.merge([audio.speaker?.bind("volume")], () => showOSD(volumeWin)); return [volumeWin, brightnessWin]; };