mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-23 09:08:36 +02:00
fix(wm): move floats in direction across monitors
This commit fixes an issue where when trying to move floating windows or windows on a floating workspace across boundaries to another monitor using the `move_container_in_direction` it wouldn't move the floating windows physically, although it moved them internally on komorebi, resulting in weird and wrong behavior. This commit creates a new method on `Monitor` to `add_container_with_direction` which takes a move direction and then uses the same logic that was previously on the `move_container_in_direction` function. It changes the `move_container_to_monitor` function to take an optional move direction which if it is some will have this function call the new method `add_container_with_direction` instead of just `add_container`. Lastly the `move_container_in_direction` function now when it realizes the move will be across monitors simply calls the `move_container_to_monitor` with the direction that was initially given to it. These changes require that all callers of `move_container_to_monitor` add an direction option, instead of passing `None` on all of them, a new helper function was created, named `direction_from_monitor_idx` which calculates the direction a move will have from the currently focused monitor and the target monitor return `None` if they are the same or returning `Some(direction)` if not. This way now all commands that call a move across monitor will use the logic to check from the direction if it should add the container on front or end.
This commit is contained in:
@@ -139,6 +139,86 @@ impl Monitor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Adds a container to this `Monitor` using the move direction to calculate if the container
|
||||
/// should be added in front of all containers, in the back or in place of the focused
|
||||
/// container, moving the rest along. The move direction should be from the origin monitor
|
||||
/// towards the target monitor.
|
||||
pub fn add_container_with_direction(
|
||||
&mut self,
|
||||
container: Container,
|
||||
workspace_idx: Option<usize>,
|
||||
direction: OperationDirection,
|
||||
) -> Result<()> {
|
||||
let workspace = if let Some(idx) = workspace_idx {
|
||||
self.workspaces_mut()
|
||||
.get_mut(idx)
|
||||
.ok_or_else(|| anyhow!("there is no workspace at index {}", idx))?
|
||||
} else {
|
||||
self.focused_workspace_mut()
|
||||
.ok_or_else(|| anyhow!("there is no workspace"))?
|
||||
};
|
||||
|
||||
match direction {
|
||||
OperationDirection::Left => {
|
||||
// insert the container into the workspace on the monitor at the back (or rightmost position)
|
||||
// if we are moving across a boundary to the left (back = right side of the target)
|
||||
match workspace.layout() {
|
||||
Layout::Default(layout) => match layout {
|
||||
DefaultLayout::RightMainVerticalStack => {
|
||||
workspace.add_container_to_front(container);
|
||||
}
|
||||
DefaultLayout::UltrawideVerticalStack => {
|
||||
if workspace.containers().len() == 1 {
|
||||
workspace.insert_container_at_idx(0, container);
|
||||
} else {
|
||||
workspace.add_container_to_back(container);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
workspace.add_container_to_back(container);
|
||||
}
|
||||
},
|
||||
Layout::Custom(_) => {
|
||||
workspace.add_container_to_back(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
OperationDirection::Right => {
|
||||
// insert the container into the workspace on the monitor at the front (or leftmost position)
|
||||
// if we are moving across a boundary to the right (front = left side of the target)
|
||||
match workspace.layout() {
|
||||
Layout::Default(layout) => {
|
||||
let target_index = layout.leftmost_index(workspace.containers().len());
|
||||
|
||||
match layout {
|
||||
DefaultLayout::RightMainVerticalStack
|
||||
| DefaultLayout::UltrawideVerticalStack => {
|
||||
if workspace.containers().len() == 1 {
|
||||
workspace.add_container_to_back(container);
|
||||
} else {
|
||||
workspace.insert_container_at_idx(target_index, container);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
workspace.insert_container_at_idx(target_index, container);
|
||||
}
|
||||
}
|
||||
}
|
||||
Layout::Custom(_) => {
|
||||
workspace.add_container_to_front(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
OperationDirection::Up | OperationDirection::Down => {
|
||||
// insert the container into the workspace on the monitor at the position
|
||||
// where the currently focused container on that workspace is
|
||||
workspace.insert_container_at_idx(workspace.focused_container_idx(), container);
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn remove_workspace_by_idx(&mut self, idx: usize) -> Option<Workspace> {
|
||||
if idx < self.workspaces().len() {
|
||||
return self.workspaces_mut().remove(idx);
|
||||
|
||||
Reference in New Issue
Block a user