From a97e92cceaadd6604bc5432f120ec3a6c9f68cde Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 16 Jul 2025 21:21:00 +0200 Subject: [PATCH] toplevel: store containing float --- src/tree/container.rs | 18 ++++++++++++++---- src/tree/containing.rs | 5 ++++- src/tree/float.rs | 4 ++++ src/tree/toplevel.rs | 32 +++++++++++++++++++++++++++++--- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/tree/container.rs b/src/tree/container.rs index 41b8bfc9..dc774b31 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -17,10 +17,10 @@ use { state::State, text::TextTexture, tree::{ - ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, - OutputNode, TddType, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase, - ToplevelType, WorkspaceNode, default_tile_drag_bounds, toplevel_set_floating, - walker::NodeVisitor, + ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FloatNode, FoundNode, Node, + NodeId, OutputNode, TddType, TileDragDestination, ToplevelData, ToplevelNode, + ToplevelNodeBase, ToplevelType, WorkspaceNode, default_tile_drag_bounds, + toplevel_set_floating, walker::NodeVisitor, }, utils::{ asyncevent::AsyncEvent, @@ -2063,6 +2063,10 @@ impl ContainingNode for ContainerNode { fn cnode_set_pinned(self: Rc, pinned: bool) { self.tl_set_pinned(false, pinned); } + + fn cnode_get_float(self: Rc) -> Option> { + self.tl_data().float.get() + } } impl ToplevelNodeBase for ContainerNode { @@ -2176,6 +2180,12 @@ impl ToplevelNodeBase for ContainerNode { }; child.node.tl_tile_drag_bounds(split, start) / 2 } + + fn tl_push_float(&self, float: Option<&Rc>) { + for child in self.children.iter() { + child.node.tl_set_float(float); + } + } } fn direction_to_split(dir: Direction) -> (ContainerSplit, bool) { diff --git a/src/tree/containing.rs b/src/tree/containing.rs index 009ac694..8cbdee0d 100644 --- a/src/tree/containing.rs +++ b/src/tree/containing.rs @@ -1,5 +1,5 @@ use { - crate::tree::{Node, ToplevelNode, WorkspaceNode}, + crate::tree::{FloatNode, Node, ToplevelNode, WorkspaceNode}, std::rc::Rc, }; @@ -37,4 +37,7 @@ pub trait ContainingNode: Node { fn cnode_set_pinned(self: Rc, pinned: bool) { let _ = pinned; } + fn cnode_get_float(self: Rc) -> Option> { + None + } } diff --git a/src/tree/float.rs b/src/tree/float.rs index 79c12ca3..8c62edb6 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -958,6 +958,10 @@ impl ContainingNode for FloatNode { } self.toggle_pinned(); } + + fn cnode_get_float(self: Rc) -> Option> { + Some(self) + } } impl StackedNode for FloatNode { diff --git a/src/tree/toplevel.rs b/src/tree/toplevel.rs index e79679ed..58801503 100644 --- a/src/tree/toplevel.rs +++ b/src/tree/toplevel.rs @@ -26,8 +26,8 @@ use { rect::Rect, state::State, tree::{ - ContainerNode, ContainerSplit, ContainingNode, Direction, Node, NodeId, OutputNode, - PlaceholderNode, WorkspaceNode, + ContainerNode, ContainerSplit, ContainingNode, Direction, FloatNode, Node, NodeId, + OutputNode, PlaceholderNode, WorkspaceNode, }, utils::{ array_to_tuple::ArrayToTuple, @@ -35,6 +35,7 @@ use { copyhashmap::CopyHashMap, hash_map_ext::HashMapExt, numcell::NumCell, + rc_eq::rc_eq, threshold_counter::ThresholdCounter, toplevel_identifier::{ToplevelIdentifier, toplevel_identifier}, }, @@ -67,6 +68,7 @@ pub trait ToplevelNode: ToplevelNodeBase { fn tl_destroy(&self); fn tl_pinned(&self) -> bool; fn tl_set_pinned(&self, self_pinned: bool, pinned: bool); + fn tl_set_float(&self, float: Option<&Rc>); } impl ToplevelNode for T { @@ -118,7 +120,19 @@ impl ToplevelNode for T { data.property_changed(TL_CHANGED_FLOATING); } data.parent_is_float.set(is_floating); - self.tl_set_workspace(&parent.cnode_workspace()); + self.tl_set_workspace(&parent.clone().cnode_workspace()); + { + let float = parent.cnode_get_float(); + let prev = data.float.set(float.clone()); + let same = match (&prev, &float) { + (None, None) => true, + (Some(prev), Some(float)) => rc_eq(prev, float), + _ => false, + }; + if !same { + self.tl_push_float(float.as_ref()); + } + } } fn tl_extents_changed(&self) { @@ -207,6 +221,11 @@ impl ToplevelNode for T { }; parent.cnode_set_pinned(pinned); } + + fn tl_set_float(&self, float: Option<&Rc>) { + self.tl_data().float.set(float.cloned()); + self.tl_push_float(float); + } } pub trait ToplevelNodeBase: Node { @@ -266,6 +285,10 @@ pub trait ToplevelNodeBase: Node { .is_some() .then_some(self.node_absolute_position()) } + + fn tl_push_float(&self, float: Option<&Rc>) { + let _ = float; + } } pub struct FullscreenedData { @@ -317,6 +340,7 @@ pub struct ToplevelData { pub active_surfaces: ThresholdCounter, pub visible: Cell, pub parent_is_float: Cell, + pub float: CloneCell>>, pub float_width: Cell, pub float_height: Cell, pub pinned: Cell, @@ -370,6 +394,7 @@ impl ToplevelData { active_surfaces: Default::default(), visible: Cell::new(false), parent_is_float: Default::default(), + float: Default::default(), float_width: Default::default(), float_height: Default::default(), pinned: Cell::new(false), @@ -491,6 +516,7 @@ impl ToplevelData { if let Some(parent) = self.parent.take() { parent.cnode_remove_child(node); } + self.float.take(); self.workspace.take(); self.seat_state.destroy_node(node); }