use config::Config; use std::io::prelude::*; use std::io::BufReader; use std::process::{ChildStdin, ChildStdout, Command, Stdio}; use std::thread; pub struct Bar { stdin: ChildStdin } impl Bar { pub fn new(top: bool, cfg: &Config) -> Bar { let val = cfg.lookup("bar.fonts").unwrap(); let fonts = val.as_slice().unwrap(); let fonts = fonts.iter().flat_map(|elem| elem.as_str()); let mut bar = Command::new("lemonbar"); bar.stdin(Stdio::piped()); bar.stdout(Stdio::piped()); bar.arg("-B"); bar.arg("#FF000000"); if !top { bar.arg("-b"); } for font in fonts { bar.arg("-f"); bar.arg(font); } let child = bar.spawn() .ok() .expect("Failed to start lemonbar"); let stdout = child.stdout.unwrap(); Bar::read_loop(stdout); Bar { stdin: child.stdin.unwrap() } } fn read_loop(stdout: ChildStdout) { thread::spawn(move || { let mut s = String::new(); let mut reader = BufReader::new(stdout); loop { s.clear(); reader.read_line(&mut s).ok().expect("Failed to read from lemonbar"); let mut chars = s.trim().chars(); let kind = chars.next().unwrap(); let name = chars.collect::(); match kind { 'w' => Command::new("bspc") .arg("desktop") .arg("-f") .arg(&name) .output() .ok(), 'm' => Command::new("mpc") .arg("toggle") .output() .ok(), _ => None }; } }); } pub fn send(&mut self, text: &str) { writeln!(&mut self.stdin, "{}", text).ok(); } }