diff --git a/komorebi/src/container.rs b/komorebi/src/container.rs index e1d9d6df..ec555895 100644 --- a/komorebi/src/container.rs +++ b/komorebi/src/container.rs @@ -26,7 +26,7 @@ impl Default for Container { } } -impl PartialEq for &Container { +impl PartialEq for Container { fn eq(&self, other: &Self) -> bool { self.id == other.id } diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index 82f73d33..cc5769cb 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -138,6 +138,27 @@ impl WindowManager { } } + // There are some applications such as Firefox where, if they are focused when a + // workspace switch takes place, it will fire an additional Show event, which will + // result in them being associated with both the original workspace and the workspace + // being switched to. This loop is to try to ensure that we don't end up with + // duplicates across multiple workspaces, as it results in ghost layout tiles. + for (i, monitor) in self.monitors().iter().enumerate() { + for (j, workspace) in monitor.workspaces().iter().enumerate() { + if workspace.container_for_window(window.hwnd).is_some() + && i != self.focused_monitor_idx() + && j != monitor.focused_workspace_idx() + { + tracing::debug!( + "ignoring show event for window already associated with another workspace" + ); + + window.hide(); + return Ok(()); + } + } + } + let workspace = self.focused_workspace_mut()?; if workspace.containers().is_empty() || !workspace.contains_window(window.hwnd) { diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index 8aed25ec..edc79689 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -182,6 +182,10 @@ impl Workspace { Ok((hwnds.len() + floating_hwnds.len(), container_ids.len())) } + pub fn container_for_window(&self, hwnd: isize) -> Option<&Container> { + self.containers().get(self.container_idx_for_window(hwnd)?) + } + pub fn focus_container_by_window(&mut self, hwnd: isize) -> Result<()> { let container_idx = self .container_idx_for_window(hwnd) @@ -249,7 +253,7 @@ impl Workspace { self.containers_mut().remove(idx) } - fn container_idx_for_window(&mut self, hwnd: isize) -> Option { + fn container_idx_for_window(&self, hwnd: isize) -> Option { let mut idx = None; for (i, x) in self.containers().iter().enumerate() { if x.contains_window(hwnd) {