diff --git a/Cargo.lock b/Cargo.lock index abd27b6..654c188 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,9 +279,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" +checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" [[package]] name = "log" @@ -413,9 +413,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ "unicode-xid", ] @@ -652,9 +652,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" dependencies = [ "proc-macro2", "quote", @@ -663,9 +663,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.23.6" +version = "0.23.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f3c0db8e08e06cfd352a043bd0143498fb7d42783a6e941da83b55464eb27d2" +checksum = "b3fb8adaa82317f1e8a040281807f411803c9111303cfe129b4abb4a14b2c223" dependencies = [ "cfg-if", "core-foundation-sys 0.8.3", diff --git a/swayrbar/src/module.rs b/swayrbar/src/module.rs index 7fba67b..4995a3d 100644 --- a/swayrbar/src/module.rs +++ b/swayrbar/src/module.rs @@ -44,8 +44,5 @@ pub trait BarModuleFn: Sync + Send { } } fn build(&self) -> s::Block; - fn subst_args<'a>(&'a self, _cmd: &'a [String]) -> Option> { - // None means, no substitution are to be made. - None - } + fn subst_args<'a>(&'a self, _cmd: &'a [String]) -> Option>; } diff --git a/swayrbar/src/module/battery.rs b/swayrbar/src/module/battery.rs index 8e46c55..4e10448 100644 --- a/swayrbar/src/module/battery.rs +++ b/swayrbar/src/module/battery.rs @@ -20,12 +20,20 @@ use crate::module::BarModuleFn; use crate::shared::fmt::format_placeholders; use battery as bat; use std::collections::HashSet; +use std::sync::Mutex; use swaybar_types as s; const NAME: &str = "battery"; +struct State { + state_of_charge: f32, + state_of_health: f32, + state: String, +} + pub struct BarModuleBattery { config: config::ModuleConfig, + state: Mutex, } fn get_refreshed_batteries( @@ -42,56 +50,70 @@ fn get_refreshed_batteries( Ok(bats) } -fn get_text(cfg: &config::ModuleConfig) -> String { +fn set_state(state: &Mutex) { // FIXME: Creating the Manager on every refresh is bad but internally // it uses an Rc so if I keep it as a field of BarModuleBattery, that // cannot be Sync. let manager = battery::Manager::new().unwrap(); match get_refreshed_batteries(&manager) { Ok(bats) => { - if bats.is_empty() { - return String::new(); - } - format_placeholders!(&cfg.format, cfg.is_html_escape(), { - "state_of_charge" => bats.iter() - .map(|b| b.state_of_charge().value) - .sum::() - / bats.len() as f32 * 100_f32, - "state_of_health" => bats.iter() - .map(|b| b.state_of_health().value) - .sum::() - / bats.len() as f32 * 100_f32, - "state" => { - let states = bats.iter() - .map(|b| format!("{:?}", b.state())) - .collect::>(); - if states.len() == 1 { - states.iter().next().unwrap().to_owned() - } else { - let mut comma_sep_string = String::from("["); - let mut first = true; - for state in states { - if first { - comma_sep_string = comma_sep_string + &state; - first = false; - } else { - comma_sep_string = comma_sep_string - + ", " + &state; - } + let mut state = state.lock().expect("Could not lock state."); + state.state_of_charge = + bats.iter().map(|b| b.state_of_charge().value).sum::() + / bats.len() as f32 + * 100_f32; + state.state_of_health = + bats.iter().map(|b| b.state_of_health().value).sum::() + / bats.len() as f32 + * 100_f32; + state.state = { + let states = bats + .iter() + .map(|b| format!("{:?}", b.state())) + .collect::>(); + if states.len() == 1 { + states.iter().next().unwrap().to_owned() + } else { + let mut comma_sep_string = String::from("["); + let mut first = true; + for state in states { + if first { + comma_sep_string = comma_sep_string + &state; + first = false; + } else { + comma_sep_string = comma_sep_string + ", " + &state; } - comma_sep_string += "]"; - comma_sep_string } - }, - }) + comma_sep_string += "]"; + comma_sep_string + } + } + } + Err(err) => { + log::error!("Could not update battery state: {}", err); } - Err(err) => format!("{}", err), } } +fn get_text(fmt: &str, html_escape: bool, state: &Mutex) -> String { + let state = state.lock().expect("Could not lock state."); + format_placeholders!(fmt, html_escape, { + "state_of_charge" => state.state_of_charge, + "state_of_health" => state.state_of_health, + "state" => state.state.as_str(), + }) +} + impl BarModuleFn for BarModuleBattery { fn create(config: config::ModuleConfig) -> Box { - Box::new(BarModuleBattery { config }) + Box::new(BarModuleBattery { + config, + state: Mutex::new(State { + state_of_charge: 0.0, + state_of_health: 0.0, + state: "Unknown".to_owned(), + }), + }) } fn default_config(instance: String) -> config::ModuleConfig { @@ -109,7 +131,12 @@ impl BarModuleFn for BarModuleBattery { } fn build(&self) -> s::Block { - let text = get_text(&self.config); + set_state(&self.state); + let text = get_text( + &self.config.format, + self.config.is_html_escape(), + &self.state, + ); s::Block { name: Some(NAME.to_owned()), instance: Some(self.config.instance.clone()), @@ -130,4 +157,12 @@ impl BarModuleFn for BarModuleBattery { separator_block_width: None, } } + + fn subst_args<'a>(&'a self, cmd: &'a [String]) -> Option> { + Some( + cmd.iter() + .map(|arg| get_text(arg, false, &self.state)) + .collect(), + ) + } } diff --git a/swayrbar/src/module/date.rs b/swayrbar/src/module/date.rs index 7d799f8..ca6ed91 100644 --- a/swayrbar/src/module/date.rs +++ b/swayrbar/src/module/date.rs @@ -25,6 +25,10 @@ pub struct BarModuleDate { config: config::ModuleConfig, } +fn chrono_format(s: &str) -> String { + chrono::Local::now().format(s).to_string() +} + impl BarModuleFn for BarModuleDate { fn create(cfg: config::ModuleConfig) -> Box { Box::new(BarModuleDate { config: cfg }) @@ -44,8 +48,21 @@ impl BarModuleFn for BarModuleDate { &self.config } + fn get_on_click_map( + &self, + name: &str, + instance: &str, + ) -> Option<&std::collections::HashMap>> { + let cfg = self.get_config(); + if name == cfg.name && instance == cfg.instance { + cfg.on_click.as_ref() + } else { + None + } + } + fn build(&self) -> s::Block { - let text = chrono::Local::now().format(&self.config.format).to_string(); + let text = chrono_format(&self.config.format); s::Block { name: Some(NAME.to_owned()), instance: Some(self.config.instance.clone()), @@ -66,4 +83,8 @@ impl BarModuleFn for BarModuleDate { separator_block_width: None, } } + + fn subst_args<'a>(&'a self, cmd: &'a [String]) -> Option> { + Some(cmd.iter().map(|arg| chrono_format(arg)).collect()) + } } diff --git a/swayrbar/src/module/sysinfo.rs b/swayrbar/src/module/sysinfo.rs index 43d8b6b..aba8756 100644 --- a/swayrbar/src/module/sysinfo.rs +++ b/swayrbar/src/module/sysinfo.rs @@ -145,4 +145,9 @@ impl BarModuleFn for BarModuleSysInfo { separator_block_width: None, } } + + fn subst_args<'a>(&'a self, _cmd: &'a [String]) -> Option> { + // TOOD: Set a State we can refer to here. + todo!() + } }