@@ -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 ) ]
216238enum DropPosition {
0 commit comments