Read brightness state with one status command

This commit is contained in:
Samuel Onoja committed 2026-09-27 07:28:44 +01:00
1 parent 08a586612f
commit 5450384386
1 file changed
+43 -9
+43 -9
View File
@@ -365,15 +365,31 @@ fn battery() -> Option<Battery> {
} }
fn brightness() -> Option<u8> { fn brightness() -> Option<u8> {
let max = run("brightnessctl", &["--class=backlight", "max"]) parse_brightness(
.ok()? &run(
.parse::<f64>() "brightnessctl",
.ok()?; &["--class=backlight", "--machine-readable", "info"],
let current = run("brightnessctl", &["--class=backlight", "get"]) )
.ok()? .ok()?,
.parse::<f64>() )
.ok()?; }
(max > 0.0 && current.is_finite())
fn parse_brightness(value: &str) -> Option<u8> {
// device,class,current,percentage,max. Compute the ratio ourselves to
// preserve the previous rounding rather than using the CLI's percentage.
let mut fields = value.trim().split(',');
let _device = fields.next()?;
if fields.next()? != "backlight" {
return None;
}
let current = fields.next()?.parse::<f64>().ok()?;
let _percentage = fields.next()?;
let max = fields.next()?.parse::<f64>().ok()?;
(fields.next().is_none()
&& max.is_finite()
&& max > 0.0
&& current.is_finite()
&& current >= 0.0)
.then(|| (100.0 * current / max).round().clamp(0.0, 100.0) as u8) .then(|| (100.0 * current / max).round().clamp(0.0, 100.0) as u8)
} }
@@ -486,6 +502,24 @@ fn execute(action: &Action, settings: Option<&[String]>) -> Result<(), String> {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn brightness_info_preserves_ratio_rounding_and_rejects_bad_devices() {
assert_eq!(parse_brightness("intel,backlight,72,18%,400"), Some(18));
assert_eq!(parse_brightness("panel,backlight,2,66%,3\n"), Some(67));
assert_eq!(parse_brightness("panel,backlight,0,0%,400"), Some(0));
for value in [
"",
"panel,leds,1,1%,100",
"panel,backlight,1,0%,0",
"panel,backlight,NaN,0%,100",
"panel,backlight,1,0%,inf",
"panel,backlight,-1,0%,100",
"panel,backlight,1,0%,100,extra",
] {
assert_eq!(parse_brightness(value), None, "{value}");
}
}
#[test] #[test]
fn polling_waits_for_a_write_and_uses_the_completed_generation() { fn polling_waits_for_a_write_and_uses_the_completed_generation() {
let shared = Arc::new((Mutex::new((7, true, None, false)), Condvar::new())); let shared = Arc::new((Mutex::new((7, true, None, false)), Condvar::new()));