From 247654bbfab1ceec427767744a1feaba9b43dc4f Mon Sep 17 00:00:00 2001 From: ryukamish Date: Wed, 15 Jul 2026 23:26:39 +0530 Subject: add: sway window add id and title on waybar module --- waybar-window/Cargo.lock | 149 ++++++++++++++++++++++++++++++++++++++++++++++ waybar-window/Cargo.toml | 8 +++ waybar-window/src/main.rs | 64 ++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 waybar-window/Cargo.lock create mode 100644 waybar-window/Cargo.toml create mode 100644 waybar-window/src/main.rs (limited to 'waybar-window') diff --git a/waybar-window/Cargo.lock b/waybar-window/Cargo.lock new file mode 100644 index 0000000..2c0af73 --- /dev/null +++ b/waybar-window/Cargo.lock @@ -0,0 +1,149 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "swayipc" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd6ee13016b1ae2fbf741ddb2133d983a3fecdc34686eec6202e2a80612d82f" +dependencies = [ + "serde", + "serde_json", + "swayipc-types", +] + +[[package]] +name = "swayipc-types" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a29165dc67819a052bd67962b6c9de7c5d4461f0e8d224eb0f7cdd26cf05a650" +dependencies = [ + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "waybar-window" +version = "0.1.0" +dependencies = [ + "serde_json", + "swayipc", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/waybar-window/Cargo.toml b/waybar-window/Cargo.toml new file mode 100644 index 0000000..e263b39 --- /dev/null +++ b/waybar-window/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "waybar-window" +version = "0.1.0" +edition = "2024" + +[dependencies] +serde_json = "1.0.150" +swayipc = "4.0.0" diff --git a/waybar-window/src/main.rs b/waybar-window/src/main.rs new file mode 100644 index 0000000..aa301ec --- /dev/null +++ b/waybar-window/src/main.rs @@ -0,0 +1,64 @@ +use serde_json::json; +use std::io::Write; +use swayipc::{Connection, Event, EventType, Fallible, Node}; + +/// True if this node represents an actual window (not a workspace/output/container) +fn is_window(node: &Node) -> bool { + node.app_id.is_some() || node.window_properties.is_some() +} + +/// Walk the tree and find the focused node. +fn find_focused(node: &Node) -> Option<&Node> { + // Also checking for if it's a window otherwise Sway marks an empty workspace as focused + if node.focused && is_window(node) { + return Some(node); + } + node.nodes + .iter() + .chain(node.floating_nodes.iter()) + .find_map(find_focused) +} + +fn format_line(node: &Node) -> String { + let app_id = node + .app_id + .clone() + .or_else(|| node.window_properties.as_ref()?.class.clone()) + .unwrap_or_else(|| "?".to_string()); + let title = node.name.clone().unwrap_or_default(); + format!("{app_id} | {title}") +} + +fn print_json(text: &str) { + let escaped = json!({ "text": text, "tooltip": false }); + println!("{escaped}"); + let _ = std::io::stdout().flush(); +} + +fn main() -> Fallible<()> { + // Print current focused window immediately so waybar has something + // on startup instead of waiting for the next event. + { + let mut conn = Connection::new()?; + let tree = conn.get_tree()?; + let text = find_focused(&tree).map(format_line).unwrap_or_default(); + print_json(&text); + } + + // Then stream updates as they happen. + let subs = [EventType::Window, EventType::Workspace]; + for event in Connection::new()?.subscribe(subs)? { + match event { + Ok(Event::Window(_)) | Ok(Event::Workspace(_)) => { + let mut conn = Connection::new()?; + let tree = conn.get_tree()?; + let text = find_focused(&tree).map(format_line).unwrap_or_default(); + print_json(&text); + } + Ok(_) => {} + Err(e) => eprintln!("swayipc event error: {e}"), + } + } + + Ok(()) +} -- cgit v1.3