From 7d665ea632fd0676b217bcba367ba5728ae1b514 Mon Sep 17 00:00:00 2001 From: MaxVerevkin Date: Fri, 6 Sep 2024 14:01:32 +0300 Subject: flush wayland socket after tag updates on hypland --- src/event_loop.rs | 31 ++++++++++++++++++++++++------- src/main.rs | 13 ++++++------- src/wm_info_provider/hyprland.rs | 2 -- 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, cbs: HashMap, + on_idle: Vec, } 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(&mut self, cb: F) + where + F: FnMut(EventLoopCtx) -> Result + 'static, + { + self.on_idle.push(Box::new(cb)); + } + pub fn run(&mut self, conn: &mut Connection, 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) } } -- cgit v1.3.1