From 63b8e1b07e725384e4c8323af7f3e63600721a82 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Sun, 24 Sep 2023 19:44:02 +0200 Subject: initial Signed-off-by: Anna (navi) Figueiredo Gomes --- src/main.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/main.rs (limited to 'src') diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..b251bab --- /dev/null +++ b/src/main.rs @@ -0,0 +1,91 @@ +use swayipc::{Connection, WindowChange, EventType}; +use std::{env,fs::File, io::Read}; +use regex::Regex; + +struct WindowHider { + term: String +} + +impl WindowHider { + fn get_parent_term_pid(&self, pid: i32) -> Option { + let mut file = String::new(); + File::open(format!("/proc/{pid}/stat")).expect("procfs stat doesn't exist").read_to_string(&mut file).unwrap(); + let re = Regex::new(r"\d+ \((.*)\) (\w) (\d+) \d+").unwrap().captures(&file).unwrap(); + let name = re.get(1).unwrap().as_str(); + let status = re.get(2).unwrap().as_str(); + let ppid = re.get(3).unwrap().as_str().parse::().unwrap(); + + println!("looking for {pid}. {name}, {status}, {ppid}"); + match name { + _ if name == self.term => { + Some(pid) + }, + _ if name == "init" => { + None + } + _ => { + self.get_parent_term_pid(ppid) + } + } + } + + fn hide(&self, conn: &mut Connection, pid: i32) -> Result<(), swayipc::Error> { + let ppid = self.get_parent_term_pid(pid); + if let Some(ppid) = ppid { + println!("found parent pid of {pid} as {ppid}"); + conn.run_command(format!("[pid={ppid}] mark --add {pid}, move scratchpad"))?; + } + Ok(()) + } + + fn show(&self, conn: &mut Connection, pid: i32) -> Result<(), swayipc::Error> { + conn.run_command(format!("[con_mark={pid}] move workspace current"))?; + conn.run_command(format!("[con_mark={pid}] floating toggle"))?; + Ok(()) + } +} + +fn main() -> Result<(), swayipc::Error> { + let mut conn = Connection::new().expect("couldn't connect to sway's socket"); + let evs = Connection::new()?.subscribe([EventType::Window])?; // one can't use the same + // connection for events and for + // running commands. :( + + let mut args: Vec = env::args().collect(); + + if args.len() < 2 { + println!("usage: swhd "); + return Ok(()); + } + + let wh = WindowHider { + term: args.remove(1) + }; + + for item in evs { + if let Ok(item) = item { + match item { + swayipc::Event::Window(win) => { + if win.change == WindowChange::New { + if let Some(pid) = win.container.pid { + match wh.hide(&mut conn, pid) { + Ok(_) => {}, + Err(_) => println!("failed to hide terminal {pid}") + }; + } + } else if win.change == WindowChange::Close { + if let Some(pid) = win.container.pid { + match wh.show(&mut conn, pid) { + Ok(_) => {}, + Err(_) => println!("failed to show terminal {pid}") + }; + } + } + } + _ => {} + } + } + } + + Ok(()) +} -- cgit v1.2.3