fix(wm): avoid focused ws rule enforcement deadlock

This commit adds mutex lock scoping in
WindowManager::enforce_workspace_rule to avoid a deadlock when
should_update_focused_workspace evaluates to true.

fix #1212
This commit is contained in:
LGUG2Z
2025-01-04 09:39:04 -08:00
parent 4b30cecba9
commit 44716fdc98
+6 -1
View File
@@ -720,6 +720,9 @@ impl WindowManager {
.ok_or_else(|| anyhow!("there is no monitor with that index"))? .ok_or_else(|| anyhow!("there is no monitor with that index"))?
.focused_workspace_idx(); .focused_workspace_idx();
// scope mutex locks to avoid deadlock if should_update_focused_workspace evaluates to true
// at the end of this function
{
let workspace_matching_rules = WORKSPACE_MATCHING_RULES.lock(); let workspace_matching_rules = WORKSPACE_MATCHING_RULES.lock();
let regex_identifiers = REGEX_IDENTIFIERS.lock(); let regex_identifiers = REGEX_IDENTIFIERS.lock();
// Go through all the monitors and workspaces // Go through all the monitors and workspaces
@@ -727,7 +730,8 @@ impl WindowManager {
for (j, workspace) in monitor.workspaces().iter().enumerate() { for (j, workspace) in monitor.workspaces().iter().enumerate() {
// And all the visible windows (at the top of a container) // And all the visible windows (at the top of a container)
for window in workspace.visible_windows().into_iter().flatten() { for window in workspace.visible_windows().into_iter().flatten() {
let mut already_moved_window_handles = self.already_moved_window_handles.lock(); let mut already_moved_window_handles =
self.already_moved_window_handles.lock();
let exe_name = window.exe()?; let exe_name = window.exe()?;
let title = window.title()?; let title = window.title()?;
let class = window.class()?; let class = window.class()?;
@@ -795,6 +799,7 @@ impl WindowManager {
} }
} }
} }
}
// Only retain operations where the target is not the current workspace // Only retain operations where the target is not the current workspace
to_move.retain(|op| !op.is_target(focused_monitor_idx, focused_workspace_idx)); to_move.retain(|op| !op.is_target(focused_monitor_idx, focused_workspace_idx));