summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxVerevkin <maxxverrr@gmail.com>2023-09-07 16:31:06 +0300
committerMaxVerevkin <maxxverrr@gmail.com>2023-09-07 16:31:06 +0300
commit87673d7ecce661f3b8c5db949e70640934a55de9 (patch)
treeb2ac86792f42a0cf6bd7defc4f8bc86cddfc7988
parent74cc46a2383db5538d7e0392e4b79b7287775e9b (diff)
downloadi3bar-mango-87673d7ecce661f3b8c5db949e70640934a55de9.tar.gz
some refactoring
-rw-r--r--src/event_loop.rs22
-rw-r--r--src/main.rs41
-rw-r--r--src/state.rs11
-rw-r--r--src/wm_info_provider.rs17
-rw-r--r--src/wm_info_provider/hyprland.rs58
-rw-r--r--src/wm_info_provider/river.rs10
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);