|
|
@ -30,6 +30,7 @@ use std::sync::Arc; |
|
|
|
use std::sync::RwLock; |
|
|
|
use std::sync::RwLock; |
|
|
|
use std::thread; |
|
|
|
use std::thread; |
|
|
|
use std::time::Duration; |
|
|
|
use std::time::Duration; |
|
|
|
|
|
|
|
use std::time::Instant; |
|
|
|
use swayipc as s; |
|
|
|
use swayipc as s; |
|
|
|
|
|
|
|
|
|
|
|
pub fn run_daemon() { |
|
|
|
pub fn run_daemon() { |
|
|
@ -41,6 +42,7 @@ pub fn run_daemon() { |
|
|
|
|
|
|
|
|
|
|
|
let config = config::load_config(); |
|
|
|
let config = config::load_config(); |
|
|
|
let lockin_delay = config.get_focus_lockin_delay(); |
|
|
|
let lockin_delay = config.get_focus_lockin_delay(); |
|
|
|
|
|
|
|
let sequence_timeout = config.get_focus_sequence_timeout(); |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
let fdata = fdata.clone(); |
|
|
|
let fdata = fdata.clone(); |
|
|
@ -52,7 +54,12 @@ pub fn run_daemon() { |
|
|
|
{ |
|
|
|
{ |
|
|
|
let fdata = fdata.clone(); |
|
|
|
let fdata = fdata.clone(); |
|
|
|
thread::spawn(move || { |
|
|
|
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)] |
|
|
|
#[derive(Debug)] |
|
|
|
enum InhibitState { |
|
|
|
enum InhibitState { |
|
|
|
FocusInhibit, |
|
|
|
FocusInhibit, |
|
|
|
|
|
|
|
FocusInhibitUntil(Instant), |
|
|
|
FocusActive, |
|
|
|
FocusActive, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl InhibitState { |
|
|
|
impl InhibitState { |
|
|
|
pub fn set(&mut self) { |
|
|
|
pub fn is_inhibited(&self) -> bool { |
|
|
|
if let InhibitState::FocusActive = self { |
|
|
|
match self { |
|
|
|
log::debug!("Inhibiting tick focus updates"); |
|
|
|
InhibitState::FocusActive => false, |
|
|
|
*self = InhibitState::FocusInhibit; |
|
|
|
InhibitState::FocusInhibit => true, |
|
|
|
|
|
|
|
InhibitState::FocusInhibitUntil(t) => &Instant::now() < t, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn set(&mut self, timeout: Option<Duration>) { |
|
|
|
|
|
|
|
*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) { |
|
|
|
pub fn clear(&mut self) { |
|
|
|
if let InhibitState::FocusInhibit = self { |
|
|
|
if self.is_inhibited() { |
|
|
|
log::debug!("Activating tick focus updates"); |
|
|
|
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<FocusMessage>, |
|
|
|
focus_chan: mpsc::Receiver<FocusMessage>, |
|
|
|
fdata: FocusData, |
|
|
|
fdata: FocusData, |
|
|
|
lockin_delay: Duration, |
|
|
|
lockin_delay: Duration, |
|
|
|
|
|
|
|
sequence_timeout: Option<Duration>, |
|
|
|
) { |
|
|
|
) { |
|
|
|
// Focus event that has not yet been locked-in to the LRU order
|
|
|
|
// Focus event that has not yet been locked-in to the LRU order
|
|
|
|
let mut pending_fev: Option<FocusEvent> = None; |
|
|
|
let mut pending_fev: Option<FocusEvent> = None; |
|
|
@ -309,7 +356,7 @@ fn focus_lock_in_handler( |
|
|
|
|
|
|
|
|
|
|
|
let mut fev = match fmsg { |
|
|
|
let mut fev = match fmsg { |
|
|
|
FocusMessage::TickUpdateInhibit => { |
|
|
|
FocusMessage::TickUpdateInhibit => { |
|
|
|
inhibit.set(); |
|
|
|
inhibit.set(sequence_timeout); |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
FocusMessage::TickUpdateActivate => { |
|
|
|
FocusMessage::TickUpdateActivate => { |
|
|
@ -318,7 +365,7 @@ fn focus_lock_in_handler( |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
FocusMessage::FocusEvent(fev) => { |
|
|
|
FocusMessage::FocusEvent(fev) => { |
|
|
|
if let InhibitState::FocusInhibit = inhibit { |
|
|
|
if inhibit.is_inhibited() { |
|
|
|
// update the pending event but take no further action
|
|
|
|
// update the pending event but take no further action
|
|
|
|
pending_fev = Some(fev); |
|
|
|
pending_fev = Some(fev); |
|
|
|
continue; |
|
|
|
continue; |
|
|
@ -343,7 +390,7 @@ fn focus_lock_in_handler( |
|
|
|
// inhibit requested before currently focused container
|
|
|
|
// inhibit requested before currently focused container
|
|
|
|
// was locked-in, set it as pending in case no other
|
|
|
|
// was locked-in, set it as pending in case no other
|
|
|
|
// focus changes are made while updates remain inhibited
|
|
|
|
// focus changes are made while updates remain inhibited
|
|
|
|
inhibit.set(); |
|
|
|
inhibit.set(sequence_timeout); |
|
|
|
pending_fev = Some(fev); |
|
|
|
pending_fev = Some(fev); |
|
|
|
break; // return to outer loop with a preset pending_fev
|
|
|
|
break; // return to outer loop with a preset pending_fev
|
|
|
|
} |
|
|
|
} |
|
|
|