summaryrefslogtreecommitdiff
path: root/waybar-window/src/main.rs
diff options
context:
space:
mode:
authorryukamish <[email protected]>2026-07-15 23:26:39 +0530
committerryukamish <[email protected]>2026-07-15 23:26:39 +0530
commit247654bbfab1ceec427767744a1feaba9b43dc4f (patch)
treeb790d13fbf1b985dd57fc93ab7c853fa7afac456 /waybar-window/src/main.rs
parente001da47918c8a311eaec61fdda7b15dfc8786f4 (diff)
add: sway window add id and title on waybar moduleHEADmain
Diffstat (limited to 'waybar-window/src/main.rs')
-rw-r--r--waybar-window/src/main.rs64
1 files changed, 64 insertions, 0 deletions
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(())
+}