repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
quickshell/nuguland/Brightness.qml
Rawimport QtQuick
import Quickshell
import Quickshell.Io
import "brightness.js" as Brightness
Item {
id: root
property Osd osdService
property Niri niriService
property string devicePath: "/sys/class/backlight/intel_backlight"
property var ddcDisplays: ({})
property var lastAction: ({})
property var lastOsd: ({})
// Optimistic session level. The sysfs write is async (execDetached) and the
// FileView (blockAllReads) loads once and never reloads, so a fresh read after
// a write returns the stale startup value. Track the level we just set so
// stateJson / the bar reflect it immediately. -1 = not yet set this session.
property real liveLevel: -1
function intText(text, fallback) {
const n = parseInt(String(text || "").trim(), 10);
return isFinite(n) ? n : fallback;
}
function backlightPresent() {
return String(maxFile.text() || "").trim().length > 0 && String(brightnessFile.text() || "").trim().length > 0;
}
function nativeMax() {
return Math.max(1, intText(maxFile.text(), 1));
}
function nativeBrightness() {
return Math.max(1, intText(brightnessFile.text(), nativeMax()));
}
function levelFraction() {
if (!backlightPresent())
return 0;
if (liveLevel >= 0)
return Brightness.clampLevel(liveLevel);
return Brightness.clampLevel(nativeBrightness() / nativeMax());
}
function outputRows() {
return niriService ? niriService.outputList() : [];
}
function osd(value) {
const text = String(Brightness.levelPercent(value));
if (!osdService)
return {
"event": "brightness",
"value": text
};
try {
return JSON.parse(osdService.trigger("brightness", text));
} catch (error) {
return {
"event": "brightness",
"value": text
};
}
}
function stateObject() {
const level = Math.round(levelFraction() * 100) / 100;
const displays = Brightness.displayRows({
"present": backlightPresent(),
"level": level
}, outputRows(), ddcDisplays);
const global = Brightness.globalState(displays);
// Internal panels use backlight; only external displays need DDC setup.
const setupNeeded = displays.some(row => row.kind === "ddc" && !row.controllable);
return {
"level": global.level,
"displays": displays,
"global": global,
"setup": {
"needed": setupNeeded,
"available": true
},
"compact": {
"label": "brightness",
"role": Brightness.levelRole(global.level)
},
"lastAction": lastAction,
"lastOsd": lastOsd
};
}
function stateJson() {
return JSON.stringify(stateObject());
}
function selfTest() {
const cases = [];
const check = (name, got, want) => cases.push({
"case": name,
"ok": JSON.stringify(got) === JSON.stringify(want),
"got": got,
"want": want
});
check("clampLevel(-1)", Brightness.clampLevel(-1), 0);
check("clampLevel(2)", Brightness.clampLevel(2), 1);
check("levelPercent(0.5)", Brightness.levelPercent(0.5), 50);
check("levelRole(0.15)", Brightness.levelRole(0.15), "ui.minor");
check("levelRole(0.5)", Brightness.levelRole(0.5), "ui.accent");
check("levelRole(0.85)", Brightness.levelRole(0.85), "warning");
const fail = cases.filter(c => !c.ok).length;
return JSON.stringify({
"pass": cases.length - fail,
"fail": fail,
"cases": cases
});
}
function applyNative(level) {
if (!backlightPresent())
return;
const value = Brightness.clampLevel(level);
Quickshell.execDetached(["sh", "-c", `d='${devicePath}'; m=$(cat "$d/max_brightness"); n=$(awk -v v=${value} -v m=$m 'BEGIN { x=int(v*m); if (x<1) x=1; if (x>m) x=m; print x }'); printf '%s\n' "$n" > "$d/brightness"`]);
}
function setupDdc() {
lastAction = {
"kind": "setup-ddc"
};
Quickshell.execDetached(["pkexec", "sh", "-c", "pacman -S --needed --noconfirm ddcutil && modprobe i2c-dev && udevadm trigger --subsystem-match=i2c-dev"]);
return stateJson();
}
function setDisplay(id, level) {
const value = Brightness.clampLevel(level);
if (String(id) === "backlight") {
applyNative(value);
liveLevel = value;
}
lastAction = {
"kind": "set-display",
"id": String(id),
"level": Math.round(value * 100) / 100
};
lastOsd = osd(value);
return stateJson();
}
function setAll(level) {
const value = Brightness.clampLevel(level);
const rows = stateObject().displays || [];
for (let i = 0; i < rows.length; i++) {
if (rows[i].controllable)
setDisplay(rows[i].id, value);
}
lastAction = {
"kind": "set-all",
"level": Math.round(value * 100) / 100
};
lastOsd = osd(value);
return stateJson();
}
function setLevel(level) {
const value = Brightness.clampLevel(level);
return setAll(value);
}
function increase() {
return setLevel(levelFraction() + 0.05);
}
function decrease() {
return setLevel(levelFraction() - 0.05);
}
FileView {
id: brightnessFile
path: `${root.devicePath}/brightness`
blockLoading: true
blockAllReads: true
printErrors: false
}
FileView {
id: maxFile
path: `${root.devicePath}/max_brightness`
blockLoading: true
blockAllReads: true
printErrors: false
}
}