aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs91
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(())
+}