Skip to content

Commit ea29009

Browse files
committed
fix: Drop window on mouse position rather than window center
1 parent 2d12e1d commit ea29009

File tree

1 file changed

+33
-11
lines changed

1 file changed

+33
-11
lines changed

packages/wm/src/events/handle_window_moved_or_resized_end.rs

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use crate::{
1212
window::{resize_window, update_window_state},
1313
},
1414
models::{
15-
DirectionContainer, NonTilingWindow, SplitContainer, TilingContainer,
16-
WindowContainer,
15+
Container, DirectionContainer, NonTilingWindow, SplitContainer,
16+
TilingContainer, WindowContainer,
1717
},
1818
traits::{
1919
CommonGetters, PositionGetters, TilingDirectionGetters, WindowGetters,
@@ -98,19 +98,23 @@ fn drop_as_tiling_window(
9898
);
9999

100100
let mouse_pos = Platform::mouse_position()?;
101-
let workspace = moved_window.workspace().context("No workspace.")?;
101+
let mouse_workspace = state
102+
.monitor_at_point(&mouse_pos)
103+
.and_then(|monitor| monitor.displayed_workspace())
104+
.or_else(|| moved_window.workspace())
105+
.context("Couldn't find workspace for window drop")?;
102106

103107
// Get the workspace, split containers, and other windows under the
104108
// dragged window.
105109
let containers_at_pos = state
106-
.containers_at_point(&workspace.clone().into(), &mouse_pos)
110+
.containers_at_point(&mouse_workspace.clone().into(), &mouse_pos)
107111
.into_iter()
108112
.filter(|container| container.id() != moved_window.id());
109113

110114
// Get the deepest direction container under the dragged window.
111115
let target_parent: DirectionContainer = containers_at_pos
112116
.filter_map(|container| container.as_direction_container().ok())
113-
.fold(workspace.into(), |acc, container| {
117+
.fold(mouse_workspace.into(), |acc, container| {
114118
if container.ancestors().count() > acc.ancestors().count() {
115119
container
116120
} else {
@@ -121,14 +125,12 @@ fn drop_as_tiling_window(
121125
// If the target parent has no children (i.e. an empty workspace), then
122126
// add the window directly.
123127
if target_parent.tiling_children().count() == 0 {
124-
update_window_state(
125-
moved_window.clone().into(),
126-
WindowState::Tiling,
128+
return dropped_on_empty_workspace(
129+
moved_window,
130+
&target_parent.as_container(),
127131
state,
128132
config,
129-
)?;
130-
131-
return Ok(());
133+
);
132134
}
133135

134136
let nearest_container = target_parent
@@ -211,6 +213,26 @@ fn drop_as_tiling_window(
211213
Ok(())
212214
}
213215

216+
fn dropped_on_empty_workspace(
217+
moved_window: &NonTilingWindow,
218+
target_parent: &Container,
219+
state: &mut WmState,
220+
config: &UserConfig,
221+
) -> anyhow::Result<()> {
222+
moved_window.set_insertion_target(None);
223+
224+
let win_container = moved_window
225+
.as_window_container()
226+
.expect("NonTilingWindow is not a window container");
227+
let container = win_container.as_container();
228+
229+
move_container_within_tree(&container, target_parent, 0, state)?;
230+
231+
moved_window.set_insertion_target(None);
232+
update_window_state(win_container, WindowState::Tiling, state, config)
233+
.map(|_| ())
234+
}
235+
214236
/// Represents where the window was dropped over another.
215237
#[derive(Debug, Clone, PartialEq)]
216238
enum DropPosition {

0 commit comments

Comments
 (0)