fix(wm): don't duplicate windows across workspaces

There are some applications such as Firefox where, if they are focused
when a workspace switch takes place, an additional Show event will be
fired. This results in the window being associated with both the
original workspace and the workspace being switched to.

This commit adds a check when handling WindowManagerEvent::Show to try
and ignore events from windows that are already known to be associated
with other workspaces (which are not the currently focused workspace).
This commit is contained in:
LGUG2Z
2021-08-15 07:31:42 -07:00
parent a59bbacb29
commit 126eee49ca
3 changed files with 27 additions and 2 deletions

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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<usize> {
fn container_idx_for_window(&self, hwnd: isize) -> Option<usize> {
let mut idx = None;
for (i, x) in self.containers().iter().enumerate() {
if x.contains_window(hwnd) {