From 97833271a32c63c2fdd68b05b30c9e38a42b1f42 Mon Sep 17 00:00:00 2001 From: Elden Date: Tue, 16 Jun 2026 06:22:04 +0700 Subject: added clicking tags support & layout name --- src/wm_info_provider/mango.rs | 75 +++++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/wm_info_provider/mango.rs b/src/wm_info_provider/mango.rs index 82b511c..fe5759e 100644 --- a/src/wm_info_provider/mango.rs +++ b/src/wm_info_provider/mango.rs @@ -12,7 +12,7 @@ use crate::utils::read_to_vec; pub struct MangoInfoProvider { mmsg_sock: UnixStream, mmsg_buf: Vec, - all_tags: Vec, + all_monitors: Vec, } #[derive(serde::Deserialize, Debug, Clone)] @@ -24,21 +24,25 @@ struct MangoTag { } #[derive(serde::Deserialize, Debug, Clone)] -struct MangoTagsContainer { - monitor: String, +struct MangoMonitor { + name: String, + active: bool, tags: Vec, + layout_symbol: String, } + + #[derive(serde::Deserialize, Debug)] struct MangoIpc { - all_tags: Vec, + monitors: Vec, } impl MangoInfoProvider { pub fn new() -> Option { let child = Command::new("/usr/bin/mmsg") .arg("watch") - .arg("all-tags") + .arg("all-monitors") .stdout(Stdio::piped()) .spawn().ok()?; let stdout = child.stdout.expect("couldn't get stdout"); @@ -47,7 +51,7 @@ impl MangoInfoProvider { Some(Self { mmsg_sock: sock, mmsg_buf: Vec::new(), - all_tags: Vec::new(), + all_monitors: Vec::new(), }) } fn next_event(&mut self) -> io::Result { @@ -67,14 +71,23 @@ impl MangoInfoProvider { } } + + impl WmInfoProvider for MangoInfoProvider { fn register(&self, ev: &mut EventLoop) { + ev.register_with_fd(self.mmsg_sock.as_raw_fd(), |ctx| { loop { - match ctx.state.shared_state.get_mango().unwrap().next_event() { + let mango = ctx.state.shared_state.get_mango().unwrap(); + let mut layout_updated = false; + match mango.next_event() { Ok(event) => { - ctx.state.shared_state.get_mango().unwrap().all_tags = event.all_tags; - ctx.state.tags_updated(ctx.conn, None); + if let Some(i) = event.monitors.iter().position(|m| m.active) { + if mango.all_monitors.get(i).map(|m| &m.layout_symbol) != event.monitors.get(i).map(|m| &m.layout_symbol) { + layout_updated = true; + } + } + mango.all_monitors = event.monitors; } Err(e) if e.kind() == io::ErrorKind::WouldBlock => break, Err(e) => { @@ -82,21 +95,21 @@ impl WmInfoProvider for MangoInfoProvider { return Ok(event_loop::Action::Unregister); } } + ctx.state.tags_updated(ctx.conn, None); + if layout_updated { + ctx.state.layout_name_updated(ctx.conn, None); + } } Ok(event_loop::Action::Keep) }); } fn get_tags(&self, output: &Output) -> Vec { - self.all_tags + self.all_monitors .iter() - .find(|c| c.monitor == output.name) - .map_or_else( - || { - eprintln!("Couldn't find tags for monitor {}", output.name); - Vec::new() - }, - |container| { - container + .find(|c| c.name == output.name) + .map_or_default( + |monitor| { + monitor .tags .iter() .enumerate() @@ -111,17 +124,39 @@ impl WmInfoProvider for MangoInfoProvider { }, ) } + // TODO + fn get_layout_name(&self, output: &Output) -> Option { + // self.layout_symbol.clone() + self.all_monitors + .iter() + .find(|c| c.name == output.name) + .map_or_else( + || { + eprintln!("Couldn't find layout_name for monitor {}", output.name); + None + }, + |monitor| { + Some(monitor.layout_symbol.clone()) + }) + } fn get_mode_name(&self, _: &Output) -> Option { None } fn click_on_tag( &mut self, - _conn: &mut Connection, + conn: &mut Connection, _output: &Output, _seat: WlSeat, - _tag_id: Option, + tag_id: Option, _btn: PointerBtn, ) { + if let Some(id) = tag_id { + let _ = Command::new("/usr/bin/mmsg") + .arg("dispatch") + .arg(format!("view,{}", id)) + .stdout(Stdio::piped()) + .spawn(); + } } } -- cgit v1.3.1