Each brightness key ran omarchy-brightness-display: resolving the focused monitor and backlight device, checking for an Apple display, reading, writing and reading back through brightnessctl, then omarchy-osd over a qs IPC client. That is 64-133ms from keypress to OSD depending on load, on keys that repeat while held. The brightness up and down keys now dispatch global shortcuts. On an internal panel the shell reads the level from sysfs, steps it by the script's rules, writes it with one brightnessctl, and shows the OSD from the level read back. A press overlapping one still being applied is dropped, as the script's flock drops it. External and Apple displays fall back to the script, which drives them over DDC or their own helper. The absolute and precise brightness keys still run the script. Across 24 steps from eight starting levels the shell and the script land on identical levels, and keypress to OSD drops to ~31ms. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
102 lines
3.2 KiB
QML
102 lines
3.2 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Hyprland
|
|
import Quickshell.Io
|
|
import qs.Commons
|
|
import "BrightnessModel.js" as BrightnessModel
|
|
|
|
// The display brightness keys, arriving as global shortcuts. On the internal
|
|
// panel they step the backlight here: one brightnessctl write and the OSD in
|
|
// process, instead of omarchy-brightness-display resolving the monitor and
|
|
// device, reading, writing and reading back, then an IPC client for the OSD.
|
|
// They step, clamp and read back the way that script does, so either path
|
|
// lands on the same level and OSD. External and Apple displays go through the
|
|
// script, which drives them over DDC or their own helper.
|
|
Item {
|
|
id: root
|
|
|
|
// The shell host, for summoning the OSD.
|
|
property var host: null
|
|
// The backlight omarchy-hw-display picks. Devices do not come and go at
|
|
// runtime, but each press refreshes it for the next.
|
|
property string device: ""
|
|
readonly property string devicePath: device ? "/sys/class/backlight/" + device : ""
|
|
|
|
// Returns false when the focused display is not one to handle here, so the
|
|
// caller falls back to the script.
|
|
function handle(action) {
|
|
var monitor = Hyprland.focusedMonitor
|
|
var name = monitor ? String(monitor.name || "") : ""
|
|
if (!/^(eDP|LVDS|DSI)-/.test(name) || !device) return false
|
|
if (action !== "raise" && action !== "lower") return false
|
|
|
|
// The script drops a press that overlaps one still being applied, so key
|
|
// repeat cannot race the writes.
|
|
if (setProc.running) return true
|
|
|
|
var max = readNumber(maxFile)
|
|
if (!(max > 0)) return false
|
|
var current = Math.round(100 * readNumber(brightnessFile) / max)
|
|
|
|
setProc.command = ["brightnessctl", "-q", "-d", device, "set", BrightnessModel.brightnessKeyTarget(action, current) + "%"]
|
|
setProc.running = true
|
|
return true
|
|
}
|
|
|
|
// reload() reads in the background, so wait for it: text() would otherwise
|
|
// still hold the previous reading, and a level changed elsewhere (the
|
|
// monitor panel, a script) would step from the wrong place.
|
|
function readNumber(file) {
|
|
file.reload()
|
|
file.waitForJob()
|
|
return Number(String(file.text() || "").trim())
|
|
}
|
|
|
|
// The payload omarchy-osd builds, from the level read back after the write.
|
|
function showOsd() {
|
|
var max = readNumber(maxFile)
|
|
if (!host || !(max > 0)) return
|
|
var percent = Math.round(100 * readNumber(brightnessFile) / max)
|
|
host.summon("omarchy.osd", JSON.stringify({
|
|
icon: "brightness",
|
|
message: "",
|
|
value: String(percent),
|
|
progressText: percent + "%",
|
|
max: "100",
|
|
duration: ""
|
|
}))
|
|
}
|
|
|
|
FileView {
|
|
id: brightnessFile
|
|
path: root.devicePath ? root.devicePath + "/brightness" : ""
|
|
blockLoading: true
|
|
printErrors: false
|
|
}
|
|
|
|
FileView {
|
|
id: maxFile
|
|
path: root.devicePath ? root.devicePath + "/max_brightness" : ""
|
|
blockLoading: true
|
|
printErrors: false
|
|
}
|
|
|
|
Process {
|
|
id: setProc
|
|
onExited: {
|
|
root.showOsd()
|
|
if (!deviceProc.running) deviceProc.running = true
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: deviceProc
|
|
command: ["omarchy-hw-display"]
|
|
running: true
|
|
stdout: StdioCollector {
|
|
waitForEnd: true
|
|
onStreamFinished: root.device = String(text || "").trim()
|
|
}
|
|
}
|
|
}
|