Add widget: Brightness
- Use `/sys/class/backlight/` values
This commit is contained in:
parent
fa206d7f42
commit
8851869f07
84
src/widgets/brightnesswidget.rs
Normal file
84
src/widgets/brightnesswidget.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use super::common::run_cmd;
|
||||
use crate::TopBar;
|
||||
use slint::{ComponentHandle, SharedString, Timer, TimerMode};
|
||||
use std::{fs, time::Duration};
|
||||
|
||||
/// Read a file and trim whitespace
|
||||
fn read_file(path: &str) -> Option<String> {
|
||||
fs::read_to_string(path).ok().map(|s| s.trim().to_string())
|
||||
}
|
||||
|
||||
/// Return (`brightness`, `max_brightness`)
|
||||
/// Use the first device listed under /sys/class/backlight/
|
||||
fn read_brightness_raw() -> Option<(u32, u32)> {
|
||||
let base = "/sys/class/backlight";
|
||||
let mut entries = fs::read_dir(base).ok()?;
|
||||
|
||||
// First device (intel_backlight, amdgpu_bl0, acpi_video0, etc.)
|
||||
let dev = entries.next()?.ok()?.path();
|
||||
|
||||
let b = read_file(dev.join("brightness").to_str()?)?.parse().ok()?;
|
||||
let m = read_file(dev.join("max_brightness").to_str()?)?
|
||||
.parse()
|
||||
.ok()?;
|
||||
|
||||
Some((b, m))
|
||||
}
|
||||
|
||||
/// Convert brightness raw values into a 0–100% percentage
|
||||
fn brightness_percent() -> u8 {
|
||||
if let Some((b, m)) = read_brightness_raw()
|
||||
&& m > 0
|
||||
{
|
||||
return ((b as f32 / m as f32) * 100.0).round() as u8;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// Pick an icon based on percentage
|
||||
fn brightness_icon(p: u8) -> SharedString {
|
||||
let icon = match p {
|
||||
0 => "", // off
|
||||
1..=20 => "", // low
|
||||
21..=60 => "", // medium
|
||||
_ => "", // high
|
||||
};
|
||||
SharedString::from(icon)
|
||||
}
|
||||
|
||||
/// Tooltip text displayed when hovering the icon
|
||||
fn brightness_tooltip(p: u8) -> String {
|
||||
format!("Brightness: {p}%")
|
||||
}
|
||||
|
||||
/// Start timer to update brightness every second
|
||||
fn start_brightness_updater(ui: &TopBar) {
|
||||
let weak = ui.as_weak();
|
||||
|
||||
let timer = Box::leak(Box::new(Timer::default()));
|
||||
timer.start(TimerMode::Repeated, Duration::from_secs(1), move || {
|
||||
if let Some(ui) = weak.upgrade() {
|
||||
// Read brightness
|
||||
let p = brightness_percent();
|
||||
|
||||
// Update properties on the root component
|
||||
ui.set_brightness_icon(brightness_icon(p));
|
||||
ui.set_brightness_tooltip(brightness_tooltip(p).into());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Public entry for this widget
|
||||
pub fn install(ui: &TopBar) {
|
||||
let weak = ui.as_weak();
|
||||
|
||||
// Click callback (open brightness settings)
|
||||
ui.on_show_brightness(move || {
|
||||
if weak.upgrade().is_some() {
|
||||
run_cmd("xclock"); // Fix later
|
||||
}
|
||||
});
|
||||
|
||||
// Start updating
|
||||
start_brightness_updater(ui);
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
mod batterywidget;
|
||||
mod brightnesswidget;
|
||||
mod common;
|
||||
mod datewidget;
|
||||
mod timewidget;
|
||||
@ -11,6 +12,7 @@ pub fn install_callbacks(ui: &TopBar) {
|
||||
datewidget::install(ui);
|
||||
batterywidget::install(ui);
|
||||
volumewidget::install(ui);
|
||||
brightnesswidget::install(ui);
|
||||
|
||||
// In the future:
|
||||
// networkwidget::install(ui);
|
||||
|
||||
@ -27,7 +27,6 @@ export component TopBar inherits Window {
|
||||
in property <color> battery_bg_clicked;*/
|
||||
callback show_battery();
|
||||
|
||||
|
||||
// Volume widget
|
||||
in property <string> volume_tooltip;
|
||||
in property <string> volume_icon;
|
||||
@ -37,6 +36,15 @@ export component TopBar inherits Window {
|
||||
in property <color> volume_bg_clicked;*/
|
||||
callback show_volume();
|
||||
|
||||
// brightness widget
|
||||
in property <string> brightness_tooltip;
|
||||
in property <string> brightness_icon;
|
||||
/*in property <color> brightness_icon_color;
|
||||
in property <color> brightness_bg_normal;
|
||||
in property <color> brightness_bg_hover;
|
||||
in property <color> brightness_bg_clicked;*/
|
||||
callback show_brightness();
|
||||
|
||||
title: "chocobar";
|
||||
width: bar_width *1px;
|
||||
height: bar_height *1px;
|
||||
@ -81,6 +89,18 @@ export component TopBar inherits Window {
|
||||
HorizontalLayout {
|
||||
alignment: end; // Right-align
|
||||
|
||||
// SquareIconWidget - brightness
|
||||
SquareIconWidget {
|
||||
bar_height: root.bar_height;
|
||||
icon_text: root.brightness_icon;
|
||||
tooltip_text: root.brightness_tooltip;
|
||||
/*icon_color: root.brightness_icon_color;
|
||||
bg_normal: root.brightness_bg_normal;
|
||||
bg_hover: root.brightness_bg_hover;
|
||||
bg_clicked: root.brightness_bg_clicked;*/
|
||||
square_btn_callback => root.show_brightness();
|
||||
}
|
||||
|
||||
// SquareIconWidget - Volume
|
||||
SquareIconWidget {
|
||||
bar_height: root.bar_height;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user