From 461d59ec0ee83272682b5128e2c31ae67a7695b2 Mon Sep 17 00:00:00 2001 From: Penelope Gwen Date: Tue, 16 Sep 2025 12:12:21 -0700 Subject: [PATCH] monitoring windows and workspaces are functional --- src/config.rs | 4 +- src/lib/monitor/windows.rs | 18 ------ src/lib/monitor/workspaces.rs | 10 ---- src/lib/results.rs | 12 ++++ src/lib/windows.rs | 24 ++++++++ src/lib/workspaces.rs | 24 ++++++++ src/main.rs | 108 ++++++++++++++-------------------- 7 files changed, 105 insertions(+), 95 deletions(-) delete mode 100644 src/lib/monitor/windows.rs delete mode 100644 src/lib/monitor/workspaces.rs create mode 100644 src/lib/results.rs create mode 100644 src/lib/windows.rs create mode 100644 src/lib/workspaces.rs diff --git a/src/config.rs b/src/config.rs index 0461de9..fc23579 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,7 +9,7 @@ pub struct WindowIcon { pub icon: String, pub substring: String } -#[derive(Deserialize)] +#[derive(Deserialize, Default)] pub struct Config { pub title_length: usize, pub window_icons: Vec @@ -20,7 +20,7 @@ pub fn parse_config() -> Config { let config_path = xdg_dirs .place_config_file("config.toml") .expect("cannot create configuration directory"); - println!("{}",config_path.exists()); +// println!("{}",config_path.exists()); if !config_path.exists() { let _ = File::create(&config_path); // let config_file = File::create(&config_path); diff --git a/src/lib/monitor/windows.rs b/src/lib/monitor/windows.rs deleted file mode 100644 index 9591bbb..0000000 --- a/src/lib/monitor/windows.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::{fmt::Write}; -use swayipc::WindowEvent; -use crate::config::WindowIcon; - -pub fn get_window_title(title_length: usize, window_event: WindowEvent, window_icons: Vec) -> String { - let mut window_title = window_event.container.name.unwrap().trim_end().to_string(); - for pair in window_icons { - if window_title.contains(&pair.substring) { - window_title = pair.icon + " " + &window_title.replace(&pair.substring, ""); - } - - } - if window_title.len().gt(&title_length) { - window_title.truncate(title_length); - let _ = window_title.write_char('…'); - } - window_title -} \ No newline at end of file diff --git a/src/lib/monitor/workspaces.rs b/src/lib/monitor/workspaces.rs deleted file mode 100644 index 02aa5dc..0000000 --- a/src/lib/monitor/workspaces.rs +++ /dev/null @@ -1,10 +0,0 @@ -use swayipc::WorkspaceEvent; - -pub fn get_workspace_name(workspace_event: WorkspaceEvent) -> String { - workspace_event.current.unwrap().name.unwrap() -} - -pub fn get_workspace_list(workspace_event: WorkspaceEvent) -> String { - println!("{:?}",workspace_event.change); - "blah".to_string() -} \ No newline at end of file diff --git a/src/lib/results.rs b/src/lib/results.rs new file mode 100644 index 0000000..8caee70 --- /dev/null +++ b/src/lib/results.rs @@ -0,0 +1,12 @@ +#[derive(serde::Serialize)] +pub struct WindowInfo { + pub title: String +} + +#[derive(serde::Serialize)] +pub struct WorkspaceInfo { + pub num: i32, + pub name: String, + pub is_focused: bool, + pub position: char +} \ No newline at end of file diff --git a/src/lib/windows.rs b/src/lib/windows.rs new file mode 100644 index 0000000..4d10234 --- /dev/null +++ b/src/lib/windows.rs @@ -0,0 +1,24 @@ +use std::{fmt::Write}; +use serde_json::json; +use swayipc::Node; +use crate::{config::Config, Cli}; + +//#[path = "../results.rs"] +mod results; +use results::WindowInfo; + +pub fn print_window_title(window_node: Node,cli: &Cli,config: &Config) { + let mut window_title_display: String = window_node.name.unwrap(); + for pair in &config.window_icons { + if window_title_display.contains(&pair.substring) { + window_title_display = pair.icon.clone() + " " + &window_title_display.replace(&pair.substring, ""); + } + } + if !cli.no_truncate_title.unwrap() && window_title_display.len().gt(&config.title_length) { + window_title_display.truncate(config.title_length); + let _ = window_title_display.write_char('…'); + } + let window_info = WindowInfo { title: window_title_display }; + let window_output = json!(window_info); + println!("{}",window_output) +} \ No newline at end of file diff --git a/src/lib/workspaces.rs b/src/lib/workspaces.rs new file mode 100644 index 0000000..9f3f440 --- /dev/null +++ b/src/lib/workspaces.rs @@ -0,0 +1,24 @@ +use serde_json::json; +use swayipc::Workspace; + +//#[path = "../results.rs"] +mod results; +use results::WorkspaceInfo; + +pub fn print_workspace_array(workspaces: Vec) { + let current_ws = workspaces.iter().find(|&x| x.focused).unwrap().num; + let mut workspaces_info: Vec = vec![]; + for workspace in workspaces { + let mut ws_position = 'c'; + if current_ws.lt(&workspace.num) { + ws_position = 'r'; + } else if current_ws.gt(&workspace.num){ + ws_position = 'l'; + } + let workspace_info = WorkspaceInfo { num: workspace.num, name: workspace.name, is_focused: workspace.focused, position: ws_position }; + workspaces_info.push(workspace_info); + } + workspaces_info.sort_by(|a, b| a.num.cmp(&b.num)); + let workspace_output = json!(workspaces_info); + println!("{}",workspace_output) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 007a0f3..6fbad1a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,16 @@ use std::process::exit; -use clap::{Parser,Subcommand}; +use clap::{Parser,Subcommand,ArgAction}; use swayipc::{Connection, Event, EventType, Fallible}; + mod config; -#[path = "lib/monitor/windows.rs"] +#[path = "lib/windows.rs"] mod windows; -use windows::get_window_title; -#[path = "lib/monitor/workspaces.rs"] +use windows::print_window_title; +#[path = "lib/workspaces.rs"] mod workspaces; -use workspaces::get_workspace_name; +use workspaces::print_workspace_array; use crate::config::Config; mod monitor; @@ -17,17 +18,21 @@ mod monitor; #[derive(Parser)] #[command(version, about, long_about = None)] -struct Cli { - /// Optional name to operate on - #[arg(short, long)] - name: Option, +pub struct Cli { + /// Disable truncation of window titles + #[arg(short = 'T', long = "no-truncate-title", action = ArgAction::SetTrue)] + no_truncate_title: Option, + + /// Enables monitoring for supported event types + #[arg(short = 'm', long = "monitor", action = ArgAction::SetTrue)] + monitor: Option, // /// Sets a custom config file // #[arg(short, long, value_name = "FILE")] // config: Option, /// Turn debugging information on - #[arg(short, long, action = clap::ArgAction::Count)] + #[arg(short, long, action = ArgAction::Count)] debug: u8, #[command(subcommand)] @@ -37,22 +42,24 @@ struct Cli { #[derive(Subcommand)] enum Commands { /// Prints the Currently Active Window Title - WindowTitle, - // + Windows, + // Prints the Currently Active Workspace layout + Workspaces, + // Launch Program with Current Profile's Configuration Launch, Lock, Rename, Profile, Shortcuts { - #[arg(short, long, action = clap::ArgAction::Count)] - global: u8, + #[arg(short, long, action = ArgAction::SetTrue)] + global: Option, }, - Monitor { - /// monitor a sway activity type +// Monitor { +// /// monitor a sway activity type // #[arg(short, long)] - #[command(subcommand)] - monitor_type: MonitorTypes, - }, +// #[command(subcommand)] +// monitor_type: MonitorTypes, +// }, } #[derive(Subcommand)] @@ -68,31 +75,23 @@ enum MonitorTypes { fn main() -> Fallible<()> { let cli = Cli::parse(); let config = config::parse_config(); -// std::process::exit(0); - if let Some(name) = cli.name.as_deref() { - println!("Value for name: {name}"); + if let Some(no_truncate_title) = cli.no_truncate_title { + println!("Value for no_truncate_title: {no_truncate_title}"); } + let mut sway_connection = Connection::new()?; match &cli.command { - Commands::WindowTitle => { - println!("Print window title"); - let sway_connection = Connection::new()?; - sway_connection.get_tree().unwrap(); -// println!("{:?}", sway_connection.get_tree().map(op)) + Commands::Windows => { + print_window_title(sway_connection.get_tree().iter().find(|&x | x.focused).unwrap().clone(), &cli, &config); + if cli.monitor.unwrap() { + let _ = monitor_events(EventType::Window, cli, config); } - Commands::Monitor { monitor_type } => { - match monitor_type { - MonitorTypes::Workspaces => { - println!("monitoring workspace changes!") - } - MonitorTypes::Windows => { - println!("monitoring window changes!"); - monitor_events(EventType::Window, config); - } - MonitorTypes::Profile => { - println!("monitoring profile changes!") - } - } + } + Commands::Workspaces => { + print_workspace_array(sway_connection.get_workspaces().unwrap()); + if cli.monitor.unwrap() { + let _ = monitor_events(EventType::Workspace, cli, config); } + } Commands::Launch => todo!(), Commands::Lock => todo!(), Commands::Rename => todo!(), @@ -102,7 +101,7 @@ fn main() -> Fallible<()> { exit(0); } -pub fn monitor_events(event_type: EventType, config: Config) -> Fallible<()> { +pub fn monitor_events(event_type: EventType, cli: Cli, config: Config) -> Fallible<()> { /* let subs = [ // Valid EventTypes: Workspace, Output, Input, Tick, Shutdown, Mode, Window, BarStateUpdate, BarConfigUpdate, Binding //EventType::Workspace, @@ -111,35 +110,14 @@ pub fn monitor_events(event_type: EventType, config: Config) -> Fallible<()> { event_type ]; */ let sway_connection = Connection::new()?; - -// for event in Connection::new()?.subscribe(subs)? { for event in sway_connection.subscribe([event_type])? { let e = event?; -// println!("{:?}\n", e); match e { Event::Window(w) => { -// println!("{}",config.window_icons[0].icon); - println!("{}", get_window_title(config.title_length, *w, config.window_icons.clone())); -// println!("{:?}",w.container.nodes); -// println!("{:?}",Connection::get_workspaces(&mut Connection::new().unwrap()).unwrap()); - - }, + print_window_title(w.container, &cli, &config); +}, Event::Workspace(w) => { -// println!("{}", get_workspace_name(*w)); -// println!("{:?}",w.change); - let mut sway_con = self::Connection::new()?; - for workspace in Connection::get_workspaces(&mut sway_con)? { -// println!("{}",workspace.name); - let current_workspace_num = w.current.as_ref().unwrap().num.unwrap(); - if workspace.num.lt(¤t_workspace_num) { - println!("left: {} {}",workspace.num % 10, workspace.name) - } else if workspace.focused { - println!("focused: {}",workspace.num % 10) - } else if workspace.num.gt(¤t_workspace_num) { - println!("right: {} {}",workspace.num % 10, workspace.name) - } -// println!("{}",workspace.focused); - } + print_workspace_array(self::Connection::get_workspaces(&mut self::Connection::new().unwrap()).unwrap()); }, Event::Tick(w) => { println!("{}",w.payload);