fix(wm): enforce strict manage override checks

This commit ensures that when a window has matched a float rule, the
managed override rule will only apply to that window if the override
identifier is of the same kind (exe, title, class) as the float rule
identifier.

This ensures that the wm isn't constantly trying to allow and disallow
certain windows such as Slack's hidden window, resulting in an infinite
show/hide and retile loop.
This commit is contained in:
LGUG2Z
2022-07-25 20:52:27 -07:00
parent 77ae5bc2f4
commit eec628f7f1
+52 -22
View File
@@ -12,6 +12,7 @@ use serde::Serialize;
use serde::Serializer; use serde::Serializer;
use windows::Win32::Foundation::HWND; use windows::Win32::Foundation::HWND;
use komorebi_core::ApplicationIdentifier;
use komorebi_core::HidingBehaviour; use komorebi_core::HidingBehaviour;
use komorebi_core::Rect; use komorebi_core::Rect;
@@ -293,45 +294,79 @@ impl Window {
// If not allowing cloaked windows, we need to ensure the window is not cloaked // If not allowing cloaked windows, we need to ensure the window is not cloaked
(false, false) => { (false, false) => {
if let (Ok(title), Ok(exe_name), Ok(class)) = (self.title(), self.exe(), self.class()) { if let (Ok(title), Ok(exe_name), Ok(class)) = (self.title(), self.exe(), self.class()) {
return Ok(window_is_eligible(&title, &exe_name, &class, self.style()?, self.ex_style()?, event));
}
}
_ => {}
}
Ok(false)
}
}
fn window_is_eligible(
title: &String,
exe_name: &String,
class: &String,
style: WindowStyle,
ex_style: ExtendedWindowStyle,
event: Option<WindowManagerEvent>,
) -> bool {
let mut should_float = false; let mut should_float = false;
let mut matched_identifier = None;
{ {
let float_identifiers = FLOAT_IDENTIFIERS.lock(); let float_identifiers = FLOAT_IDENTIFIERS.lock();
for identifier in float_identifiers.iter() { for identifier in float_identifiers.iter() {
if title.starts_with(identifier) || title.ends_with(identifier) || if title.starts_with(identifier) || title.ends_with(identifier) {
class.starts_with(identifier) || class.ends_with(identifier) ||
identifier == &exe_name {
should_float = true; should_float = true;
matched_identifier = Option::from(ApplicationIdentifier::Title);
}
if class.starts_with(identifier) || class.ends_with(identifier) {
should_float = true;
matched_identifier = Option::from(ApplicationIdentifier::Class);
}
if identifier == exe_name {
should_float = true;
matched_identifier = Option::from(ApplicationIdentifier::Exe);
} }
} }
} };
let managed_override = { let managed_override = {
let manage_identifiers = MANAGE_IDENTIFIERS.lock(); let manage_identifiers = MANAGE_IDENTIFIERS.lock();
manage_identifiers.contains(&exe_name) matched_identifier.map_or_else(
|| manage_identifiers.contains(&class) || {
|| manage_identifiers.contains(&title) manage_identifiers.contains(exe_name)
|| manage_identifiers.contains(class)
|| manage_identifiers.contains(title)
},
|matched_identifier| match matched_identifier {
ApplicationIdentifier::Exe => manage_identifiers.contains(exe_name),
ApplicationIdentifier::Class => manage_identifiers.contains(class),
ApplicationIdentifier::Title => manage_identifiers.contains(title),
},
)
}; };
if should_float && !managed_override { if should_float && !managed_override {
return Ok(false); return false;
} }
let allow_layered = { let allow_layered = {
let layered_whitelist = LAYERED_WHITELIST.lock(); let layered_whitelist = LAYERED_WHITELIST.lock();
layered_whitelist.contains(&exe_name) layered_whitelist.contains(exe_name)
|| layered_whitelist.contains(&class) || layered_whitelist.contains(class)
|| layered_whitelist.contains(&title) || layered_whitelist.contains(title)
}; };
let allow_wsl2_gui = { let allow_wsl2_gui = {
let wsl2_ui_processes = WSL2_UI_PROCESSES.lock(); let wsl2_ui_processes = WSL2_UI_PROCESSES.lock();
wsl2_ui_processes.contains(&exe_name) wsl2_ui_processes.contains(exe_name)
}; };
let style = self.style()?;
let ex_style = self.ex_style()?;
if (allow_wsl2_gui || style.contains(WindowStyle::CAPTION) && ex_style.contains(ExtendedWindowStyle::WINDOWEDGE)) if (allow_wsl2_gui || style.contains(WindowStyle::CAPTION) && ex_style.contains(ExtendedWindowStyle::WINDOWEDGE))
&& !ex_style.contains(ExtendedWindowStyle::DLGMODALFRAME) && !ex_style.contains(ExtendedWindowStyle::DLGMODALFRAME)
// Get a lot of dupe events coming through that make the redrawing go crazy // Get a lot of dupe events coming through that make the redrawing go crazy
@@ -341,15 +376,10 @@ impl Window {
&& (allow_layered || !ex_style.contains(ExtendedWindowStyle::LAYERED)) && (allow_layered || !ex_style.contains(ExtendedWindowStyle::LAYERED))
|| managed_override || managed_override
{ {
return Ok(true); return true;
} else if event.is_some() { } else if event.is_some() {
tracing::debug!("ignoring (exe: {}, title: {})", exe_name, title); tracing::debug!("ignoring (exe: {}, title: {})", exe_name, title);
} }
}
}
_ => {}
}
Ok(false) false
}
} }