summaryrefslogtreecommitdiff
path: root/src/status_cmd.rs
diff options
context:
space:
mode:
authorMax Verevkin <maxxverrr@gmail.com>2022-04-06 18:47:13 +0300
committerMax Verevkin <maxxverrr@gmail.com>2022-04-06 18:49:52 +0300
commit9009579fd9328c4beaea7daa47533aa6dc4df11b (patch)
tree2e47121f887efc39ae968cdcd0e66b58a7a0f655 /src/status_cmd.rs
parentb759c7ec2ac5411f7dd254bb19a20c27a166e7e2 (diff)
downloadi3bar-mango-9009579fd9328c4beaea7daa47533aa6dc4df11b.tar.gz
heavy refacotring, improve error handling, make `command` optional
Diffstat (limited to 'src/status_cmd.rs')
-rw-r--r--src/status_cmd.rs119
1 files changed, 50 insertions, 69 deletions
diff --git a/src/status_cmd.rs b/src/status_cmd.rs
index e77e4b2..9824be4 100644
--- a/src/status_cmd.rs
+++ b/src/status_cmd.rs
@@ -1,97 +1,78 @@
-use crate::Surface;
use std::cell::RefCell;
-use std::io::Result;
-use std::io::{BufRead, BufReader, Write};
-use std::os::unix::prelude::{AsRawFd, RawFd};
-use std::process::{ChildStdin, ChildStdout, Command, Stdio};
+use std::io::{BufRead, BufReader, Result, Write};
+use std::os::unix::prelude::AsRawFd;
+use std::process::{Child, ChildStdin, ChildStdout, Command, Stdio};
use std::rc::Rc;
+use smithay_client_toolkit::reexports::calloop::{self, LoopHandle};
+
use crate::i3bar_protocol::{Block, Event, Protocol};
-use crate::pointer_btn::PointerBtn;
+use crate::BarState;
-#[derive(Clone)]
pub struct StatusCmd {
- inner: Rc<RefCell<Inner>>,
-}
-
-struct Inner {
+ child: Child,
output: BufReader<ChildStdout>,
input: ChildStdin,
protocol: Protocol,
- blocks: Rc<RefCell<Vec<Block>>>,
- surfaces: Rc<RefCell<Vec<Surface>>>,
-}
-
-impl AsRawFd for StatusCmd {
- fn as_raw_fd(&self) -> RawFd {
- self.inner.borrow().output.get_ref().as_raw_fd()
- }
-}
-
-impl Inner {
- pub fn notify_available(&mut self) -> Result<()> {
- let buf = self.output.fill_buf()?;
- self.protocol.process_new_bytes(buf)?;
- let consumed = buf.len();
- self.output.consume(consumed);
- if let Some(new_blocks) = self.protocol.get_blocks() {
- *self.blocks.borrow_mut() = new_blocks;
- for s in &mut *self.surfaces.borrow_mut() {
- s.blocks_need_update = true;
- }
- }
- Ok(())
- }
}
impl StatusCmd {
- pub fn new(
- cmd: &str,
- blocks: Rc<RefCell<Vec<Block>>>,
- surfaces: Rc<RefCell<Vec<Surface>>>,
- ) -> Result<Self> {
+ pub fn new(cmd: &str) -> Result<Self> {
let mut child = Command::new("sh")
.args(["-c", &format!("exec {cmd}")])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
- let output = BufReader::new(child.stdout.take().unwrap());
+ let output = child.stdout.take().unwrap();
let input = child.stdin.take().unwrap();
Ok(Self {
- inner: Rc::new(RefCell::new(Inner {
- output,
- input,
- protocol: Protocol::Unknown,
- blocks,
- surfaces,
- })),
+ child,
+ output: BufReader::new(output),
+ input,
+ protocol: Protocol::Unknown,
})
}
- pub fn notify_available(&mut self) -> Result<()> {
- self.inner.borrow_mut().notify_available()
+ pub fn notify_available(&mut self) -> Result<Option<Vec<Block>>> {
+ let buf = self.output.fill_buf()?;
+ self.protocol.process_new_bytes(buf)?;
+ let consumed = buf.len();
+ self.output.consume(consumed);
+ Ok(self.protocol.get_blocks())
}
- pub fn send_click_event(
- &mut self,
- button: PointerBtn,
- name: Option<&str>,
- instance: Option<&str>,
- ) -> Result<()> {
- let mut inner = self.inner.borrow_mut();
- if inner.protocol.supports_clicks() {
- writeln!(
- inner.input,
- "{}",
- serde_json::to_string(&Event {
- name,
- instance,
- button,
- ..Default::default()
- })
- .unwrap()
- )?;
+ pub fn send_click_event(&mut self, event: &Event) -> Result<()> {
+ if self.protocol.supports_clicks() {
+ writeln!(self.input, "{}", serde_json::to_string(event).unwrap(),)?;
}
Ok(())
}
+
+ pub fn quick_insert(&self, handle: LoopHandle<()>, bar_state: Rc<RefCell<BarState>>) {
+ handle
+ .insert_source(
+ calloop::generic::Generic::new(
+ self.output.get_ref().as_raw_fd(),
+ calloop::Interest {
+ readable: true,
+ writable: false,
+ },
+ calloop::Mode::Level,
+ ),
+ move |ready, _, _| {
+ if ready.readable {
+ bar_state.borrow_mut().notify_available()?;
+ Ok(calloop::PostAction::Continue)
+ } else {
+ let mut bar_state = bar_state.borrow_mut();
+ bar_state.set_error("error reading from status command");
+ if let Some(mut child) = bar_state.status_cmd.take() {
+ let _ = child.child.kill();
+ }
+ Ok(calloop::PostAction::Remove)
+ }
+ },
+ )
+ .expect("failed to inser calloop source");
+ }
}