From 88d6eee7afbfae0751395469e5fa85ecc65ac02c Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Fri, 6 Aug 2021 08:23:24 -0700 Subject: [PATCH] fix(wm): clean stale floating windows from state Floating windows that were minimised or destroyed remained in the Workspace state because the call to workspace.remove_window() was only checking containers for a matching hwnd. This commit ensures that floating windows are checked before other window containers and removes the window from the Workspace state if necessary. This commit also adds steam.exe to the MULTI_WINDOW_EXES list to ensure the expected behaviour when responding to an ObjectHide event. --- komorebi/src/main.rs | 3 ++- komorebi/src/process_command.rs | 2 +- komorebi/src/workspace.rs | 21 ++++++++++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/komorebi/src/main.rs b/komorebi/src/main.rs index dbb3b91c..0acf888e 100644 --- a/komorebi/src/main.rs +++ b/komorebi/src/main.rs @@ -47,7 +47,8 @@ lazy_static! { "firefox.exe".to_string(), "chrome.exe".to_string(), "idea64.exe".to_string(), - "ApplicationFrameHost.exe".to_string() + "ApplicationFrameHost.exe".to_string(), + "steam.exe".to_string() ])); } diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 96be8e6b..9b36de28 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -123,7 +123,7 @@ impl WindowManager { self.focus_workspace(workspace_idx)?; } SocketMessage::Stop => { - tracing::error!( + tracing::info!( "received stop command, restoring all hidden windows and terminating process" ); self.restore_all_windows(); diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index 2482538f..bad345be 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -108,17 +108,31 @@ impl Workspace { pub fn reap_orphans(&mut self) -> Result<(usize, usize)> { let mut hwnds = vec![]; + let mut floating_hwnds = vec![]; + for window in self.visible_windows_mut().into_iter().flatten() { if !window.is_window() { hwnds.push(window.hwnd); } } + for window in self.floating_windows() { + if !window.is_window() { + floating_hwnds.push(window.hwnd); + } + } + for hwnd in &hwnds { tracing::debug!("reaping hwnd: {}", hwnd); self.remove_window(*hwnd)?; } + for hwnd in &floating_hwnds { + tracing::debug!("reaping floating hwnd: {}", hwnd); + self.floating_windows_mut() + .retain(|w| !floating_hwnds.contains(&w.hwnd)); + } + let mut container_ids = vec![]; for container in self.containers() { if container.windows().is_empty() { @@ -129,7 +143,7 @@ impl Workspace { self.containers_mut() .retain(|c| !container_ids.contains(c.id())); - Ok((hwnds.len(), container_ids.len())) + Ok((hwnds.len() + floating_hwnds.len(), container_ids.len())) } pub fn focus_container_by_window(&mut self, hwnd: isize) -> Result<()> { @@ -209,6 +223,11 @@ impl Workspace { } pub fn remove_window(&mut self, hwnd: isize) -> Result<()> { + if self.floating_windows().iter().any(|w| w.hwnd == hwnd) { + self.floating_windows_mut().retain(|w| w.hwnd != hwnd); + return Ok(()); + } + let container_idx = self .container_idx_for_window(hwnd) .context("there is no window")?;