diff --git a/komorebi/src/lib.rs b/komorebi/src/lib.rs index b8076102..f2758dac 100644 --- a/komorebi/src/lib.rs +++ b/komorebi/src/lib.rs @@ -165,6 +165,13 @@ lazy_static! { "X410.exe".to_string(), "vcxsrv.exe".to_string(), ])); + static ref SLOW_APPLICATION_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![ + MatchingRule::Simple(IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("firefox.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + }), + ])); static ref SUBSCRIPTION_PIPES: Arc>> = Arc::new(Mutex::new(HashMap::new())); pub static ref SUBSCRIPTION_SOCKETS: Arc>> = @@ -231,6 +238,8 @@ pub static REMOVE_TITLEBARS: AtomicBool = AtomicBool::new(false); pub static ANIMATION_ENABLED: AtomicBool = AtomicBool::new(false); pub static ANIMATION_DURATION: AtomicU64 = AtomicU64::new(250); +pub static SLOW_APPLICATION_COMPENSATION_TIME: AtomicU64 = AtomicU64::new(20); + #[must_use] pub fn current_virtual_desktop() -> Option> { let hkcu = RegKey::predef(HKEY_CURRENT_USER); diff --git a/komorebi/src/static_config.rs b/komorebi/src/static_config.rs index 409025ed..c920f84e 100644 --- a/komorebi/src/static_config.rs +++ b/komorebi/src/static_config.rs @@ -42,6 +42,8 @@ use crate::MANAGE_IDENTIFIERS; use crate::MONITOR_INDEX_PREFERENCES; use crate::OBJECT_NAME_CHANGE_ON_LAUNCH; use crate::REGEX_IDENTIFIERS; +use crate::SLOW_APPLICATION_COMPENSATION_TIME; +use crate::SLOW_APPLICATION_IDENTIFIERS; use crate::TRANSPARENCY_BLACKLIST; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; use crate::WINDOWS_11; @@ -333,6 +335,12 @@ pub struct StaticConfig { /// Theme configuration options #[serde(skip_serializing_if = "Option::is_none")] pub theme: Option, + /// Identify applications which are slow to send initial event notifications + #[serde(skip_serializing_if = "Option::is_none")] + pub slow_application_identifiers: Option>, + /// How long to wait when compensating for slow applications, in milliseconds (default: 20) + #[serde(skip_serializing_if = "Option::is_none")] + pub slow_application_compensation_time: Option, } #[derive(Debug, Serialize, Deserialize, JsonSchema)] @@ -544,6 +552,10 @@ impl From<&WindowManager> for StaticConfig { stackbar: None, animation: None, theme: None, + slow_application_compensation_time: Option::from( + SLOW_APPLICATION_COMPENSATION_TIME.load(Ordering::SeqCst), + ), + slow_application_identifiers: Option::from(SLOW_APPLICATION_IDENTIFIERS.lock().clone()), } } } @@ -652,6 +664,7 @@ impl StaticConfig { let mut object_name_change_identifiers = OBJECT_NAME_CHANGE_ON_LAUNCH.lock(); let mut layered_identifiers = LAYERED_WHITELIST.lock(); let mut transparency_blacklist = TRANSPARENCY_BLACKLIST.lock(); + let mut slow_application_identifiers = SLOW_APPLICATION_IDENTIFIERS.lock(); if let Some(rules) = &mut self.float_rules { populate_rules(rules, &mut float_identifiers, &mut regex_identifiers)?; @@ -685,6 +698,14 @@ impl StaticConfig { populate_rules(rules, &mut transparency_blacklist, &mut regex_identifiers)?; } + if let Some(rules) = &mut self.slow_application_identifiers { + populate_rules( + rules, + &mut slow_application_identifiers, + &mut regex_identifiers, + )?; + } + if let Some(stackbar) = &self.stackbar { if let Some(height) = &stackbar.height { STACKBAR_TAB_HEIGHT.store(*height, Ordering::SeqCst); diff --git a/komorebi/src/window.rs b/komorebi/src/window.rs index 97acd326..336398a7 100644 --- a/komorebi/src/window.rs +++ b/komorebi/src/window.rs @@ -6,6 +6,8 @@ use crate::windows_api; use crate::ANIMATIONS_IN_PROGRESS; use crate::ANIMATION_DURATION; use crate::ANIMATION_ENABLED; +use crate::SLOW_APPLICATION_COMPENSATION_TIME; +use crate::SLOW_APPLICATION_IDENTIFIERS; use std::collections::HashMap; use std::convert::TryFrom; use std::fmt::Display; @@ -634,8 +636,23 @@ fn window_is_eligible( titlebars_removed.contains(exe_name) }; - if exe_name.contains("firefox") { - std::thread::sleep(Duration::from_millis(10)); + { + let slow_application_identifiers = SLOW_APPLICATION_IDENTIFIERS.lock(); + let should_sleep = should_act( + title, + exe_name, + class, + path, + &slow_application_identifiers, + ®ex_identifiers, + ) + .is_some(); + + if should_sleep { + std::thread::sleep(Duration::from_millis( + SLOW_APPLICATION_COMPENSATION_TIME.load(Ordering::SeqCst), + )); + } } if (allow_wsl2_gui || allow_titlebar_removed || style.contains(WindowStyle::CAPTION) && ex_style.contains(ExtendedWindowStyle::WINDOWEDGE))