diff options
| author | ryukamish <[email protected]> | 2026-07-15 23:26:39 +0530 |
|---|---|---|
| committer | ryukamish <[email protected]> | 2026-07-15 23:26:39 +0530 |
| commit | 247654bbfab1ceec427767744a1feaba9b43dc4f (patch) | |
| tree | b790d13fbf1b985dd57fc93ab7c853fa7afac456 /waybar-window/src | |
| parent | e001da47918c8a311eaec61fdda7b15dfc8786f4 (diff) | |
Diffstat (limited to 'waybar-window/src')
| -rw-r--r-- | waybar-window/src/main.rs | 64 |
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(()) +} |
