diff --git a/komorebi-core/src/lib.rs b/komorebi-core/src/lib.rs index c541fab2..5a01e402 100644 --- a/komorebi-core/src/lib.rs +++ b/komorebi-core/src/lib.rs @@ -57,10 +57,8 @@ pub enum SocketMessage { // Configuration ReloadConfiguration, WatchConfiguration(bool), - FloatClass(String), - FloatExe(String), - FloatTitle(String), WorkspaceRule(ApplicationIdentifier, String, usize, usize), + FloatRule(ApplicationIdentifier, String), ManageRule(ApplicationIdentifier, String), IdentifyTrayApplication(ApplicationIdentifier, String), State, diff --git a/komorebi/src/main.rs b/komorebi/src/main.rs index 5d4dd7df..17f112a3 100644 --- a/komorebi/src/main.rs +++ b/komorebi/src/main.rs @@ -48,9 +48,6 @@ mod winevent_listener; mod workspace; lazy_static! { - static ref FLOAT_CLASSES: Arc>> = Arc::new(Mutex::new(vec![])); - static ref FLOAT_EXES: Arc>> = Arc::new(Mutex::new(vec![])); - static ref FLOAT_TITLES: Arc>> = Arc::new(Mutex::new(vec![])); static ref HIDDEN_HWNDS: Arc>> = Arc::new(Mutex::new(vec![])); static ref LAYERED_EXE_WHITELIST: Arc>> = Arc::new(Mutex::new(vec!["steam.exe".to_string()])); @@ -71,6 +68,7 @@ lazy_static! { static ref WORKSPACE_RULES: Arc>> = Arc::new(Mutex::new(HashMap::new())); static ref MANAGE_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![])); + static ref FLOAT_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![])); } fn setup() -> Result<(WorkerGuard, WorkerGuard)> { diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 55e6350e..bfd9a7b5 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -16,9 +16,7 @@ use komorebi_core::SocketMessage; use crate::window_manager; use crate::window_manager::WindowManager; use crate::windows_api::WindowsApi; -use crate::FLOAT_CLASSES; -use crate::FLOAT_EXES; -use crate::FLOAT_TITLES; +use crate::FLOAT_IDENTIFIERS; use crate::MANAGE_IDENTIFIERS; use crate::TRAY_AND_MULTI_WINDOW_CLASSES; use crate::TRAY_AND_MULTI_WINDOW_EXES; @@ -52,18 +50,7 @@ pub fn listen_for_commands(wm: Arc>) { impl WindowManager { #[tracing::instrument(skip(self))] pub fn process_command(&mut self, message: SocketMessage) -> Result<()> { - let virtual_desktop_id = winvd::helpers::get_current_desktop_number().ok(); - if let (Some(id), Some(virtual_desktop_id)) = (virtual_desktop_id, self.virtual_desktop_id) - { - if id != virtual_desktop_id { - tracing::warn!( - "ignoring events while not on virtual desktop {:?}", - virtual_desktop_id - ); - - return Ok(()); - } - } + self.validate_virtual_desktop_id(); match message { SocketMessage::Promote => self.promote_container_to_front()?, @@ -87,24 +74,6 @@ impl WindowManager { SocketMessage::WorkspacePadding(monitor_idx, workspace_idx, size) => { self.set_workspace_padding(monitor_idx, workspace_idx, size)?; } - SocketMessage::FloatClass(target) => { - let mut float_classes = FLOAT_CLASSES.lock(); - if !float_classes.contains(&target) { - float_classes.push(target); - } - } - SocketMessage::FloatExe(target) => { - let mut float_exes = FLOAT_EXES.lock(); - if !float_exes.contains(&target) { - float_exes.push(target); - } - } - SocketMessage::FloatTitle(target) => { - let mut float_titles = FLOAT_TITLES.lock(); - if !float_titles.contains(&target) { - float_titles.push(target); - } - } SocketMessage::WorkspaceRule(identifier, id, monitor_idx, workspace_idx) => { match identifier { ApplicationIdentifier::Exe | ApplicationIdentifier::Class => { @@ -120,17 +89,19 @@ impl WindowManager { } SocketMessage::ManageRule(identifier, id) => match identifier { ApplicationIdentifier::Exe | ApplicationIdentifier::Class => { - { - let mut manage_identifiers = MANAGE_IDENTIFIERS.lock(); - if !manage_identifiers.contains(&id) { - manage_identifiers.push(id); - } + let mut manage_identifiers = MANAGE_IDENTIFIERS.lock(); + if !manage_identifiers.contains(&id) { + manage_identifiers.push(id); } - - self.update_focused_workspace(false)?; } ApplicationIdentifier::Title => {} }, + SocketMessage::FloatRule(_, id) => { + let mut float_identifiers = FLOAT_IDENTIFIERS.lock(); + if !float_identifiers.contains(&id) { + float_identifiers.push(id); + } + } SocketMessage::AdjustContainerPadding(sizing, adjustment) => { self.adjust_container_padding(sizing, adjustment)?; } diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index de54ac66..aaa506c2 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -48,18 +48,7 @@ impl WindowManager { return Ok(()); } - let virtual_desktop_id = winvd::helpers::get_current_desktop_number().ok(); - if let (Some(id), Some(virtual_desktop_id)) = (virtual_desktop_id, self.virtual_desktop_id) - { - if id != virtual_desktop_id { - tracing::warn!( - "ignoring events while not on virtual desktop {:?}", - virtual_desktop_id - ); - - return Ok(()); - } - } + self.validate_virtual_desktop_id(); // Make sure we have the most recently focused monitor from any event match event { diff --git a/komorebi/src/window.rs b/komorebi/src/window.rs index cc88325a..dd32e7de 100644 --- a/komorebi/src/window.rs +++ b/komorebi/src/window.rs @@ -15,9 +15,7 @@ use crate::styles::GwlExStyle; use crate::styles::GwlStyle; use crate::window_manager_event::WindowManagerEvent; use crate::windows_api::WindowsApi; -use crate::FLOAT_CLASSES; -use crate::FLOAT_EXES; -use crate::FLOAT_TITLES; +use crate::FLOAT_IDENTIFIERS; use crate::HIDDEN_HWNDS; use crate::LAYERED_EXE_WHITELIST; use crate::MANAGE_IDENTIFIERS; @@ -220,10 +218,6 @@ impl Window { #[tracing::instrument(fields(exe, title))] pub fn should_manage(self, event: Option) -> Result { - let float_classes = FLOAT_CLASSES.lock(); - let float_exes = FLOAT_EXES.lock(); - let float_titles = FLOAT_TITLES.lock(); - if self.title().is_err() { return Ok(false); } @@ -241,21 +235,24 @@ impl Window { // If not allowing cloaked windows, we need to ensure the window is not cloaked (false, false) => { if let (Ok(title), Ok(exe_name), Ok(class)) = (self.title(), self.exe(), self.class()) { - if float_titles.contains(&title) { - return Ok(false); - } - - if float_exes.contains(&exe_name) { - return Ok(false); - } - - if let Ok(class) = self.class() { - if float_classes.contains(&class) { + { + let float_identifiers = FLOAT_IDENTIFIERS.lock(); + if float_identifiers.contains(&title) + || float_identifiers.contains(&exe_name) + || float_identifiers.contains(&class) { return Ok(false); } } - let allow_layered = LAYERED_EXE_WHITELIST.lock().contains(&exe_name); + let managed_override = { + let manage_identifiers = MANAGE_IDENTIFIERS.lock(); + manage_identifiers.contains(&exe_name) || manage_identifiers.contains(&class) + }; + + let allow_layered = { + let layered_exe_whitelist = LAYERED_EXE_WHITELIST.lock(); + layered_exe_whitelist.contains(&exe_name) + }; let style = self.style()?; let ex_style = self.ex_style()?; @@ -268,21 +265,17 @@ impl Window { // allowing a specific layered window on the whitelist (like Steam), it should // pass this check && (allow_layered || !ex_style.contains(GwlExStyle::LAYERED)) - || MANAGE_IDENTIFIERS.lock().contains(&exe_name) || MANAGE_IDENTIFIERS.lock().contains(&class) + || managed_override { - Ok(true) - } else { - if event.is_some() { - tracing::debug!("ignoring (exe: {}, title: {})", exe_name, title); - } - - Ok(false) + return Ok(true) + } else if event.is_some() { + tracing::debug!("ignoring (exe: {}, title: {})", exe_name, title); } - } else { - Ok(false) } } - _ => Ok(false), + _ => {} } + + Ok(false) } } diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 4d9e1f7e..8b694794 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -30,10 +30,9 @@ use crate::window_manager_event::WindowManagerEvent; use crate::windows_api::WindowsApi; use crate::winevent_listener::WINEVENT_CALLBACK_CHANNEL; use crate::workspace::Workspace; -use crate::FLOAT_CLASSES; -use crate::FLOAT_EXES; -use crate::FLOAT_TITLES; +use crate::FLOAT_IDENTIFIERS; use crate::LAYERED_EXE_WHITELIST; +use crate::MANAGE_IDENTIFIERS; use crate::TRAY_AND_MULTI_WINDOW_CLASSES; use crate::TRAY_AND_MULTI_WINDOW_EXES; use crate::WORKSPACE_RULES; @@ -52,9 +51,8 @@ pub struct WindowManager { pub struct State { pub monitors: Ring, pub is_paused: bool, - pub float_classes: Vec, - pub float_exes: Vec, - pub float_titles: Vec, + pub float_identifiers: Vec, + pub manage_identifiers: Vec, pub layered_exe_whitelist: Vec, pub tray_and_multi_window_exes: Vec, pub tray_and_multi_window_classes: Vec, @@ -66,9 +64,8 @@ impl From<&mut WindowManager> for State { Self { monitors: wm.monitors.clone(), is_paused: wm.is_paused, - float_classes: FLOAT_CLASSES.lock().clone(), - float_exes: FLOAT_EXES.lock().clone(), - float_titles: FLOAT_TITLES.lock().clone(), + float_identifiers: FLOAT_IDENTIFIERS.lock().clone(), + manage_identifiers: MANAGE_IDENTIFIERS.lock().clone(), layered_exe_whitelist: LAYERED_EXE_WHITELIST.lock().clone(), tray_and_multi_window_exes: TRAY_AND_MULTI_WINDOW_EXES.lock().clone(), tray_and_multi_window_classes: TRAY_AND_MULTI_WINDOW_CLASSES.lock().clone(), @@ -334,6 +331,20 @@ impl WindowManager { Ok(()) } + #[tracing::instrument(skip(self))] + pub fn validate_virtual_desktop_id(&self) { + let virtual_desktop_id = winvd::helpers::get_current_desktop_number().ok(); + if let (Some(id), Some(virtual_desktop_id)) = (virtual_desktop_id, self.virtual_desktop_id) + { + if id != virtual_desktop_id { + tracing::warn!( + "ignoring events while not on virtual desktop {}", + virtual_desktop_id + ); + } + } + } + #[tracing::instrument(skip(self))] pub fn manage_focused_window(&mut self) -> Result<()> { let hwnd = WindowsApi::foreground_window()?; diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 48ac32c0..3fd84f41 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -424,17 +424,9 @@ fn main() -> Result<()> { SubCommand::Stop => { send_message(&*SocketMessage::Stop.as_bytes()?)?; } - SubCommand::FloatRule(arg) => match arg.identifier { - ApplicationIdentifier::Exe => { - send_message(&*SocketMessage::FloatExe(arg.id).as_bytes()?)?; - } - ApplicationIdentifier::Class => { - send_message(&*SocketMessage::FloatClass(arg.id).as_bytes()?)?; - } - ApplicationIdentifier::Title => { - send_message(&*SocketMessage::FloatTitle(arg.id).as_bytes()?)?; - } - }, + SubCommand::FloatRule(arg) => { + send_message(&*SocketMessage::FloatRule(arg.identifier, arg.id).as_bytes()?)?; + } SubCommand::ManageRule(arg) => { send_message(&*SocketMessage::ManageRule(arg.identifier, arg.id).as_bytes()?)?; }