diff --git a/src/tree/container.rs b/src/tree/container.rs index e4a6652d..d9a8c80e 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -20,7 +20,8 @@ use { ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FloatNode, FoundNode, Node, NodeId, NodeLayerLink, NodeLocation, OutputNode, TddType, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase, ToplevelType, WorkspaceNode, - default_tile_drag_bounds, toplevel_set_floating, walker::NodeVisitor, + default_tile_drag_bounds, toplevel_set_floating, toplevel_set_workspace, + walker::NodeVisitor, }, utils::{ asyncevent::AsyncEvent, @@ -1052,16 +1053,42 @@ impl ContainerNode { // pub fn move_child(self: Rc, child: Rc, direction: Direction) { + let move_to_neighboring_output = |child: Rc| { + let Some(output) = self.find_neighboring_output(direction) else { + return; + }; + let ws = output.ensure_workspace(); + let mut foci = SmallVec::new(); + let move_foci = !ws.container_visible(); + if move_foci { + collect_kb_foci2(child.clone(), &mut foci); + } + if let Some(c) = ws.container.get() { + self.clone().cnode_remove_child2(&*child, true); + c.insert_child(child, direction); + } else { + toplevel_set_workspace(&self.state, child, &ws); + } + if move_foci { + for seat in foci { + ws.clone().node_do_focus(&seat, Direction::Unspecified); + } + } + }; + // CASE 1: This is the only child of the container. Replace the container by the child. if self.num_children.get() == 1 { if let Some(parent) = self.toplevel_data.parent.get() && !self.toplevel_data.is_fullscreen.get() - && parent.cnode_accepts_child(&*child) { - parent.cnode_replace_child(self.deref(), child.clone()); - self.toplevel_data.parent.take(); - self.child_nodes.borrow_mut().clear(); - self.tl_destroy(); + if parent.cnode_accepts_child(&*child) { + parent.cnode_replace_child(self.deref(), child.clone()); + self.toplevel_data.parent.take(); + self.child_nodes.borrow_mut().clear(); + self.tl_destroy(); + } else { + move_to_neighboring_output(child); + } } return; } @@ -1112,7 +1139,10 @@ impl ContainerNode { } let parent = match parent_opt { Some(p) => p, - _ => return, + _ => { + move_to_neighboring_output(child); + return; + } }; self.cnode_remove_child2(&*child, true); match prev {