bar.rs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. use config::Config;
  2. use std::io::prelude::*;
  3. use std::io::BufReader;
  4. use std::process::{ChildStdin, ChildStdout, Command, Stdio};
  5. use std::thread;
  6. pub struct Bar {
  7. stdin: ChildStdin
  8. }
  9. impl Bar {
  10. pub fn new(top: bool, cfg: &Config) -> Bar {
  11. let val = cfg.lookup("bar.fonts").unwrap();
  12. let fonts = val.as_slice().unwrap();
  13. let fonts = fonts.iter().flat_map(|elem| elem.as_str());
  14. let mut bar = Command::new("lemonbar");
  15. bar.stdin(Stdio::piped());
  16. bar.stdout(Stdio::piped());
  17. bar.arg("-B");
  18. bar.arg("#FF000000");
  19. if !top {
  20. bar.arg("-b");
  21. }
  22. for font in fonts {
  23. bar.arg("-f");
  24. bar.arg(font);
  25. }
  26. let child = bar.spawn()
  27. .ok()
  28. .expect("Failed to start lemonbar");
  29. let stdout = child.stdout.unwrap();
  30. Bar::read_loop(stdout);
  31. Bar { stdin: child.stdin.unwrap() }
  32. }
  33. fn read_loop(stdout: ChildStdout) {
  34. thread::spawn(move || {
  35. let mut s = String::new();
  36. let mut reader = BufReader::new(stdout);
  37. loop {
  38. s.clear();
  39. reader.read_line(&mut s).ok().expect("Failed to read from lemonbar");
  40. let mut chars = s.trim().chars();
  41. let kind = chars.next().unwrap();
  42. let name = chars.collect::<String>();
  43. match kind {
  44. 'w' => Command::new("bspc")
  45. .arg("desktop")
  46. .arg("-f")
  47. .arg(&name)
  48. .output()
  49. .ok(),
  50. 'm' => Command::new("mpc")
  51. .arg("toggle")
  52. .output()
  53. .ok(),
  54. _ => None
  55. };
  56. }
  57. });
  58. }
  59. pub fn send(&mut self, text: &str) {
  60. writeln!(&mut self.stdin, "{}", text).ok();
  61. }
  62. }