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.
This commit is contained in:
LGUG2Z
2021-08-06 08:23:24 -07:00
parent bebf2f791a
commit 88d6eee7af
3 changed files with 23 additions and 3 deletions

View File

@@ -47,7 +47,8 @@ lazy_static! {
"firefox.exe".to_string(), "firefox.exe".to_string(),
"chrome.exe".to_string(), "chrome.exe".to_string(),
"idea64.exe".to_string(), "idea64.exe".to_string(),
"ApplicationFrameHost.exe".to_string() "ApplicationFrameHost.exe".to_string(),
"steam.exe".to_string()
])); ]));
} }

View File

@@ -123,7 +123,7 @@ impl WindowManager {
self.focus_workspace(workspace_idx)?; self.focus_workspace(workspace_idx)?;
} }
SocketMessage::Stop => { SocketMessage::Stop => {
tracing::error!( tracing::info!(
"received stop command, restoring all hidden windows and terminating process" "received stop command, restoring all hidden windows and terminating process"
); );
self.restore_all_windows(); self.restore_all_windows();

View File

@@ -108,17 +108,31 @@ impl Workspace {
pub fn reap_orphans(&mut self) -> Result<(usize, usize)> { pub fn reap_orphans(&mut self) -> Result<(usize, usize)> {
let mut hwnds = vec![]; let mut hwnds = vec![];
let mut floating_hwnds = vec![];
for window in self.visible_windows_mut().into_iter().flatten() { for window in self.visible_windows_mut().into_iter().flatten() {
if !window.is_window() { if !window.is_window() {
hwnds.push(window.hwnd); hwnds.push(window.hwnd);
} }
} }
for window in self.floating_windows() {
if !window.is_window() {
floating_hwnds.push(window.hwnd);
}
}
for hwnd in &hwnds { for hwnd in &hwnds {
tracing::debug!("reaping hwnd: {}", hwnd); tracing::debug!("reaping hwnd: {}", hwnd);
self.remove_window(*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![]; let mut container_ids = vec![];
for container in self.containers() { for container in self.containers() {
if container.windows().is_empty() { if container.windows().is_empty() {
@@ -129,7 +143,7 @@ impl Workspace {
self.containers_mut() self.containers_mut()
.retain(|c| !container_ids.contains(c.id())); .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<()> { 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<()> { 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 let container_idx = self
.container_idx_for_window(hwnd) .container_idx_for_window(hwnd)
.context("there is no window")?; .context("there is no window")?;