- AGS v3.1.0 (Astal/GTK3) Ghost Shell avec ghost mode (heartbeat + hover reveal) - Modules : clock, battery, volume (interactif), network, MPRIS, CPU/RAM, systray - Brain Power panel (Super + B) — lecture live focus/todos/session - tetardtek_ prompt avec curseur clignotant - Palette violet-chaton v2 documentée (Mitsuri Kanroji gradient magenta → green) - Autostart COSMIC via .desktop - Archive AGS v1 conservée pour référence
96 lines
3.3 KiB
JavaScript
96 lines
3.3 KiB
JavaScript
// ── 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];
|
|
};
|