Skip to content

Commit

Permalink
fix(borders): update border loc when moving
Browse files Browse the repository at this point in the history
Currently, komorebi checks if a move is happening by checking if the
left mouse is pressed and updates the borders when there is a move while
the left mouse button is pressed (BTW this is why when moving with the
keyboard using the system move it only updates after pressing enter).

However, for some reason AltSnap somehow steals this left button
information and komorebi thinks the button is not pressed.

This PR makes it so it checks for the state of the pending_move_op and
keeps updating the borders while this is_some().

This fixes both that issue with AltSnap and the issue with system move,
as well as any other situations that might allow moving a window with
anything else that doesn't use a left mouse button press.
  • Loading branch information
alex-ds13 authored and LGUG2Z committed Oct 31, 2024
1 parent 4198f6f commit 7f7b8c7
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 10 deletions.
24 changes: 21 additions & 3 deletions komorebi/src/border_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> 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()
Expand Down Expand Up @@ -413,7 +414,19 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> 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) => {
Expand Down Expand Up @@ -496,7 +509,12 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> 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) => {
Expand Down
9 changes: 5 additions & 4 deletions komorebi/src/process_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion komorebi/src/static_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())),
};

Expand Down
4 changes: 2 additions & 2 deletions komorebi/src/window_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub struct WindowManager {
pub hotwatch: Hotwatch,
pub virtual_desktop_id: Option<Vec<u8>>,
pub has_pending_raise_op: bool,
pub pending_move_op: Option<(usize, usize, usize)>,
pub pending_move_op: Arc<Option<(usize, usize, usize)>>,
pub already_moved_window_handles: Arc<Mutex<HashSet<isize>>>,
}

Expand Down Expand Up @@ -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())),
})
}
Expand Down

0 comments on commit 7f7b8c7

Please sign in to comment.