Brightness: brings back realtime brightness monitoring for internal(laptop) display.

The pill will open and show the change in real time
This commit is contained in:
LemmyCook 2025-09-06 19:27:32 -04:00
parent 9bc6479c92
commit 36d3a50f21
2 changed files with 70 additions and 28 deletions

View file

@ -37,28 +37,26 @@ Item {
target: getMonitor() target: getMonitor()
ignoreUnknownSignals: true ignoreUnknownSignals: true
function onBrightnessUpdated() { function onBrightnessUpdated() {
Logger.log("Bar-Brightness", "OnBrightnessUpdated") // Ignore if this is the first time we receive an update.
var monitor = getMonitor() // Most likely service just kicked off.
if (!monitor)
return
var currentBrightness = monitor.brightness
// Ignore if this is the first time or if brightness hasn't actually changed
if (!firstBrightnessReceived) { if (!firstBrightnessReceived) {
firstBrightnessReceived = true firstBrightnessReceived = true
monitor.lastBrightness = currentBrightness
return return
} }
// Only show pill if brightness actually changed (not just loaded from settings) pill.show()
if (Math.abs(currentBrightness - monitor.lastBrightness) > 0.1) { hideTimerAfterChange.restart()
pill.show()
}
monitor.lastBrightness = currentBrightness
} }
} }
Timer {
id: hideTimerAfterChange
interval: 2500
running: false
repeat: false
onTriggered: pill.hide()
}
NPill { NPill {
id: pill id: pill

View file

@ -110,9 +110,43 @@ Singleton {
property real lastBrightness: 0 property real lastBrightness: 0
property real queuedBrightness: NaN property real queuedBrightness: NaN
// For internal displays - store the backlight device path
property string backlightDevice: ""
property string brightnessPath: ""
property string maxBrightnessPath: ""
property int maxBrightness: 100
property bool ignoreNextChange: false
// Signal for brightness changes // Signal for brightness changes
signal brightnessUpdated(real newBrightness) signal brightnessUpdated(real newBrightness)
// FileView to watch for external brightness changes (internal displays only)
readonly property FileView brightnessWatcher: FileView {
id: brightnessWatcher
// Only set path for internal displays with a valid brightness path
path: (!monitor.isDdc && !monitor.isAppleDisplay && monitor.brightnessPath !== "") ? monitor.brightnessPath : ""
watchChanges: path !== ""
onFileChanged: {
reload()
if (monitor.ignoreNextChange) {
monitor.ignoreNextChange = false
return
}
if (text() === "")
return
var current = parseInt(text().trim())
if (!isNaN(current) && monitor.maxBrightness > 0) {
var newBrightness = current / monitor.maxBrightness
// Only update if it's actually different (avoid feedback loops)
if (Math.abs(newBrightness - monitor.brightness) > 0.01) {
monitor.brightness = newBrightness
monitor.brightnessUpdated(monitor.brightness)
//Logger.log("Brightness", "External change detected:", monitor.modelData.name, monitor.brightness)
}
}
}
}
// Initialize brightness // Initialize brightness
readonly property Process initProc: Process { readonly property Process initProc: Process {
stdout: StdioCollector { stdout: StdioCollector {
@ -121,8 +155,8 @@ Singleton {
if (dataText === "") { if (dataText === "") {
return return
} }
Logger.log("Brightness", "Raw brightness data for", monitor.modelData.name + ":", dataText)
//Logger.log("Brightness", "Raw brightness data for", monitor.modelData.name + ":", dataText)
if (monitor.isAppleDisplay) { if (monitor.isAppleDisplay) {
var val = parseInt(dataText) var val = parseInt(dataText)
if (!isNaN(val)) { if (!isNaN(val)) {
@ -140,14 +174,20 @@ Singleton {
} }
} }
} else { } else {
// Internal backlight // Internal backlight - parse the response which includes device path
var parts = dataText.split(" ") var lines = dataText.split("\n")
if (parts.length >= 2) { if (lines.length >= 3) {
var current = parseInt(parts[0]) monitor.backlightDevice = lines[0]
var max = parseInt(parts[1]) monitor.brightnessPath = monitor.backlightDevice + "/brightness"
monitor.maxBrightnessPath = monitor.backlightDevice + "/max_brightness"
var current = parseInt(lines[1])
var max = parseInt(lines[2])
if (!isNaN(current) && !isNaN(max) && max > 0) { if (!isNaN(current) && !isNaN(max) && max > 0) {
monitor.maxBrightness = max
monitor.brightness = current / max monitor.brightness = current / max
Logger.log("Brightness", "Internal brightness:", current + "/" + max + " =", monitor.brightness) Logger.log("Brightness", "Internal brightness:", current + "/" + max + " =", monitor.brightness)
Logger.log("Brightness", "Using backlight device:", monitor.backlightDevice)
} }
} }
} }
@ -171,7 +211,7 @@ Singleton {
function increaseBrightness(): void { function increaseBrightness(): void {
var stepSize = Settings.data.brightness.brightnessStep / 100.0 var stepSize = Settings.data.brightness.brightnessStep / 100.0
setBrightnessDebounced(brightness + stepSize) setBrightnessDebounced(monitor.brightness + stepSize)
} }
function decreaseBrightness(): void { function decreaseBrightness(): void {
@ -183,22 +223,23 @@ Singleton {
value = Math.max(0, Math.min(1, value)) value = Math.max(0, Math.min(1, value))
var rounded = Math.round(value * 100) var rounded = Math.round(value * 100)
if (Math.round(brightness * 100) === rounded) if (Math.round(monitor.brightness * 100) === rounded)
return return
if (isDdc && timer.running) { if (isDdc && timer.running) {
queuedBrightness = value monitor.queuedBrightness = value
return return
} }
brightness = value monitor.brightness = value
brightnessUpdated(brightness) brightnessUpdated(monitor.brightness)
if (isAppleDisplay) { if (isAppleDisplay) {
Quickshell.execDetached(["asdbctl", "set", rounded]) Quickshell.execDetached(["asdbctl", "set", rounded])
} else if (isDdc) { } else if (isDdc) {
Quickshell.execDetached(["ddcutil", "-b", busNum, "setvcp", "10", rounded]) Quickshell.execDetached(["ddcutil", "-b", busNum, "setvcp", "10", rounded])
} else { } else {
monitor.ignoreNextChange = true
Quickshell.execDetached(["brightnessctl", "s", rounded + "%"]) Quickshell.execDetached(["brightnessctl", "s", rounded + "%"])
} }
@ -208,7 +249,7 @@ Singleton {
} }
function setBrightnessDebounced(value: real): void { function setBrightnessDebounced(value: real): void {
queuedBrightness = value monitor.queuedBrightness = value
timer.restart() timer.restart()
} }
@ -218,8 +259,11 @@ Singleton {
} else if (isDdc) { } else if (isDdc) {
initProc.command = ["ddcutil", "-b", busNum, "getvcp", "10", "--brief"] initProc.command = ["ddcutil", "-b", busNum, "getvcp", "10", "--brief"]
} else { } else {
// Internal backlight - try to find the first available backlight device // Internal backlight - find the first available backlight device and get its info
initProc.command = ["sh", "-c", "for dev in /sys/class/backlight/*; do if [ -f \"$dev/brightness\" ] && [ -f \"$dev/max_brightness\" ]; then echo \"$(cat $dev/brightness) $(cat $dev/max_brightness)\"; break; fi; done"] // This now returns: device_path, current_brightness, max_brightness (on separate lines)
initProc.command = ["sh", "-c", "for dev in /sys/class/backlight/*; do "
+ " if [ -f \"$dev/brightness\" ] && [ -f \"$dev/max_brightness\" ]; then " + " echo \"$dev\"; "
+ " cat \"$dev/brightness\"; " + " cat \"$dev/max_brightness\"; " + " break; " + " fi; " + "done"]
} }
initProc.running = true initProc.running = true
} }