Skip to content

Commit

Permalink
fix(wm): avoid obvious border manager thread crash
Browse files Browse the repository at this point in the history
This commit adds an early exit from the border manager's event
processing loop whenever a window which still exists in the state but
has been destroyed is encountered. Instead of returning an error, the
'containers loop will now skip ahead to the next iteration.

This commit also makes an adjustment to the frequency with which the
reaper sends border manager notifications - a single notification is now
sent at the end of each iteration if necessary, rather than one
notification per workspace.
  • Loading branch information
LGUG2Z committed Jan 4, 2025
1 parent 631d336 commit 3803a02
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
14 changes: 12 additions & 2 deletions komorebi/src/border_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
borders.remove(id);
}

for (idx, c) in ws.containers().iter().enumerate() {
'containers: for (idx, c) in ws.containers().iter().enumerate() {
// Get the border entry for this container from the map or create one
let mut new_border = false;
let border = match borders.entry(c.id().clone()) {
Expand Down Expand Up @@ -471,7 +471,17 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
let reference_hwnd =
c.focused_window().copied().unwrap_or_default().hwnd;

let rect = WindowsApi::window_rect(reference_hwnd)?;
// avoid getting into a thread restart loop if we try to look up
// rect info for a window that has been destroyed by the time
// we get here
let rect = match WindowsApi::window_rect(reference_hwnd) {
Ok(rect) => rect,
Err(_) => {
let _ = border.destroy();
borders.remove(c.id());
continue 'containers;
}
};

let should_invalidate = match last_focus_state {
None => true,
Expand Down
8 changes: 7 additions & 1 deletion komorebi/src/reaper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ pub fn find_orphans(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result<()> {
let mut wm = arc.lock();
let offset = wm.work_area_offset;

let mut update_borders = false;

for (i, monitor) in wm.monitors_mut().iter_mut().enumerate() {
let work_area = *monitor.work_area_size();
let window_based_work_area_offset = (
Expand All @@ -51,7 +53,7 @@ pub fn find_orphans(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result<()> {
let reaped_orphans = workspace.reap_orphans()?;
if reaped_orphans.0 > 0 || reaped_orphans.1 > 0 {
workspace.update(&work_area, offset, window_based_work_area_offset)?;
border_manager::send_notification(None);
update_borders = true;
tracing::info!(
"reaped {} orphan window(s) and {} orphaned container(s) on monitor: {}, workspace: {}",
reaped_orphans.0,
Expand All @@ -62,5 +64,9 @@ pub fn find_orphans(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result<()> {
}
}
}

if update_borders {
border_manager::send_notification(None);
}
}
}

0 comments on commit 3803a02

Please sign in to comment.