diff --git a/swayr/src/daemon.rs b/swayr/src/daemon.rs index 69d174b..1b8e06c 100644 --- a/swayr/src/daemon.rs +++ b/swayr/src/daemon.rs @@ -30,6 +30,7 @@ use std::sync::Arc; use std::sync::RwLock; use std::thread; use std::time::Duration; +use std::time::Instant; use swayipc as s; pub fn run_daemon() { @@ -41,6 +42,7 @@ pub fn run_daemon() { let config = config::load_config(); let lockin_delay = config.get_focus_lockin_delay(); + let sequence_timeout = config.get_focus_sequence_timeout(); { let fdata = fdata.clone(); @@ -52,7 +54,12 @@ pub fn run_daemon() { { let fdata = fdata.clone(); thread::spawn(move || { - focus_lock_in_handler(focus_rx, fdata, lockin_delay); + focus_lock_in_handler( + focus_rx, + fdata, + lockin_delay, + sequence_timeout, + ); }); } @@ -263,22 +270,61 @@ fn handle_client_request(mut stream: UnixStream, fdata: &FocusData) { #[derive(Debug)] enum InhibitState { FocusInhibit, + FocusInhibitUntil(Instant), FocusActive, } impl InhibitState { - pub fn set(&mut self) { - if let InhibitState::FocusActive = self { - log::debug!("Inhibiting tick focus updates"); - *self = InhibitState::FocusInhibit; + pub fn is_inhibited(&self) -> bool { + match self { + InhibitState::FocusActive => false, + InhibitState::FocusInhibit => true, + InhibitState::FocusInhibitUntil(t) => &Instant::now() < t, + } + } + + pub fn set(&mut self, timeout: Option) { + *self = match timeout { + None => match *self { + InhibitState::FocusInhibit => InhibitState::FocusInhibit, + _ => { + log::debug!("Inhibiting tick focus updates"); + InhibitState::FocusInhibit + } + }, + Some(d) => { + let new_time = Instant::now() + d; + match *self { + // Inhibit only ever gets extended unless clear() is called + InhibitState::FocusInhibit => InhibitState::FocusInhibit, + InhibitState::FocusInhibitUntil(old_time) => { + if old_time > new_time { + InhibitState::FocusInhibitUntil(old_time) + } else { + log::debug!( + "Extending tick focus updates inhibit by {}ms", + (new_time - old_time).as_millis() + ); + InhibitState::FocusInhibitUntil(new_time) + } + } + InhibitState::FocusActive => { + log::debug!( + "Inhibiting tick focus updates for {}ms", + d.as_millis() + ); + InhibitState::FocusInhibitUntil(new_time) + } + } + } } } pub fn clear(&mut self) { - if let InhibitState::FocusInhibit = self { + if self.is_inhibited() { log::debug!("Activating tick focus updates"); - *self = InhibitState::FocusActive; } + *self = InhibitState::FocusActive; } } @@ -286,6 +332,7 @@ fn focus_lock_in_handler( focus_chan: mpsc::Receiver, fdata: FocusData, lockin_delay: Duration, + sequence_timeout: Option, ) { // Focus event that has not yet been locked-in to the LRU order let mut pending_fev: Option = None; @@ -309,7 +356,7 @@ fn focus_lock_in_handler( let mut fev = match fmsg { FocusMessage::TickUpdateInhibit => { - inhibit.set(); + inhibit.set(sequence_timeout); continue; } FocusMessage::TickUpdateActivate => { @@ -318,7 +365,7 @@ fn focus_lock_in_handler( continue; } FocusMessage::FocusEvent(fev) => { - if let InhibitState::FocusInhibit = inhibit { + if inhibit.is_inhibited() { // update the pending event but take no further action pending_fev = Some(fev); continue; @@ -343,7 +390,7 @@ fn focus_lock_in_handler( // inhibit requested before currently focused container // was locked-in, set it as pending in case no other // focus changes are made while updates remain inhibited - inhibit.set(); + inhibit.set(sequence_timeout); pending_fev = Some(fev); break; // return to outer loop with a preset pending_fev }