Skip to content

Commit 6488df2

Browse files
committed
dwindle insertion success
1 parent 8177fcf commit 6488df2

File tree

8 files changed

+54
-176
lines changed

8 files changed

+54
-176
lines changed

packages/wm/src/commands/container/detach_container.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ use crate::{
1111
/// If the container is a tiling container, the siblings will be resized to
1212
/// fill the freed up space. Will flatten empty parent split containers.
1313
#[allow(clippy::needless_pass_by_value)]
14-
pub fn detach_container(child_to_remove: Container) -> anyhow::Result<Container> {
14+
pub fn detach_container(child_to_remove: Container, preserve_containers: bool) -> anyhow::Result<Container> {
1515
// Flatten the parent split container if it'll be empty after removing
1616
// the child.
1717
if let Some(split_parent) = child_to_remove
1818
.parent()
1919
.and_then(|parent| parent.as_split().cloned())
2020
{
21-
if split_parent.child_count() == 1 {
21+
if split_parent.child_count() == 1 && !preserve_containers {
2222
flatten_split_container(split_parent)?;
2323
}
2424
}

packages/wm/src/commands/container/move_container_within_tree.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub fn move_container_within_tree(
9494
let is_subtree_focused =
9595
original_focus_index < target_parent_ancestor.focus_index();
9696

97-
detach_container(container_to_move.clone())?;
97+
detach_container(container_to_move.clone(), false)?;
9898
attach_container(
9999
&container_to_move.clone(),
100100
&target_parent.clone(),
@@ -152,7 +152,7 @@ fn move_to_lowest_common_ancestor(
152152
.map(|ancestor| ancestor.focus_index())
153153
.context("Failed to get focus index of container's ancestor.")?;
154154

155-
detach_container(container_to_move.clone())?;
155+
detach_container(container_to_move.clone(), false)?;
156156

157157
attach_container(
158158
&container_to_move.clone(),

packages/wm/src/commands/container/replace_container.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
/// Replaces a container at the specified index.
1111
///
1212
/// The replaced container will be detached from the tree.
13-
///
13+
///
1414
/// TODO return container and call 2 replace_continaers in swap_container
1515
pub fn replace_container(
1616
replacement_container: &Container,
@@ -38,7 +38,7 @@ pub fn replace_container(
3838
// container to flatten. Currently, that scenario shouldn't be possible.
3939
// We also can't attach first before detaching, because detaching
4040
// removes child based on ID and both containers might have the same ID.
41-
detach_container(container_to_replace)?;
41+
detach_container(container_to_replace, false)?;
4242

4343
attach_container(
4444
replacement_container,

packages/wm/src/commands/layouts/add_dwindle_window.rs

+44-166
Original file line numberDiff line numberDiff line change
@@ -23,195 +23,73 @@ pub fn add_dwindle_window(
2323
config: &UserConfig,
2424
state: &mut WmState,
2525
) -> anyhow::Result<WindowContainer> {
26-
// Create a TilingWindow from NativeWindow.
27-
let border_delta = RectDelta::new(
28-
LengthValue::from_px(0),
29-
LengthValue::from_px(0),
30-
LengthValue::from_px(0),
31-
LengthValue::from_px(0),
32-
);
33-
let gaps_config = config.value.gaps.clone();
3426
let new_window = TilingWindow::new(
3527
None,
3628
native_window,
3729
None,
38-
border_delta,
30+
RectDelta::new(
31+
LengthValue::from_px(0),
32+
LengthValue::from_px(0),
33+
LengthValue::from_px(0),
34+
LengthValue::from_px(0),
35+
),
3936
Rect {
4037
left: 0,
4138
top: 0,
4239
right: 0,
4340
bottom: 0,
4441
},
4542
false,
46-
gaps_config,
43+
config.value.gaps.clone(),
4744
Vec::new(),
4845
None,
4946
);
5047

51-
// Setup the initial dwindle layout.
52-
if target_workspace.child_count() == 0 {
53-
attach_container(
54-
&new_window.clone().into(),
55-
&target_workspace.clone().into(),
56-
None,
57-
)?;
58-
return new_window.as_window_container();
59-
} else if target_workspace.child_count() == 1 {
60-
let new_split_container = SplitContainer::new(
61-
TilingDirection::Vertical,
62-
config.value.gaps.clone(),
63-
);
64-
attach_container(
65-
&new_window.clone().into(),
66-
&new_split_container.clone().into(),
67-
None,
68-
)?;
69-
attach_container(
70-
&new_split_container.clone().into(),
71-
&target_workspace.clone().into(),
72-
None,
73-
)?;
74-
return new_window.as_window_container();
75-
}
76-
77-
// At this point, we have at least 2 windows.
78-
// This logic inserts the new window after the focused window, shifting
79-
// all deeper windows in the dwindle tree downwards to make room.
80-
let target_parent = target_container.parent().context("No parent.")?;
81-
let child_count = target_parent.child_count();
82-
let focused_index = target_container.index();
48+
// Get starting point - use target's parent if it exists
49+
let start_container = if target_workspace.child_count() <= 1 {
50+
target_workspace.clone().into()
51+
} else {
52+
target_container.parent().context("No parent.")?
53+
};
8354

84-
// Re-organize the containers
85-
let mut workspace_children = target_parent.borrow_children_mut();
86-
87-
// The 2nd container is always a SplitContainer, 1st is just a window.
88-
let mut split_container =
89-
workspace_children.back().context("No children.")?;
90-
let mut split_children = split_container.borrow_children_mut();
91-
let window_to_shift =
92-
detach_container(*split_children.front().unwrap()).ok();
93-
attach_container(
94-
&new_window.clone().into(),
95-
&split_container.clone().into(),
96-
None,
97-
)?;
98-
// let mut window_to_shift = split_children.pop_front();
99-
// split_children.insert(0, target_container.clone());
100-
//
101-
while let Some(window) = window_to_shift {
102-
// Get the back container using a temporary reference
103-
let back = {
104-
let current_children = &split_children;
105-
current_children.back().context("No children.")?
106-
};
55+
let mut current = start_container;
56+
let mut window = new_window.clone().into();
10757

108-
// Clone the container since we need to use it after the borrow ends
109-
let next_container = back.clone();
58+
loop {
59+
if current.child_count() <= 1 {
60+
if current.child_count() == 0 {
61+
attach_container(&window, &current, Some(0))?;
62+
break;
63+
}
11064

111-
// Get the children of the next container
112-
let mut next_children = next_container.children();
65+
let direction = if current.as_workspace().is_some() {
66+
TilingDirection::Vertical
67+
} else {
68+
current
69+
.as_direction_container()?
70+
.tiling_direction()
71+
.inverse()
72+
};
11373

114-
if next_children.iter().count() == 1 {
115-
// Create the new split container
116-
let new_split_direction = next_container
117-
.as_direction_container()?
118-
.tiling_direction()
119-
.inverse();
120-
121-
let new_split_container = SplitContainer::new(
122-
new_split_direction,
123-
config.value.gaps.clone(),
124-
);
125-
126-
// Add the window to the new container and attach
127-
new_split_container.borrow_children_mut().push_back(window);
128-
attach_container(
129-
&new_split_container.clone().into(),
130-
&next_container.clone().into(),
131-
None,
132-
)?;
74+
let new_split =
75+
SplitContainer::new(direction, config.value.gaps.clone());
76+
attach_container(&window, &new_split.clone().into(), Some(0))?;
77+
attach_container(&new_split.clone().into(), &current, Some(1))?;
13378
break;
13479
}
13580

136-
// Shift windows
137-
let next_window = next_children.pop_front();
138-
next_children.insert(0, window);
81+
// Get existing split and its window
82+
let next_split = current.borrow_children().get(1).unwrap().clone();
83+
let next_window = next_split.borrow_children().get(0).unwrap().clone();
13984

140-
// Prepare for next iteration
141-
split_container = &next_container;
142-
split_children = split_container.children();
143-
window_to_shift = next_window;
85+
// Swap windows
86+
let detached = detach_container(next_window, true)?;
87+
attach_container(&window, &next_split.clone().into(), Some(0))?;
88+
89+
// Move to next container
90+
current = next_split;
91+
window = detached;
14492
}
93+
14594
new_window.as_window_container()
14695
}
147-
// ) -> anyhow::Result<(Container, usize)> {
148-
// let child_count = target_workspace.child_count();
149-
//
150-
// if child_count == 0 {
151-
// Ok((target_workspace.clone().into(), 0))
152-
// } else if child_count == 1 {
153-
// // Create a vertical split container for the stack
154-
// let new_container = SplitContainer::new(
155-
// TilingDirection::Vertical,
156-
// config.value.gaps.clone(),
157-
// );
158-
// {
159-
// let master_containers = target_workspace.borrow_children_mut();
160-
// let only_container = master_containers.front().unwrap();
161-
// state
162-
// .pending_sync
163-
// .queue_container_to_redraw(only_container.clone());
164-
// }
165-
// attach_container(
166-
// &new_container.clone().into(),
167-
// &target_workspace.clone().into(),
168-
// None,
169-
// )?;
170-
// Ok((new_container.clone().into(), 0))
171-
// } else if child_count == 2 {
172-
// let children = target_workspace.borrow_children_mut();
173-
// let back_container = children.back().context("No children.")?;
174-
// let back_clone = back_container.clone();
175-
// drop(children);
176-
//
177-
// // Now work with the cloned container
178-
// let mut current_container = back_clone;
179-
//
180-
// while current_container.children().iter().count() > 1 {
181-
// // Create a new borrow scope
182-
// let next_container = {
183-
// let children = current_container.borrow_children_mut();
184-
// let back = children.back().context("No children.")?;
185-
// back.clone() // Clone it so we can drop the borrow
186-
// };
187-
// current_container = next_container;
188-
// }
189-
//
190-
// let current_child_count =
191-
// current_container.children().iter().count(); if current_child_count
192-
// == 0 { Ok((target_workspace.clone().into(), 0))
193-
// } else if current_child_count == 1 {
194-
// let new_split_direction = current_container
195-
// .as_direction_container()?
196-
// .tiling_direction()
197-
// .inverse();
198-
// let split_container = SplitContainer::new(
199-
// new_split_direction,
200-
// config.value.gaps.clone(),
201-
// );
202-
// state
203-
// .pending_sync
204-
// .queue_container_to_redraw(current_container.clone());
205-
// attach_container(
206-
// &split_container.clone().into(),
207-
// &current_container.clone().into(),
208-
// None,
209-
// )?;
210-
// Ok((split_container.clone().into(), 0))
211-
// } else {
212-
// Err(anyhow::anyhow!("Unexpected child count"))
213-
// }
214-
// } else {
215-
// Err(anyhow::anyhow!("Unexpected child count"))
216-
// }
217-
// }

packages/wm/src/commands/monitor/remove_monitor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub fn remove_monitor(
4949
});
5050
}
5151

52-
detach_container(monitor.clone().into())?;
52+
detach_container(monitor.clone().into(), false)?;
5353

5454
state.emit_event(WmEvent::MonitorRemoved {
5555
removed_id: monitor.id(),

packages/wm/src/commands/window/ignore_window.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn ignore_window(
1919
let ancestors = window.ancestors().take(3).collect::<Vec<_>>();
2020

2121
state.ignored_windows.push(window.native().clone());
22-
detach_container(window.clone().into())?;
22+
detach_container(window.clone().into(), false)?;
2323

2424
// After detaching the container, flatten any redundant split containers.
2525
// For example, in the layout V[1 H[2]] where container 1 is detached to

packages/wm/src/commands/window/unmanage_window.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn unmanage_window(
2222
// Get container to switch focus to after the window has been removed.
2323
let focus_target = state.focus_target_after_removal(&window.clone());
2424

25-
detach_container(window.clone().into())?;
25+
detach_container(window.clone().into(), false)?;
2626

2727
// After detaching the container, flatten any redundant split containers.
2828
// For example, in the layout V[1 H[2]] where container 1 is detached to

packages/wm/src/commands/workspace/deactivate_workspace.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn deactivate_workspace(
1515
) -> anyhow::Result<()> {
1616
info!("Deactivating workspace: {workspace}");
1717

18-
detach_container(workspace.clone().into())?;
18+
detach_container(workspace.clone().into(), false)?;
1919

2020
state.emit_event(WmEvent::WorkspaceDeactivated {
2121
deactivated_id: workspace.id(),

0 commit comments

Comments
 (0)