diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 76 |
1 files changed, 53 insertions, 23 deletions
diff --git a/src/main.rs b/src/main.rs index c6cc525..befd750 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,42 +18,72 @@ mod utils; mod wm_info_provider; use signal_hook::consts::*; -use signal_hook_tokio::Signals; -use futures::stream::StreamExt; +use std::{io::ErrorKind, os::fd::AsRawFd}; use wayrs_client::connection::Connection; +use wayrs_client::IoMode; + +use nix::{ + errno::Errno, + fcntl::OFlag, + poll::{poll, PollFd, PollFlags}, +}; use state::State; -#[tokio::main(flavor = "current_thread")] -async fn main() -> anyhow::Result<()> { - let mut signals = Signals::new([SIGUSR1])?; +fn main() -> anyhow::Result<()> { + let (sig_read, sig_write) = nix::unistd::pipe2(OFlag::O_NONBLOCK | OFlag::O_CLOEXEC)?; + signal_hook::low_level::pipe::register(SIGUSR1, sig_write)?; let mut conn = Connection::connect()?; - let globals = conn.async_collect_initial_globals().await?; + let globals = conn.blocking_collect_initial_globals()?; let mut state = State::new(&mut conn, &globals); - conn.async_flush().await?; + conn.flush(IoMode::Blocking)?; + + let mut fds = Vec::with_capacity(3); + fds.push(PollFd::new(conn.as_raw_fd(), PollFlags::POLLIN)); + fds.push(PollFd::new(sig_read, PollFlags::POLLIN)); + if let Some(cmd_fd) = state.status_cmd_fd() { + fds.push(PollFd::new(cmd_fd, PollFlags::POLLIN)); + } loop { - tokio::select! { - recv_events = conn.async_recv_events() => { - recv_events?; - conn.dispatch_events(&mut state); - conn.async_flush().await?; - } - reat_res = state.status_cmd_read() => { - if let Err(e) = reat_res.and_then(|_| state.status_cmd_notify_available(&mut conn)) { - if let Some(mut status_cmd) = state.shared_state.status_cmd.take() { - let _ = status_cmd.child.kill(); - } - state.set_error(&mut conn, e.to_string()); + match poll(&mut fds, -1) { + Ok(_) => (), + Err(Errno::EINTR) => continue, + Err(e) => bail!(e), + } + + if fds[0].any().unwrap_or(false) { + match conn.recv_events(IoMode::NonBlocking) { + Ok(()) => { + conn.dispatch_events(&mut state); + conn.flush(IoMode::Blocking)?; } - conn.async_flush().await?; + Err(e) if e.kind() == ErrorKind::WouldBlock => (), + Err(e) => return Err(e.into()), } - Some(signal) = signals.next() => match signal { - SIGUSR1 => state.toggle_visibility(&mut conn), - _ => unreachable!(), + } + + if fds[1].any().unwrap_or(false) { + nix::unistd::read(sig_read, &mut [0; 1])?; + state.toggle_visibility(&mut conn); + } + + if fds.len() > 2 && fds[2].any().unwrap_or(false) { + match state.shared_state.status_cmd.as_mut().unwrap().read() { + Ok(None) => (), + Ok(Some(blocks)) => { + state.set_blocks(&mut conn, blocks); + conn.flush(IoMode::Blocking)?; + } + Err(e) => { + let _ = state.shared_state.status_cmd.take().unwrap().child.kill(); + fds.pop().unwrap(); + state.set_error(&mut conn, e); + conn.flush(IoMode::Blocking)?; + } } } } |
