waybar-modules

extend waybar functionality with custom waybar modules
Log | Files | Refs | README

main.rs (2058B)


      1 use serde_json::json;
      2 use std::io::Write;
      3 use swayipc::{Connection, Event, EventType, Fallible, Node};
      4 
      5 /// True if this node represents an actual window (not a workspace/output/container)
      6 fn is_window(node: &Node) -> bool {
      7     node.app_id.is_some() || node.window_properties.is_some()
      8 }
      9 
     10 /// Walk the tree and find the focused node.
     11 fn find_focused(node: &Node) -> Option<&Node> {
     12     // Also checking for if it's a window otherwise Sway marks an empty workspace as focused
     13     if node.focused && is_window(node) {
     14         return Some(node);
     15     }
     16     node.nodes
     17         .iter()
     18         .chain(node.floating_nodes.iter())
     19         .find_map(find_focused)
     20 }
     21 
     22 fn format_line(node: &Node) -> String {
     23     let app_id = node
     24         .app_id
     25         .clone()
     26         .or_else(|| node.window_properties.as_ref()?.class.clone())
     27         .unwrap_or_else(|| "?".to_string());
     28     let title = node.name.clone().unwrap_or_default();
     29     format!("{app_id} | {title}")
     30 }
     31 
     32 fn print_json(text: &str) {
     33     let escaped = json!({ "text": text, "tooltip": false });
     34     println!("{escaped}");
     35     let _ = std::io::stdout().flush();
     36 }
     37 
     38 fn main() -> Fallible<()> {
     39     // Print current focused window immediately so waybar has something
     40     // on startup instead of waiting for the next event.
     41     {
     42         let mut conn = Connection::new()?;
     43         let tree = conn.get_tree()?;
     44         let text = find_focused(&tree).map(format_line).unwrap_or_default();
     45         print_json(&text);
     46     }
     47 
     48     // Then stream updates as they happen.
     49     let subs = [EventType::Window, EventType::Workspace];
     50     for event in Connection::new()?.subscribe(subs)? {
     51         match event {
     52             Ok(Event::Window(_)) | Ok(Event::Workspace(_)) => {
     53                 let mut conn = Connection::new()?;
     54                 let tree = conn.get_tree()?;
     55                 let text = find_focused(&tree).map(format_line).unwrap_or_default();
     56                 print_json(&text);
     57             }
     58             Ok(_) => {}
     59             Err(e) => eprintln!("swayipc event error: {e}"),
     60         }
     61     }
     62 
     63     Ok(())
     64 }