mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-24 09:38:32 +02:00
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:
@@ -287,67 +287,75 @@ 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() {
|
if workspace.contains_window(window.hwnd) {
|
||||||
if workspace.contains_window(window.hwnd) {
|
switch_to = Some((i, j));
|
||||||
switch_to = Some((i, j));
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match switch_to {
|
||||||
|
Some((known_monitor_idx, known_workspace_idx)) => {
|
||||||
|
if !matches!(event, WindowManagerEvent::Uncloak(_, _)) {
|
||||||
|
if self.focused_monitor_idx() != known_monitor_idx
|
||||||
|
|| self
|
||||||
|
.focused_monitor()
|
||||||
|
.ok_or_else(|| anyhow!("there is no monitor"))?
|
||||||
|
.focused_workspace_idx()
|
||||||
|
!= known_workspace_idx
|
||||||
|
{
|
||||||
|
self.focus_monitor(known_monitor_idx)?;
|
||||||
|
self.focus_workspace(known_workspace_idx)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None => {
|
||||||
|
// 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.
|
||||||
|
let mut proceed = true;
|
||||||
|
|
||||||
if let Some((known_monitor_idx, known_workspace_idx)) = switch_to {
|
for (i, monitor) in self.monitors().iter().enumerate() {
|
||||||
if self.focused_monitor_idx() != known_monitor_idx
|
for (j, workspace) in monitor.workspaces().iter().enumerate() {
|
||||||
|| self
|
if workspace.container_for_window(window.hwnd).is_some()
|
||||||
.focused_monitor()
|
&& i != self.focused_monitor_idx()
|
||||||
.ok_or_else(|| anyhow!("there is no monitor"))?
|
&& j != monitor.focused_workspace_idx()
|
||||||
.focused_workspace_idx()
|
{
|
||||||
!= known_workspace_idx
|
tracing::debug!(
|
||||||
{
|
|
||||||
self.focus_monitor(known_monitor_idx)?;
|
|
||||||
self.focus_workspace(known_workspace_idx)?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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"
|
"ignoring show event for window already associated with another workspace"
|
||||||
);
|
);
|
||||||
|
|
||||||
window.hide();
|
window.hide();
|
||||||
return Ok(());
|
proceed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let behaviour = self.window_container_behaviour;
|
if proceed {
|
||||||
let workspace = self.focused_workspace_mut()?;
|
let behaviour = self.window_container_behaviour;
|
||||||
|
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);
|
||||||
self.update_focused_workspace(false, false)?;
|
self.update_focused_workspace(false, false)?;
|
||||||
}
|
}
|
||||||
WindowContainerBehaviour::Append => {
|
WindowContainerBehaviour::Append => {
|
||||||
workspace
|
workspace
|
||||||
.focused_container_mut()
|
.focused_container_mut()
|
||||||
.ok_or_else(|| anyhow!("there is no focused container"))?
|
.ok_or_else(|| {
|
||||||
.add_window(window);
|
anyhow!("there is no focused container")
|
||||||
self.update_focused_workspace(true, false)?;
|
})?
|
||||||
|
.add_window(window);
|
||||||
|
self.update_focused_workspace(true, false)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user