diff --git a/komorebi/src/border_manager/mod.rs b/komorebi/src/border_manager/mod.rs index 2825d086d..71f760573 100644 --- a/komorebi/src/border_manager/mod.rs +++ b/komorebi/src/border_manager/mod.rs @@ -157,7 +157,8 @@ pub fn handle_notifications(wm: Arc>) -> color_eyre::Result let focused_workspace_idx = state.monitors.elements()[focused_monitor_idx].focused_workspace_idx(); let monitors = state.monitors.clone(); - let pending_move_op = state.pending_move_op; + let weak_pending_move_op = Arc::downgrade(&state.pending_move_op); + let pending_move_op = *state.pending_move_op; let floating_window_hwnds = state.monitors.elements()[focused_monitor_idx].workspaces() [focused_workspace_idx] .floating_windows() @@ -413,7 +414,19 @@ pub fn handle_notifications(wm: Arc>) -> color_eyre::Result c.focused_window().copied().unwrap_or_default().hwnd, )?; - while WindowsApi::lbutton_is_pressed() { + // We create a new variable to track the actual pending move op so + // that the other variable `pending_move_op` still holds the + // pending move info so that when the move ends we know on the next + // notification that the previous pending move and pending move are + // different (because a move just finished) and still handle the + // notification. If otherwise we updated the pending_move_op here + // directly then the next pending move after finish would be the + // same because we had already updated it here. + let mut sync_pending_move_op = + weak_pending_move_op.upgrade().and_then(|p| *p); + while sync_pending_move_op.is_some() { + sync_pending_move_op = + weak_pending_move_op.upgrade().and_then(|p| *p); let border = match borders.entry(c.id().clone()) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { @@ -496,7 +509,12 @@ pub fn handle_notifications(wm: Arc>) -> color_eyre::Result if pending_move_op.is_some() && hwnd == notification_hwnd { let mut rect = WindowsApi::window_rect(hwnd)?; - while WindowsApi::lbutton_is_pressed() { + // Check comment above for containers move + let mut sync_pending_move_op = + weak_pending_move_op.upgrade().and_then(|p| *p); + while sync_pending_move_op.is_some() { + sync_pending_move_op = + weak_pending_move_op.upgrade().and_then(|p| *p); let border = match borders.entry(hwnd.to_string()) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index e286bb74d..ea98a1542 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -436,16 +436,17 @@ impl WindowManager { WindowsApi::bring_window_to_top(window.hwnd)?; - self.pending_move_op = - Option::from((monitor_idx, workspace_idx, container_idx)); + let pending_move_op = Arc::make_mut(&mut self.pending_move_op); + *pending_move_op = Option::from((monitor_idx, workspace_idx, container_idx)); } } WindowManagerEvent::MoveResizeEnd(_, window) => { // We need this because if the event ends on a different monitor, // that monitor will already have been focused and updated in the state - let pending = self.pending_move_op; + let pending = *self.pending_move_op; // Always consume the pending move op whenever this event is handled - self.pending_move_op = None; + let pending_move_op = Arc::make_mut(&mut self.pending_move_op); + *pending_move_op = None; let target_monitor_idx = self .monitor_idx_from_current_pos() diff --git a/komorebi/src/static_config.rs b/komorebi/src/static_config.rs index 9857491da..86c28e55b 100644 --- a/komorebi/src/static_config.rs +++ b/komorebi/src/static_config.rs @@ -1049,7 +1049,7 @@ impl StaticConfig { mouse_follows_focus: value.mouse_follows_focus.unwrap_or(true), hotwatch: Hotwatch::new()?, has_pending_raise_op: false, - pending_move_op: None, + pending_move_op: Arc::new(None), already_moved_window_handles: Arc::new(Mutex::new(HashSet::new())), }; diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 1080e5fa8..c5d28a3d7 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -102,7 +102,7 @@ pub struct WindowManager { pub hotwatch: Hotwatch, pub virtual_desktop_id: Option>, pub has_pending_raise_op: bool, - pub pending_move_op: Option<(usize, usize, usize)>, + pub pending_move_op: Arc>, pub already_moved_window_handles: Arc>>, } @@ -339,7 +339,7 @@ impl WindowManager { mouse_follows_focus: true, hotwatch: Hotwatch::new()?, has_pending_raise_op: false, - pending_move_op: None, + pending_move_op: Arc::new(None), already_moved_window_handles: Arc::new(Mutex::new(HashSet::new())), }) }