diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c9f55d..d07786c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.4.3 (2026-10-05) + +- Backlight: a config with a `!backlight` widget on a machine without `/sys/class/backlight` entries (or with a `device` name that does not exist) panicked at start ("did not find backlight device"), fatal with `panic = "abort"`. The widget now warns once on stderr, renders empty and ignores clicks, so one config can be shared between a laptop and a desktop. + ## 0.4.2 (2026-10-03) - Fonts: a `font_paths` entry pointing at a file that does not exist on this machine made the font-loader thread panic and abort wldash ("Font file not found"). Pinned paths that are missing now fall back to fontconfig by name, with one line on stderr; a font that cannot be resolved at all exits with a clear message instead of a backtrace. diff --git a/Cargo.lock b/Cargo.lock index 8889aff..9a4d0c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1071,7 +1071,7 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "wldash" -version = "0.4.2" +version = "0.4.3" dependencies = [ "calloop", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 75f5b2c..8ecd9b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wldash" -version = "0.4.2" +version = "0.4.3" edition = "2024" [profile.release] diff --git a/PKGBUILD b/PKGBUILD index 41695ed..231d045 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -4,7 +4,7 @@ # project.uhhm.no (namespace bl). pkgver is the version; the tag has # to agree with it and with Cargo.toml. pkgname=wldash -pkgver=0.4.2 +pkgver=0.4.3 pkgrel=1 pkgdesc="Dashboard/launcher/control-panel for wlroots-style Wayland compositors (layer-shell)" arch=('x86_64' 'aarch64') diff --git a/src/widgets/backlight.rs b/src/widgets/backlight.rs index a3393ad..7245b40 100644 --- a/src/widgets/backlight.rs +++ b/src/widgets/backlight.rs @@ -26,7 +26,11 @@ fn write_file_as_u64(path: &Path, value: u64) -> Result<(), Error> { } pub struct Backlight { - device_path: PathBuf, + /// `None` when no backlight exists on this machine: the widget then + /// renders empty and ignores clicks instead of taking wldash down. + /// Configs are shared between hosts, so a laptop config running on a + /// desktop must not panic here. + device_path: Option, cur: u64, max: u64, dirty: bool, @@ -46,10 +50,13 @@ fn find_device() -> Option { impl Backlight { fn update(&mut self) { - if let Ok(cur) = read_file_as_u64(self.device_path.join("brightness").as_path()) { + let Some(dev) = &self.device_path else { + return; + }; + if let Ok(cur) = read_file_as_u64(dev.join("brightness").as_path()) { self.cur = cur; } - if let Ok(max) = read_file_as_u64(self.device_path.join("max_brightness").as_path()) { + if let Ok(max) = read_file_as_u64(dev.join("max_brightness").as_path()) { self.max = max; } } @@ -58,11 +65,30 @@ impl Backlight { #[allow(clippy::new_ret_no_self)] pub fn new(path: Option<&str>, fm: &mut FontMap, font: &'static str, size: f32) -> BarWidget { let device_path = match path { - Some(path) => Some(Path::new("/sys/class/backlight").join(path)), - None => find_device(), + Some(path) => { + let p = Path::new("/sys/class/backlight").join(path); + if p.is_dir() { + Some(p) + } else { + eprintln!( + "wldash: backlight device {:?} not found, widget disabled", + p + ); + None + } + } + None => { + let p = find_device(); + if p.is_none() { + eprintln!( + "wldash: no backlight device under /sys/class/backlight, widget disabled" + ); + } + p + } }; let mut dev = Backlight { - device_path: device_path.expect("did not find backlight device"), + device_path, cur: 0, max: 0, dirty: true, @@ -77,9 +103,13 @@ impl Backlight { } pub fn set(&mut self, brightness: f32) { + let Some(dev) = &self.device_path else { + return; + }; let val = (self.max as f32 * brightness.clamp(0.0, 1.0)) as u64; - let _ = write_file_as_u64(self.device_path.join("brightness").as_path(), val); - if let Ok(cur) = read_file_as_u64(self.device_path.join("brightness").as_path()) { + let brightness_path = dev.join("brightness"); + let _ = write_file_as_u64(&brightness_path, val); + if let Ok(cur) = read_file_as_u64(&brightness_path) { self.cur = cur; } } @@ -93,12 +123,14 @@ impl BarWidgetImpl for Backlight { self.dirty } fn value(&mut self) -> f32 { + self.dirty = false; + if self.device_path.is_none() { + return 0.0; + } if self.max == 0 || self.cur > self.max { - // what. + // Sysfs handed us nonsense; show full rather than a bogus ratio. return 1.0; } - - self.dirty = false; self.cur as f32 / self.max as f32 } fn color(&self) -> Color {