diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 91 | 
1 files changed, 91 insertions, 0 deletions
| 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<i32> { +        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::<i32>().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<String> = env::args().collect(); + +    if args.len() < 2 { +        println!("usage: swhd <terminal>"); +        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(()) +} | 
