summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs76
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)?;
+ }
}
}
}