diff --git a/src/bar.rs b/src/bar.rs index d6ace69..1723ead 100644 --- a/src/bar.rs +++ b/src/bar.rs @@ -18,7 +18,9 @@ use crate::bar::module::BarModuleFn; use env_logger::Env; use serde_json; -use std::thread; +use serde_json::Deserializer; +use std::{sync::Arc, thread}; +use swaybar_types as sbt; pub mod config; pub mod module; @@ -29,8 +31,7 @@ pub fn start() { let config = config::Config::default(); - thread::spawn(handle_input); - let mods: Vec> = vec![ + let mods: Arc>> = Arc::new(vec![ module::window::BarModuleWindow::create( module::window::BarModuleWindow::default_config("0".to_owned()), ), @@ -43,16 +44,28 @@ pub fn start() { module::date::BarModuleDate::create( module::date::BarModuleDate::default_config("0".to_owned()), ), - ]; + ]); + let mods_for_input = mods.clone(); + thread::spawn(move || handle_input(mods_for_input)); generate_status(&mods, config.refresh_interval); } -pub fn handle_input() { +pub fn handle_input(mods: Arc>>) { // TODO: Read stdin and react to click events. + // let stream = + // Deserializer::from_reader(std::io::stdin()).into_iter::(); + // for click in stream { + // log::debug!("Click received: {:?}", click); + // } + + // let lines = std::io::stdin().lock(); + // for l in lines { + // log::debug!("{}", l); + // } } pub fn generate_status(mods: &[Box], refresh_interval: u64) { - println!("{{\"version\": 1}}"); + println!("{{\"version\": 1, \"click_events\": true}}"); // status_command should output an infinite array meaning we emit an // opening [ and never the closing bracket. println!("["); diff --git a/src/bar/module.rs b/src/bar/module.rs index 30a9fc2..0f47a0b 100644 --- a/src/bar/module.rs +++ b/src/bar/module.rs @@ -21,7 +21,7 @@ pub mod date; pub mod sysinfo; pub mod window; -pub trait BarModuleFn { +pub trait BarModuleFn: Sync + Send { fn create(config: config::ModuleConfig) -> Box where Self: Sized; diff --git a/src/bar/module/battery.rs b/src/bar/module/battery.rs index b881f80..6fc2128 100644 --- a/src/bar/module/battery.rs +++ b/src/bar/module/battery.rs @@ -19,7 +19,6 @@ use crate::bar::config; use crate::bar::module::BarModuleFn; use crate::fmt_replace::fmt_replace; use battery as bat; -use std::cell::RefCell; use std::collections::HashSet; use swaybar_types as s; @@ -27,18 +26,15 @@ const NAME: &str = "battery"; pub struct BarModuleBattery { config: config::ModuleConfig, - manager: RefCell, } fn get_refreshed_batteries( - manager: &RefCell, + manager: &bat::Manager, ) -> Result, bat::Error> { - let m = manager.borrow(); - let mut bats = vec![]; - for bat in m.batteries()? { + for bat in manager.batteries()? { let mut bat = bat?; - if m.refresh(&mut bat).is_ok() { + if manager.refresh(&mut bat).is_ok() { bats.push(bat); } } @@ -46,11 +42,12 @@ fn get_refreshed_batteries( Ok(bats) } -fn get_text( - manager: &RefCell, - cfg: &config::ModuleConfig, -) -> String { - match get_refreshed_batteries(manager) { +fn get_text(cfg: &config::ModuleConfig) -> String { + // 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(); @@ -94,12 +91,7 @@ fn get_text( impl BarModuleFn for BarModuleBattery { fn create(config: config::ModuleConfig) -> Box { - Box::new(BarModuleBattery { - config, - manager: RefCell::new( - bat::Manager::new().expect("Could not create Manager"), - ), - }) + Box::new(BarModuleBattery { config }) } fn default_config(instance: String) -> config::ModuleConfig { @@ -120,7 +112,7 @@ impl BarModuleFn for BarModuleBattery { } fn build(&self) -> s::Block { - let text = get_text(&self.manager, &self.config); + let text = get_text(&self.config); s::Block { name: Some(Self::name().to_owned()), instance: Some(self.config.instance.clone()), diff --git a/src/bar/module/sysinfo.rs b/src/bar/module/sysinfo.rs index 2695f89..aa00b6d 100644 --- a/src/bar/module/sysinfo.rs +++ b/src/bar/module/sysinfo.rs @@ -18,7 +18,7 @@ use crate::bar::config; use crate::bar::module::BarModuleFn; use crate::fmt_replace::fmt_replace; -use std::cell::RefCell; +use std::sync::Mutex; use std::sync::Once; use swaybar_types as s; use sysinfo as si; @@ -29,7 +29,7 @@ const NAME: &str = "sysinfo"; pub struct BarModuleSysInfo { config: config::ModuleConfig, - system: RefCell, + system: Mutex, } struct OnceRefresher { @@ -45,23 +45,22 @@ impl OnceRefresher { } } - fn refresh_cpu(&self, sys: &RefCell) { - self.cpu.call_once(|| sys.borrow_mut().refresh_cpu()); + fn refresh_cpu(&self, sys: &mut si::System) { + self.cpu.call_once(|| sys.refresh_cpu()); } - fn refresh_memory(&self, sys: &RefCell) { - self.memory.call_once(|| sys.borrow_mut().refresh_memory()); + fn refresh_memory(&self, sys: &mut si::System) { + self.memory.call_once(|| sys.refresh_memory()); } } -fn get_cpu_usage(sys: &RefCell, upd: &OnceRefresher) -> f32 { +fn get_cpu_usage(sys: &mut si::System, upd: &OnceRefresher) -> f32 { upd.refresh_cpu(sys); - sys.borrow().global_processor_info().cpu_usage() + sys.global_processor_info().cpu_usage() } -fn get_memory_usage(sys: &RefCell, upd: &OnceRefresher) -> f64 { +fn get_memory_usage(sys: &mut si::System, upd: &OnceRefresher) -> f64 { upd.refresh_memory(sys); - let sys = sys.borrow(); sys.used_memory() as f64 * 100_f64 / sys.total_memory() as f64 } @@ -73,12 +72,12 @@ enum LoadAvg { } fn get_load_average( - sys: &RefCell, + sys: &mut si::System, avg: LoadAvg, upd: &OnceRefresher, ) -> f64 { upd.refresh_cpu(sys); - let load_avg = sys.borrow().load_average(); + let load_avg = sys.load_average(); match avg { LoadAvg::One => load_avg.one, LoadAvg::Five => load_avg.five, @@ -90,7 +89,7 @@ impl BarModuleFn for BarModuleSysInfo { fn create(config: config::ModuleConfig) -> Box { Box::new(BarModuleSysInfo { config, - system: RefCell::new(si::System::new_all()), + system: Mutex::new(si::System::new_all()), }) } @@ -107,16 +106,19 @@ impl BarModuleFn for BarModuleSysInfo { s::Block { name: Some(Self::name().to_owned()), instance: Some(self.config.instance.clone()), - full_text: fmt_replace!(&self.config.format, self.config.html_escape, { - "cpu_usage" => get_cpu_usage(&self.system, &updater), - "mem_usage" => get_memory_usage(&self.system, &updater), - "load_avg_1" => get_load_average(&self.system, - LoadAvg::One, &updater), - "load_avg_5" => get_load_average(&self.system, - LoadAvg::Five, &updater), - "load_avg_15" => get_load_average(&self.system, - LoadAvg::Fifteen, &updater), - }), + full_text: { + let mut sys = self.system.lock().unwrap(); + fmt_replace!(&self.config.format, self.config.html_escape, { + "cpu_usage" => get_cpu_usage(&mut sys, &updater), + "mem_usage" => get_memory_usage(&mut sys, &updater), + "load_avg_1" => get_load_average(&mut sys, + LoadAvg::One, &updater), + "load_avg_5" => get_load_average(&mut sys, + LoadAvg::Five, &updater), + "load_avg_15" => get_load_average(&mut sys, + LoadAvg::Fifteen, &updater), + }) + }, align: Some(s::Align::Left), markup: Some(s::Markup::Pango), short_text: None,