diff options
| author | MaxVerevkin <maxxverrr@gmail.com> | 2023-09-07 16:31:06 +0300 |
|---|---|---|
| committer | MaxVerevkin <maxxverrr@gmail.com> | 2023-09-07 16:31:06 +0300 |
| commit | 87673d7ecce661f3b8c5db949e70640934a55de9 (patch) | |
| tree | b2ac86792f42a0cf6bd7defc4f8bc86cddfc7988 | |
| parent | 74cc46a2383db5538d7e0392e4b79b7287775e9b (diff) | |
| download | i3bar-mango-87673d7ecce661f3b8c5db949e70640934a55de9.tar.gz | |
some refactoring
| -rw-r--r-- | src/event_loop.rs | 22 | ||||
| -rw-r--r-- | src/main.rs | 41 | ||||
| -rw-r--r-- | src/state.rs | 11 | ||||
| -rw-r--r-- | src/wm_info_provider.rs | 17 | ||||
| -rw-r--r-- | src/wm_info_provider/hyprland.rs | 58 | ||||
| -rw-r--r-- | src/wm_info_provider/river.rs | 10 |
6 files changed, 86 insertions, 73 deletions
diff --git a/src/event_loop.rs b/src/event_loop.rs index d869d80..3b02624 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -3,12 +3,20 @@ use std::io; use std::os::fd::RawFd; use anyhow::Result; +use wayrs_client::Connection; -type Callback<D> = Box<dyn FnMut(&mut D) -> Result<Action>>; +use crate::state::State; -pub struct EventLoop<D> { +type Callback = Box<dyn FnMut(EventLoopCtx) -> Result<Action>>; + +pub struct EventLoopCtx<'a> { + pub conn: &'a mut Connection<State>, + pub state: &'a mut State, +} + +pub struct EventLoop { pollfds: Vec<libc::pollfd>, - cbs: HashMap<RawFd, Callback<D>>, + cbs: HashMap<RawFd, Callback>, } pub enum Action { @@ -16,7 +24,7 @@ pub enum Action { Unregister, } -impl<D> EventLoop<D> { +impl EventLoop { pub fn new() -> Self { Self { pollfds: Vec::new(), @@ -26,12 +34,12 @@ impl<D> EventLoop<D> { pub fn register_with_fd<F>(&mut self, fd: RawFd, cb: F) where - F: FnMut(&mut D) -> Result<Action> + 'static, + F: FnMut(EventLoopCtx) -> Result<Action> + 'static, { self.cbs.insert(fd, Box::new(cb)); } - pub fn run(&mut self, state: &mut D) -> Result<()> { + pub fn run(&mut self, conn: &mut Connection<State>, state: &mut State) -> Result<()> { if self.cbs.is_empty() { return Ok(()); } @@ -61,7 +69,7 @@ impl<D> EventLoop<D> { for fd in &self.pollfds { if fd.revents != 0 { let mut cb = self.cbs.remove(&fd.fd).unwrap(); - match cb(state)? { + match cb(EventLoopCtx { conn, state })? { Action::Keep => { self.cbs.insert(fd.fd, cb); } diff --git a/src/main.rs b/src/main.rs index 20bc49c..f27e076 100644 --- a/src/main.rs +++ b/src/main.rs @@ -45,21 +45,21 @@ fn main() -> anyhow::Result<()> { signal_hook::low_level::pipe::register(SIGUSR1, sig_write)?; let (mut conn, globals) = Connection::connect_and_collect_globals()?; - let mut el = EventLoop::<(Connection<State>, State)>::new(); - let state = State::new(&mut conn, &globals, &mut el, args.config.as_deref()); + let mut el = EventLoop::new(); + let mut state = State::new(&mut conn, &globals, &mut el, args.config.as_deref()); conn.flush(IoMode::Blocking)?; - el.register_with_fd(sig_read, move |(conn, state)| { + el.register_with_fd(sig_read, move |ctx| { nix::unistd::read(sig_read, &mut [0; 1])?; - state.toggle_visibility(conn); + ctx.state.toggle_visibility(ctx.conn); Ok(event_loop::Action::Keep) }); - el.register_with_fd(conn.as_raw_fd(), |(conn, state)| { - match conn.recv_events(IoMode::NonBlocking) { + el.register_with_fd(conn.as_raw_fd(), |ctx| { + match ctx.conn.recv_events(IoMode::NonBlocking) { Ok(()) => { - conn.dispatch_events(state); - conn.flush(IoMode::Blocking)?; + ctx.conn.dispatch_events(ctx.state); + ctx.conn.flush(IoMode::Blocking)?; } Err(e) if e.kind() == ErrorKind::WouldBlock => (), Err(e) => bail!(e), @@ -68,8 +68,9 @@ fn main() -> anyhow::Result<()> { }); if let Some(fd) = state.status_cmd_fd() { - el.register_with_fd(fd, |(conn, state)| { - match state + el.register_with_fd(fd, |ctx| { + match ctx + .state .shared_state .status_cmd .as_mut() @@ -78,22 +79,28 @@ fn main() -> anyhow::Result<()> { { Ok(None) => Ok(event_loop::Action::Keep), Ok(Some(blocks)) => { - state.set_blocks(conn, blocks); - conn.flush(IoMode::Blocking)?; + ctx.state.set_blocks(ctx.conn, blocks); + ctx.conn.flush(IoMode::Blocking)?; Ok(event_loop::Action::Keep) } Err(e) => { - let _ = state.shared_state.status_cmd.take().unwrap().child.kill(); - state.set_error(conn, e); - conn.flush(IoMode::Blocking)?; + let _ = ctx + .state + .shared_state + .status_cmd + .take() + .unwrap() + .child + .kill(); + ctx.state.set_error(ctx.conn, e); + ctx.conn.flush(IoMode::Blocking)?; Ok(event_loop::Action::Unregister) } } }); } - let mut el_state = (conn, state); loop { - el.run(&mut el_state)?; + el.run(&mut conn, &mut state)?; } } diff --git a/src/state.rs b/src/state.rs index c4fd0ce..92bf834 100644 --- a/src/state.rs +++ b/src/state.rs @@ -57,7 +57,7 @@ impl State { pub fn new( conn: &mut Connection<Self>, globals: &Globals, - event_loop: &mut EventLoop<(Connection<Self>, Self)>, + event_loop: &mut EventLoop, config_path: Option<&Path>, ) -> Self { let mut error = Ok(()); @@ -80,7 +80,10 @@ impl State { .map_err(|e| error = Err(e.into())) .ok(); - let wm_info_provider = wm_info_provider::bind(conn, globals, event_loop, &config.wm); + let wm_info_provider = wm_info_provider::bind(conn, globals, &config.wm); + if let Some(wm) = &wm_info_provider { + wm.register(event_loop); + } let mut this = Self { wl_compositor, @@ -155,7 +158,7 @@ impl State { } if let Some(wm) = &mut self.shared_state.wm_info_provider { - wm.new_ouput(conn, output.wl); + wm.new_ouput(conn, &output); } let mut bar = Bar::new(conn, self, output); @@ -174,7 +177,7 @@ impl State { pub fn drop_bar(&mut self, conn: &mut Connection<Self>, bar_index: usize) { let bar = self.bars.swap_remove(bar_index); if let Some(wm) = &mut self.shared_state.wm_info_provider { - wm.output_removed(conn, bar.output.wl); + wm.output_removed(conn, &bar.output); } bar.destroy(conn); } diff --git a/src/wm_info_provider.rs b/src/wm_info_provider.rs index e1004fa..25eef05 100644 --- a/src/wm_info_provider.rs +++ b/src/wm_info_provider.rs @@ -17,12 +17,18 @@ mod hyprland; pub use hyprland::*; pub trait WmInfoProvider { - fn new_ouput(&mut self, conn: &mut Connection<State>, output: WlOutput); - fn output_removed(&mut self, conn: &mut Connection<State>, output: WlOutput); + fn register(&self, _: &mut EventLoop) {} + + fn new_ouput(&mut self, _: &mut Connection<State>, _: &Output) {} + fn output_removed(&mut self, _: &mut Connection<State>, _: &Output) {} fn get_tags(&self, output: &Output) -> Vec<Tag>; - fn get_layout_name(&self, output: &Output) -> Option<String>; - fn get_mode_name(&self, output: &Output) -> Option<String>; + fn get_layout_name(&self, _: &Output) -> Option<String> { + None + } + fn get_mode_name(&self, _: &Output) -> Option<String> { + None + } fn click_on_tag( &mut self, @@ -39,14 +45,13 @@ pub trait WmInfoProvider { pub fn bind( conn: &mut Connection<State>, globals: &Globals, - event_loop: &mut EventLoop<(Connection<State>, State)>, config: &WmConfig, ) -> Option<Box<dyn WmInfoProvider>> { if let Some(river) = RiverInfoProvider::bind(conn, globals, config) { return Some(Box::new(river)); } - if let Some(hyprland) = Hyprland::new(event_loop) { + if let Some(hyprland) = Hyprland::new() { return Some(Box::new(hyprland)); } diff --git a/src/wm_info_provider/hyprland.rs b/src/wm_info_provider/hyprland.rs index 52d8325..1233e66 100644 --- a/src/wm_info_provider/hyprland.rs +++ b/src/wm_info_provider/hyprland.rs @@ -17,41 +17,31 @@ pub struct Hyprland { } impl Hyprland { - pub fn new(event_loop: &mut EventLoop<(Connection<State>, State)>) -> Option<Self> { + pub fn new() -> Option<Self> { let his = std::env::var("HYPRLAND_INSTANCE_SIGNATURE").ok()?; let ipc = Ipc::new(&his).ok()?; - let active_id = ipc.query_json::<IpcWorkspace>("j/activeworkspace").ok()?.id; - let mut this = Self { + Some(Self { + workspaces: ipc.query_sorted_workspaces().ok()?, + active_id: ipc.query_json::<IpcWorkspace>("j/activeworkspace").ok()?.id, ipc, - workspaces: Vec::new(), - active_id, - }; - this.fetch_workspaces().ok()?; - event_loop.register_with_fd(this.ipc.sock2.as_raw_fd(), |state| { - match hyprland_cb(&mut state.0, &mut state.1) { + }) + } +} + +impl WmInfoProvider for Hyprland { + fn register(&self, event_loop: &mut EventLoop) { + event_loop.register_with_fd(self.ipc.sock2.as_raw_fd(), |ctx| { + match hyprland_cb(ctx.conn, ctx.state) { Ok(()) => Ok(event_loop::Action::Keep), Err(e) => { - state.1.set_error(&mut state.0, e); - state.0.flush(IoMode::Blocking)?; + ctx.state.set_error(ctx.conn, e); + ctx.conn.flush(IoMode::Blocking)?; Ok(event_loop::Action::Unregister) } } }); - Some(this) } - fn fetch_workspaces(&mut self) -> io::Result<()> { - self.workspaces = self.ipc.query_json::<Vec<IpcWorkspace>>("j/workspaces")?; - self.workspaces.sort_unstable_by_key(|x| x.id); - Ok(()) - } -} - -impl WmInfoProvider for Hyprland { - fn new_ouput(&mut self, _: &mut Connection<State>, _: WlOutput) {} - - fn output_removed(&mut self, _: &mut Connection<State>, _: WlOutput) {} - fn get_tags(&self, output: &Output) -> Vec<Tag> { self.workspaces .iter() @@ -66,14 +56,6 @@ impl WmInfoProvider for Hyprland { .collect() } - fn get_layout_name(&self, _: &Output) -> Option<String> { - None - } - - fn get_mode_name(&self, _: &Output) -> Option<String> { - None - } - fn click_on_tag( &mut self, _: &mut Connection<State>, @@ -99,10 +81,12 @@ fn hyprland_cb(conn: &mut Connection<State>, state: &mut State) -> io::Result<() match hyprland.ipc.next_event() { Ok(event) => { if let Some(active_ws) = event.strip_prefix("workspace>>") { - hyprland.active_id = active_ws.parse().unwrap(); + hyprland.active_id = active_ws + .parse() + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; updated = true; } else if event.contains("workspace>>") { - hyprland.fetch_workspaces()?; + hyprland.workspaces = hyprland.ipc.query_sorted_workspaces()?; updated = true; } } @@ -149,6 +133,12 @@ impl Ipc { serde_json::from_reader(&mut sock).map_err(Into::into) } + fn query_sorted_workspaces(&self) -> io::Result<Vec<IpcWorkspace>> { + let mut workspaces = self.query_json::<Vec<IpcWorkspace>>("j/workspaces")?; + workspaces.sort_unstable_by_key(|x| x.id); + Ok(workspaces) + } + fn next_event(&mut self) -> io::Result<String> { loop { if let Some(i) = memchr::memchr(b'\n', &self.sock2_buf) { diff --git a/src/wm_info_provider/river.rs b/src/wm_info_provider/river.rs index d8e9c3b..6c0993b 100644 --- a/src/wm_info_provider/river.rs +++ b/src/wm_info_provider/river.rs @@ -54,12 +54,12 @@ impl RiverInfoProvider { } impl WmInfoProvider for RiverInfoProvider { - fn new_ouput(&mut self, conn: &mut Connection<State>, output: WlOutput) { + fn new_ouput(&mut self, conn: &mut Connection<State>, output: &Output) { let status = self.status_manager - .get_river_output_status_with_cb(conn, output, output_status_cb); + .get_river_output_status_with_cb(conn, output.wl, output_status_cb); self.output_statuses.push(OutputStatus { - output, + output: output.wl, status, focused_tags: 0, urgent_tags: 0, @@ -68,11 +68,11 @@ impl WmInfoProvider for RiverInfoProvider { }); } - fn output_removed(&mut self, conn: &mut Connection<State>, output: WlOutput) { + fn output_removed(&mut self, conn: &mut Connection<State>, output: &Output) { let index = self .output_statuses .iter() - .position(|s| s.output == output) + .position(|s| s.output == output.wl) .unwrap(); let output_status = self.output_statuses.swap_remove(index); output_status.status.destroy(conn); |
