aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2023-09-24 19:44:02 +0200
committerAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2023-09-24 19:47:51 +0200
commit63b8e1b07e725384e4c8323af7f3e63600721a82 (patch)
tree93ce80db469cb66a89b7763fd9e89e092e756ad5
initial
Signed-off-by: Anna (navi) Figueiredo Gomes <navi@vlhl.dev>
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock175
-rw-r--r--Cargo.toml10
-rw-r--r--README.md12
-rw-r--r--src/main.rs91
5 files changed, 289 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..3e0a48f
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,175 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
+
+[[package]]
+name = "memchr"
+version = "2.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.67"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex"
+version = "1.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
+
+[[package]]
+name = "ryu"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
+
+[[package]]
+name = "serde"
+version = "1.0.188"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.188"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.107"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "swayipc"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab1dcff328b223d85d7ca767b2e4aadbc13dad550d36b4c6b929b9ad4d26ee9a"
+dependencies = [
+ "serde",
+ "serde_json",
+ "swayipc-types",
+]
+
+[[package]]
+name = "swayipc-types"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44b43b4059d825ccc04adf9726f944d0e3aa20938f4cff3b5c6b53198afcd6b3"
+dependencies = [
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
+[[package]]
+name = "swhd"
+version = "0.1.0"
+dependencies = [
+ "regex",
+ "swayipc",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..4d4be05
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "swhd"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+regex = "1.9.5"
+swayipc = "3.0.1"
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..92fd853
--- /dev/null
+++ b/README.md
@@ -0,0 +1,12 @@
+# sway window hider daemon
+
+automatically hides windows, by looking into /proc.
+
+when a new window is spawned in sway, it looks for the pid,
+and recursivelly looks for parent pids until it finds the
+terminal listed, or init. in the case it finds the terminal,
+it sends any windows attached to that pid to the scratchpad,
+and marks the window hidden with the pid of the new process.
+
+once a window closes, it sees if any scratchpad windows have
+that pid marked, and if so, unhides them.
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(())
+}