fix(wm): avoid dupes when following links

When adding selective handling of Uncloak events, a regression was
introduced where, for example, when clicking a link from Discord on
Workspace 2, a Firefox instance on Workspace 1 would be moved to
Workspace 2 to open the link, but when moving back to Workspace 1, a
ghost tile would be left, and the Firefox instance would be duplicated
across two workspaces.

This commit fixes this regression and makes the handler a bit easier to
reason about while also removing unnecessary early return statements
which prevent notifcations from getting sent to subscribers.
This commit is contained in:
LGUG2Z
2024-05-09 20:10:36 -07:00
parent 11acff5236
commit 598f9ec0aa
+15 -7
View File
@@ -287,7 +287,6 @@ impl WindowManager {
WindowManagerEvent::Show(_, window) WindowManagerEvent::Show(_, window)
| WindowManagerEvent::Manage(window) | WindowManagerEvent::Manage(window)
| WindowManagerEvent::Uncloak(_, window) => { | WindowManagerEvent::Uncloak(_, window) => {
if !matches!(event, WindowManagerEvent::Uncloak(_, _)) {
let mut switch_to = None; let mut switch_to = None;
for (i, monitors) in self.monitors().iter().enumerate() { for (i, monitors) in self.monitors().iter().enumerate() {
for (j, workspace) in monitors.workspaces().iter().enumerate() { for (j, workspace) in monitors.workspaces().iter().enumerate() {
@@ -297,7 +296,9 @@ impl WindowManager {
} }
} }
if let Some((known_monitor_idx, known_workspace_idx)) = switch_to { match switch_to {
Some((known_monitor_idx, known_workspace_idx)) => {
if !matches!(event, WindowManagerEvent::Uncloak(_, _)) {
if self.focused_monitor_idx() != known_monitor_idx if self.focused_monitor_idx() != known_monitor_idx
|| self || self
.focused_monitor() .focused_monitor()
@@ -307,16 +308,17 @@ impl WindowManager {
{ {
self.focus_monitor(known_monitor_idx)?; self.focus_monitor(known_monitor_idx)?;
self.focus_workspace(known_workspace_idx)?; self.focus_workspace(known_workspace_idx)?;
return Ok(());
} }
} }
} }
None => {
// There are some applications such as Firefox where, if they are focused when a // 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 // 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 // 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 // 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. // duplicates across multiple workspaces, as it results in ghost layout tiles.
let mut proceed = true;
for (i, monitor) in self.monitors().iter().enumerate() { for (i, monitor) in self.monitors().iter().enumerate() {
for (j, workspace) in monitor.workspaces().iter().enumerate() { for (j, workspace) in monitor.workspaces().iter().enumerate() {
if workspace.container_for_window(window.hwnd).is_some() if workspace.container_for_window(window.hwnd).is_some()
@@ -328,15 +330,16 @@ impl WindowManager {
); );
window.hide(); window.hide();
return Ok(()); proceed = false;
} }
} }
} }
if proceed {
let behaviour = self.window_container_behaviour; let behaviour = self.window_container_behaviour;
let workspace = self.focused_workspace_mut()?; let workspace = self.focused_workspace_mut()?;
if !workspace.contains_window(window.hwnd) { if !workspace.contains_window(window.hwnd) && switch_to.is_none() {
match behaviour { match behaviour {
WindowContainerBehaviour::Create => { WindowContainerBehaviour::Create => {
workspace.new_container_for_window(window); workspace.new_container_for_window(window);
@@ -345,13 +348,18 @@ impl WindowManager {
WindowContainerBehaviour::Append => { WindowContainerBehaviour::Append => {
workspace workspace
.focused_container_mut() .focused_container_mut()
.ok_or_else(|| anyhow!("there is no focused container"))? .ok_or_else(|| {
anyhow!("there is no focused container")
})?
.add_window(window); .add_window(window);
self.update_focused_workspace(true, false)?; self.update_focused_workspace(true, false)?;
} }
} }
} }
} }
}
}
}
WindowManagerEvent::MoveResizeStart(_, window) => { WindowManagerEvent::MoveResizeStart(_, window) => {
if *self.focused_workspace()?.tile() { if *self.focused_workspace()?.tile() {
let monitor_idx = self.focused_monitor_idx(); let monitor_idx = self.focused_monitor_idx();