summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event_loop.rs31
-rw-r--r--src/main.rs13
-rw-r--r--src/wm_info_provider/hyprland.rs2
3 files changed, 30 insertions, 16 deletions
diff --git a/src/event_loop.rs b/src/event_loop.rs
index ec0d65c..89f6f81 100644
--- a/src/event_loop.rs
+++ b/src/event_loop.rs
@@ -16,8 +16,8 @@ pub struct EventLoopCtx<'a> {
/// Simple callback-based event loop. Implemented using `poll`.
pub struct EventLoop {
- pollfds: Vec<libc::pollfd>,
cbs: HashMap<RawFd, Callback>,
+ on_idle: Vec<Callback>,
}
pub enum Action {
@@ -28,8 +28,8 @@ pub enum Action {
impl EventLoop {
pub fn new() -> Self {
Self {
- pollfds: Vec::new(),
cbs: HashMap::new(),
+ on_idle: Vec::new(),
}
}
@@ -40,11 +40,21 @@ impl EventLoop {
self.cbs.insert(fd, Box::new(cb));
}
+ pub fn add_on_idle<F>(&mut self, cb: F)
+ where
+ F: FnMut(EventLoopCtx) -> Result<Action> + 'static,
+ {
+ self.on_idle.push(Box::new(cb));
+ }
+
pub fn run(&mut self, conn: &mut Connection<State>, state: &mut State) -> Result<()> {
+ let mut pollfds = Vec::new();
+ let mut on_idle_scratch = Vec::new();
+
while !self.cbs.is_empty() {
- self.pollfds.clear();
+ pollfds.clear();
for &fd in self.cbs.keys() {
- self.pollfds.push(libc::pollfd {
+ pollfds.push(libc::pollfd {
fd,
events: libc::POLLIN,
revents: 0,
@@ -52,8 +62,7 @@ impl EventLoop {
}
loop {
- let result =
- unsafe { libc::poll(self.pollfds.as_mut_ptr(), self.pollfds.len() as _, -1) };
+ let result = unsafe { libc::poll(pollfds.as_mut_ptr(), pollfds.len() as _, -1) };
if result == -1 {
let err = io::Error::last_os_error();
if err.kind() == io::ErrorKind::Interrupted {
@@ -64,7 +73,7 @@ impl EventLoop {
break;
}
- for fd in &self.pollfds {
+ for fd in &pollfds {
if fd.revents != 0 {
let mut cb = self.cbs.remove(&fd.fd).unwrap();
match cb(EventLoopCtx { conn, state })? {
@@ -75,6 +84,14 @@ impl EventLoop {
}
}
}
+
+ for mut cb in self.on_idle.drain(..) {
+ match cb(EventLoopCtx { conn, state })? {
+ Action::Keep => on_idle_scratch.push(cb),
+ Action::Unregister => (),
+ }
+ }
+ self.on_idle.append(&mut on_idle_scratch);
}
Ok(())
}
diff --git a/src/main.rs b/src/main.rs
index eed74ac..18d604e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -48,6 +48,11 @@ fn main() -> anyhow::Result<()> {
let mut state = State::new(&mut conn, &globals, &mut el, args.config.as_deref());
conn.flush(IoMode::Blocking)?;
+ el.add_on_idle(|ctx| {
+ ctx.conn.flush(IoMode::Blocking)?;
+ Ok(event_loop::Action::Keep)
+ });
+
el.register_with_fd(sig_read, move |ctx| {
let mut buf = [0u8];
assert_eq!(
@@ -55,16 +60,12 @@ fn main() -> anyhow::Result<()> {
1
);
ctx.state.toggle_visibility(ctx.conn);
- ctx.conn.flush(IoMode::Blocking)?;
Ok(event_loop::Action::Keep)
});
el.register_with_fd(conn.as_raw_fd(), |ctx| {
match ctx.conn.recv_events(IoMode::NonBlocking) {
- Ok(()) => {
- ctx.conn.dispatch_events(ctx.state);
- ctx.conn.flush(IoMode::Blocking)?;
- }
+ Ok(()) => ctx.conn.dispatch_events(ctx.state),
Err(e) if e.kind() == ErrorKind::WouldBlock => (),
Err(e) => bail!(e),
}
@@ -84,7 +85,6 @@ fn main() -> anyhow::Result<()> {
Ok(None) => Ok(event_loop::Action::Keep),
Ok(Some(blocks)) => {
ctx.state.set_blocks(ctx.conn, blocks);
- ctx.conn.flush(IoMode::Blocking)?;
Ok(event_loop::Action::Keep)
}
Err(e) => {
@@ -97,7 +97,6 @@ fn main() -> anyhow::Result<()> {
.child
.kill();
ctx.state.set_error(ctx.conn, e);
- ctx.conn.flush(IoMode::Blocking)?;
Ok(event_loop::Action::Unregister)
}
}
diff --git a/src/wm_info_provider/hyprland.rs b/src/wm_info_provider/hyprland.rs
index bbef98b..6fbfc30 100644
--- a/src/wm_info_provider/hyprland.rs
+++ b/src/wm_info_provider/hyprland.rs
@@ -4,7 +4,6 @@ use std::os::unix::net::UnixStream;
use std::path::PathBuf;
use serde::de::DeserializeOwned;
-use wayrs_client::IoMode;
use super::*;
use crate::event_loop;
@@ -35,7 +34,6 @@ impl WmInfoProvider for HyprlandInfoProvider {
Ok(()) => Ok(event_loop::Action::Keep),
Err(e) => {
ctx.state.set_error(ctx.conn, e);
- ctx.conn.flush(IoMode::Blocking)?;
Ok(event_loop::Action::Unregister)
}
}