Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
fix(tag): resolve window rendering deadlock when switching tags
src/server/window_manager.rs | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 511859b..97de8fa 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -1087,6 +1087,24 @@ impl WindowManager {
}
}
}
+ // If the focused window is no longer visible on the active tags, refocus
+ let seats_list = &mut (*self.server).input_manager.seats as *mut ffi::wl_list as *mut WlList;
+ let mut curr_seat = (*seats_list).next;
+ while curr_seat != seats_list {
+ let next_seat = (*curr_seat).next;
+ let seat = crate::container_of!(curr_seat, crate::seat::Seat, link);
+ let mut focused_visible = false;
+ if let crate::seat::Focus::Window(w) = (*seat).focused {
+ if !w.is_null() && !(*w).closed && !(*w).minimized && ((*w).tags & self.active_tags) != 0 {
+ focused_visible = true;
+ }
+ }
+ if !focused_visible {
+ self.focus_next_visible_window(seat);
+ }
+ curr_seat = next_seat;
+ }
+
self.update_status();
self.rendering_scheduled.dirty = true;
}
@@ -1484,9 +1502,6 @@ impl WindowManager {
_ => 1,
};
self.active_tags = 1 << (tag - 1);
- if let Some(seat) = self.first_seat() {
- self.focus_next_visible_window(seat);
- }
self.dirty_windowing();
}
Action::Toggle1 | Action::Toggle2 | Action::Toggle3 | Action::Toggle4 => {
@@ -1501,17 +1516,6 @@ impl WindowManager {
if self.active_tags == 0 {
self.active_tags = 1;
}
- if let Some(seat) = self.first_seat() {
- let mut current_visible = false;
- if let crate::seat::Focus::Window(fw) = (*seat).focused {
- if !fw.is_null() && !(*fw).closed && ((*fw).tags & self.active_tags) != 0 {
- current_visible = true;
- }
- }
- if !current_visible {
- self.focus_next_visible_window(seat);
- }
- }
self.dirty_windowing();
}
Action::SetTag1 | Action::SetTag2 | Action::SetTag3 | Action::SetTag4 => {