From 3e6640f0caccd3dea9598adf83d9d70877c4909c Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Thu, 24 Apr 2025 12:36:18 +0200 Subject: [PATCH] tree: ensure that floats remain accessible after workspace move --- src/tree/float.rs | 46 ++++++++++++++++++++++++++++++++++++++++++- src/tree/workspace.rs | 9 +++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/tree/float.rs b/src/tree/float.rs index adab1bba..aff53f5d 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -15,7 +15,8 @@ use { text::TextTexture, tree::{ ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, - StackedNode, TileDragDestination, ToplevelNode, WorkspaceNode, walker::NodeVisitor, + OutputNode, StackedNode, TileDragDestination, ToplevelNode, WorkspaceNode, + walker::NodeVisitor, }, utils::{ asyncevent::AsyncEvent, clonecell::CloneCell, double_click_state::DoubleClickState, @@ -411,6 +412,49 @@ impl FloatNode { self.stacked_set_visible(ws.float_visible()); } + pub fn adjust_position_after_ws_move(self: &Rc, output: &Rc) { + if output.is_dummy { + return; + } + let pos = self.position.get(); + let opos = output.global.pos.get(); + if pos.intersects(&opos) { + return; + } + let bw = self.state.theme.sizes.border_width.get(); + let th = self.state.theme.sizes.title_height.get(); + let mut x1 = pos.x1(); + let mut x2 = pos.x2(); + let mut y1 = pos.y1(); + let mut y2 = pos.y2(); + const DELTA: i32 = 100; + let delta = bw + DELTA; + macro_rules! adjust { + ($z1:ident, $z2:ident) => { + if $z1 > opos.$z2() - delta { + $z1 = (opos.$z2() - delta).max(opos.$z1()); + $z2 += $z1 - pos.$z1(); + } else if $z2 < opos.$z1() + delta { + $z2 = (opos.$z1() + delta).min(opos.$z2()); + $z1 += $z2 - pos.$z2(); + } + }; + } + adjust!(x1, x2); + adjust!(y1, y2); + if y1 + bw + th <= opos.y1() { + y1 = opos.y1(); + y2 += y1 - pos.y1(); + } + let new_pos = Rect::new(x1, y1, x2, y2).unwrap(); + self.position.set(new_pos); + if self.visible.get() { + self.state.damage(pos); + self.state.damage(new_pos); + } + self.schedule_layout(); + } + fn update_child_title(self: &Rc, title: &str) { let mut t = self.title.borrow_mut(); if t.deref() != title { diff --git a/src/tree/workspace.rs b/src/tree/workspace.rs index 63d5b0d4..a6822dd7 100644 --- a/src/tree/workspace.rs +++ b/src/tree/workspace.rs @@ -20,8 +20,8 @@ use { state::State, text::TextTexture, tree::{ - ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, - NodeVisitorBase, OutputNode, PlaceholderNode, StackedNode, ToplevelNode, + ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FloatNode, FoundNode, Node, + NodeId, NodeVisitorBase, OutputNode, PlaceholderNode, StackedNode, ToplevelNode, container::ContainerNode, walker::NodeVisitor, }, utils::{ @@ -127,6 +127,11 @@ impl WorkspaceNode { node.node_visit_children(self); } + fn visit_float(&mut self, node: &Rc) { + node.adjust_position_after_ws_move(self.0); + node.node_visit_children(self); + } + fn visit_xwindow(&mut self, node: &Rc) { node.tl_workspace_output_changed(); node.node_visit_children(self);