use std::sync::Arc;
use calibright::{CalibrightBuilder, CalibrightConfig, CalibrightError, DeviceConfig};
use super::prelude::*;
#[derive(Deserialize, Debug, SmartDefault)]
#[serde(deny_unknown_fields, default)]
pub struct Config {
pub device: Option<String>,
pub format: FormatConfig,
pub missing_format: FormatConfig,
#[default(5.0)]
pub step_width: f64,
#[default(5.0)]
pub minimum: f64,
#[default(100.0)]
pub maximum: f64,
pub cycle: Option<Vec<f64>>,
pub invert_icons: bool,
pub root_scaling: Option<f64>,
pub ddcci_sleep_multiplier: Option<f64>,
pub ddcci_max_tries_write_read: Option<u8>,
}
pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
let mut actions = api.get_actions()?;
api.set_default_actions(&[
(MouseButton::Left, None, "cycle"),
(MouseButton::WheelUp, None, "brightness_up"),
(MouseButton::WheelDown, None, "brightness_down"),
])?;
let format = config.format.with_default(" $icon $brightness ")?;
let missing_format = config
.missing_format
.with_default(" no backlight devices ")?;
let default_cycle = &[config.minimum, config.maximum];
let mut cycle = config
.cycle
.as_deref()
.unwrap_or(default_cycle)
.iter()
.map(|x| x / 100.0)
.cycle();
let step_width = config.step_width / 100.0;
let minimum = config.minimum / 100.0;
let maximum = config.maximum / 100.0;
let mut calibright_defaults = DeviceConfig::default();
if let Some(root_scaling) = config.root_scaling {
calibright_defaults.root_scaling = root_scaling;
}
if let Some(ddcci_sleep_multiplier) = config.ddcci_sleep_multiplier {
calibright_defaults.ddcci_sleep_multiplier = ddcci_sleep_multiplier;
}
if let Some(ddcci_max_tries_write_read) = config.ddcci_max_tries_write_read {
calibright_defaults.ddcci_max_tries_write_read = ddcci_max_tries_write_read;
}
let calibright_config = CalibrightConfig::new_with_defaults(&calibright_defaults)
.await
.error("calibright config error")?;
let mut calibright = CalibrightBuilder::new()
.with_device_regex(config.device.as_deref().unwrap_or("."))
.with_config(calibright_config)
.with_poll_interval(api.error_interval)
.build()
.await
.error("Failed to init calibright")?;
let mut block_error: Option<CalibrightError> = None;
let mut brightness = calibright
.get_brightness()
.await
.map_err(|e| block_error = Some(e))
.unwrap_or_default();
loop {
match block_error {
Some(CalibrightError::NoDevices) => {
let widget = Widget::new()
.with_format(missing_format.clone())
.with_state(State::Critical);
api.set_widget(widget)?;
}
Some(e) => {
api.set_error(Error {
message: None,
cause: Some(Arc::new(e)),
})?;
}
None => {
let mut widget = Widget::new().with_format(format.clone());
let mut icon_value = brightness;
if config.invert_icons {
icon_value = 1.0 - icon_value;
}
widget.set_values(map! {
"icon" => Value::icon_progression("backlight", icon_value),
"brightness" => Value::percents((brightness * 100.0).round())
});
api.set_widget(widget)?;
}
}
loop {
select! {
_ = calibright.next() => {
block_error = calibright
.get_brightness()
.await
.map(|new_brightness| {brightness = new_brightness;})
.err();
break;
},
Some(action) = actions.recv() => match action.as_ref() {
"cycle" => {
if let Some(cycle_brightness) = cycle.next() {
brightness = cycle_brightness;
block_error = calibright
.set_brightness(brightness)
.await
.err();
break;
}
}
"brightness_up" => {
brightness = (brightness + step_width).clamp(minimum, maximum);
block_error = calibright
.set_brightness(brightness)
.await
.err();
break;
}
"brightness_down" => {
brightness = (brightness - step_width).clamp(minimum, maximum);
block_error = calibright
.set_brightness(brightness)
.await
.err();
break;
}
_ => (),
}
}
}
}
}