1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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(())
}
|