diff --git a/Cargo.lock b/Cargo.lock index b5a940b..989d4a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -637,7 +637,7 @@ dependencies = [ [[package]] name = "swayrbar" -version = "0.1.1" +version = "0.2.0" dependencies = [ "battery", "chrono", diff --git a/README.md b/README.md index a27f592..133c223 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ * [Screenshots](#swayrbar-screenshots) * [Installation](#swayrbar-installation) * [Configuration](#swayrbar-configuration) + * [Version changes](#swayrbar-version-changes) * [Questions and patches](#questions-and-patches) * [Bugs](#bugs) * [Build status](#build-status) @@ -673,6 +674,14 @@ The `date` module shows the date and time by defining the `format` using [chrono's strftime format](https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html#specifiers). +### Version changes + +Version changes are summarized in the [NEWS](swayrbar/NEWS.md) file. If +something doesn't seem to work as expected after an update, please consult this +file to check if there has been some (possibly incompatible) change requiring +an update of your config. + + ## Questions & Patches For asking questions, sending feedback, or patches, refer to [my public inbox diff --git a/swayrbar/Cargo.toml b/swayrbar/Cargo.toml index 38c6726..17da226 100644 --- a/swayrbar/Cargo.toml +++ b/swayrbar/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "swayrbar" -version = "0.1.1" +version = "0.2.0" edition = "2021" homepage = "https://sr.ht/~tsdh/swayr/#swayrbar" repository = "https://git.sr.ht/~tsdh/swayr" diff --git a/swayrbar/NEWS.md b/swayrbar/NEWS.md new file mode 100644 index 0000000..bb143f0 --- /dev/null +++ b/swayrbar/NEWS.md @@ -0,0 +1,15 @@ +swayrbar 0.2.0 +============== + +- If a window module is used, subscribe to sway events in order to immediately + refresh it on window/workspace changes. + +swayrbar 0.1.1 +============== + +- Only refresh the module which received the click event. + +swayrbar 0.1.0 +============== + +- Add pactl module. diff --git a/swayrbar/src/bar.rs b/swayrbar/src/bar.rs index fccd077..d05248f 100644 --- a/swayrbar/src/bar.rs +++ b/swayrbar/src/bar.rs @@ -27,6 +27,7 @@ use std::sync::Mutex; use std::time::Duration; use std::{sync::Arc, thread}; use swaybar_types as sbt; +use swayipc as si; pub fn start() { env_logger::Builder::from_env(Env::default().default_filter_or("warn")) @@ -38,8 +39,24 @@ pub fn start() { let mods_for_input = mods.clone(); let trigger = Arc::new((Mutex::new((String::new(), String::new())), Condvar::new())); + let trigger_for_input = trigger.clone(); thread::spawn(move || handle_input(mods_for_input, trigger_for_input)); + + let window_mods: Vec = mods + .iter() + .filter(|m| m.get_config().name == "window") + .map(|m| (m.get_config().name.clone(), m.get_config().instance.clone())) + .collect(); + if !window_mods.is_empty() { + // There's at least a window module, so subscribe to focus events for + // immediate refreshes. + let trigger_for_events = trigger.clone(); + thread::spawn(move || { + handle_sway_events(window_mods, trigger_for_events) + }); + } + generate_status(&mods, trigger, refresh_interval); } @@ -62,7 +79,7 @@ fn create_modules(config: config::Config) -> Vec> { mods } -pub fn handle_input( +fn handle_input( mods: Arc>>, trigger: Arc<(Mutex, Condvar)>, ) { @@ -152,7 +169,77 @@ fn execute_command(cmd: &[String]) { } } -pub fn generate_status( +fn sway_subscribe() -> si::Fallible { + si::Connection::new()?.subscribe(&[ + si::EventType::Window, + si::EventType::Shutdown, + si::EventType::Workspace, + ]) +} + +fn handle_sway_events( + window_mods: Vec, + trigger: Arc<(Mutex, Condvar)>, +) { + let mut resets = 0; + let max_resets = 10; + + 'reset: loop { + if resets >= max_resets { + break; + } + resets += 1; + + log::debug!("Connecting to sway for subscribing to events..."); + + match sway_subscribe() { + Err(err) => { + log::warn!("Could not connect and subscribe: {}", err); + std::thread::sleep(std::time::Duration::from_secs(3)); + } + Ok(iter) => { + for ev_result in iter { + resets = 0; + match ev_result { + Ok(ev) => match ev { + si::Event::Window(_) | si::Event::Workspace(_) => { + log::trace!( + "Window or Workspace event: {:?}", + ev + ); + for m in &window_mods { + let (mtx, cvar) = &*trigger; + let mut name_and_instance = + mtx.lock().unwrap(); + name_and_instance.0 = m.0.to_owned(); + name_and_instance.1 = m.1.to_owned(); + cvar.notify_one(); + } + } + si::Event::Shutdown(sd_ev) => { + log::debug!( + "Sway shuts down with reason '{:?}'.", + sd_ev.change + ); + break 'reset; + } + _ => (), + }, + Err(e) => { + log::warn!("Error while receiving events: {}", e); + std::thread::sleep(std::time::Duration::from_secs( + 3, + )); + log::warn!("Resetting!"); + } + } + } + } + } + } +} + +fn generate_status( mods: &[Box], trigger: Arc<(Mutex, Condvar)>, refresh_interval: u64,