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,