// Backlight slider, via brightnessctl. // // This machine drives an external DisplayPort monitor and has no backlight // class device at all (brightnessctl only reports keyboard/NIC LEDs), so the // row removes itself rather than sitting there as a dead control. Probed once // at startup — backlight devices do not appear and disappear. import QtQuick import Quickshell import Quickshell.Io import qs.widgets import qs.config Item { id: root property bool available: false property real value: 0 visible: root.available implicitHeight: root.available ? 32 : 0 // `-m` is the machine-readable form: name,class,current,percent,max Process { running: true command: ["brightnessctl", "-m", "-c", "backlight", "-l"] stdout: StdioCollector { onStreamFinished: root.parseDevices(this.text) } } function parseDevices(text: string): void { for (const line of text.trim().split("\n")) { const fields = line.split(","); if (fields.length < 5 || fields[1] !== "backlight") continue; root.available = true; root.value = parseInt(fields[3]) / 100; return; } } function apply(v: real): void { root.value = v; // Never go fully dark: a 0% backlight looks like a broken shell. Quickshell.execDetached(["brightnessctl", "-c", "backlight", "-q", "set", Math.max(1, Math.round(v * 100)) + "%"]); } // ValueSlider draws its own leading icon, but symbolic icons need // recolouring to be visible — see ThemedIcon. ThemedIcon { id: glyph anchors.left: parent.left anchors.leftMargin: 6 anchors.verticalCenter: parent.verticalCenter size: 17 icon: "display-brightness-symbolic" } ValueSlider { anchors.left: glyph.right anchors.leftMargin: 12 anchors.right: parent.right anchors.rightMargin: 32 anchors.verticalCenter: parent.verticalCenter value: root.value onMoved: v => root.apply(v) } }