From fe804b82769487973ab446ebccf94b3d2e72d3d9 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 21 Feb 2024 19:38:31 +0100 Subject: [PATCH] tree: clean up object attachment --- src/ifs/wl_surface/x_surface/xwindow.rs | 2 +- .../wl_surface/xdg_surface/xdg_toplevel.rs | 2 +- src/state.rs | 1 - src/tree/container.rs | 136 ++++++++++-------- src/tree/containing.rs | 3 +- src/tree/float.rs | 49 ++++--- src/tree/toplevel.rs | 41 ++---- src/tree/workspace.rs | 21 +-- 8 files changed, 140 insertions(+), 115 deletions(-) diff --git a/src/ifs/wl_surface/x_surface/xwindow.rs b/src/ifs/wl_surface/x_surface/xwindow.rs index 1d220953..eb476ef1 100644 --- a/src/ifs/wl_surface/x_surface/xwindow.rs +++ b/src/ifs/wl_surface/x_surface/xwindow.rs @@ -379,7 +379,7 @@ impl ToplevelNodeBase for Xwindow { Some(self.x.surface.clone()) } - fn tl_set_workspace_ext(self: Rc, ws: &Rc) { + fn tl_set_workspace_ext(&self, ws: &Rc) { self.x.surface.set_output(&ws.output.get()); } diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index 1eaf205b..8061b2a8 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -477,7 +477,7 @@ impl ToplevelNodeBase for XdgToplevel { Some(self.xdg.surface.clone()) } - fn tl_set_workspace_ext(self: Rc, ws: &Rc) { + fn tl_set_workspace_ext(&self, ws: &Rc) { self.xdg.set_workspace(ws); } diff --git a/src/state.rs b/src/state.rs index 8a0faf72..a570ea37 100644 --- a/src/state.rs +++ b/src/state.rs @@ -520,7 +520,6 @@ impl State { mut height: i32, workspace: &Rc, ) { - node.clone().tl_set_workspace(workspace); width += 2 * self.theme.sizes.border_width.get(); height += 2 * self.theme.sizes.border_width.get() + self.theme.sizes.title_height.get() + 1; let output = workspace.output.get(); diff --git a/src/tree/container.rs b/src/tree/container.rs index 35c0310c..52e3079f 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -172,7 +172,6 @@ impl ContainerNode { child: Rc, split: ContainerSplit, ) -> Rc { - child.clone().tl_set_workspace(workspace); let children = LinkedList::new(); let child_node = children.add_last(ContainerChild { node: child.clone(), @@ -217,7 +216,7 @@ impl ContainerNode { attention_requests: Default::default(), }); child.tl_set_parent(slf.clone()); - slf.apply_child_flags(&child_node_ref); + slf.pull_child_properties(&child_node_ref); slf } @@ -301,9 +300,8 @@ impl ContainerNode { links.insert(new.node_id(), link); r }; - self.apply_child_flags(&new_ref); - new.clone().tl_set_workspace(&self.workspace.get()); new.tl_set_parent(self.clone()); + self.pull_child_properties(&new_ref); new.tl_set_visible(self.toplevel_data.visible.get()); let num_children = self.num_children.fetch_add(1) + 1; self.update_content_size(); @@ -605,7 +603,7 @@ impl ContainerNode { } } - fn update_title(self: &Rc) { + fn update_title(&self) { let mut title = self.toplevel_data.title.borrow_mut(); title.clear(); let split = match (self.mono_child.get().is_some(), self.split.get()) { @@ -951,16 +949,70 @@ impl ContainerNode { } } - fn apply_child_flags(&self, child: &ContainerChild) { - let data = child.node.tl_data(); - let attention_requested = data.wants_attention.get(); - child.attention_requested.set(attention_requested); - if attention_requested { - self.mod_attention_requests(true); + fn update_child_title(self: &Rc, child: &ContainerChild, title: &str) { + { + let mut ct = child.title.borrow_mut(); + if ct.deref() == title { + return; + } + ct.clear(); + ct.push_str(title); + } + self.update_title(); + // log::info!("node_child_title_changed"); + self.schedule_compute_render_data(); + } + + fn update_child_active( + self: &Rc, + node: &NodeRef, + active: bool, + depth: u32, + ) { + if depth == 1 { + node.active.set(active); + } + if active { + node.focus_history + .set(Some(self.focus_history.add_last(node.clone()))); + } + // log::info!("node_child_active_changed"); + self.schedule_compute_render_data(); + if let Some(parent) = self.toplevel_data.parent.get() { + parent.node_child_active_changed(self.deref(), active, depth + 1); } } - fn discard_child_flags(&self, child: &ContainerChild) { + fn update_child_size(&self, node: &NodeRef, width: i32, height: i32) { + let rect = Rect::new(0, 0, width, height).unwrap(); + node.content.set(rect); + node.position_content(); + if let Some(mono) = self.mono_child.get() { + if mono.node.node_id() == node.node.node_id() { + let body = self.mono_body.get(); + self.mono_content.set(rect.at_point(body.x1(), body.y1())); + } + } + } + + fn pull_child_properties(self: &Rc, child: &NodeRef) { + let data = child.node.tl_data(); + { + let attention_requested = data.wants_attention.get(); + child.attention_requested.set(attention_requested); + if attention_requested { + self.mod_attention_requests(true); + } + } + self.update_child_title(child, &data.title.borrow()); + self.update_child_active(child, data.active(), 1); + { + let pos = data.pos.get(); + self.update_child_size(child, pos.width(), pos.height()); + } + } + + fn discard_child_properties(&self, child: &ContainerChild) { if child.attention_requested.get() { self.mod_attention_requests(false); } @@ -1042,21 +1094,9 @@ impl Node for ContainerNode { } fn node_child_title_changed(self: Rc, child: &dyn Node, title: &str) { - let child = match self.child_nodes.borrow().get(&child.node_id()) { - Some(cn) => cn.to_ref(), - _ => return, - }; - { - let mut ct = child.title.borrow_mut(); - if ct.deref() == title { - return; - } - ct.clear(); - ct.push_str(title); + if let Some(child) = self.child_nodes.borrow().get(&child.node_id()) { + self.update_child_title(child, title); } - self.update_title(); - // log::info!("node_child_title_changed"); - self.schedule_compute_render_data(); } fn node_do_focus(self: Rc, seat: &Rc, direction: Direction) { @@ -1115,34 +1155,13 @@ impl Node for ContainerNode { fn node_child_size_changed(&self, child: &dyn Node, width: i32, height: i32) { let cn = self.child_nodes.borrow(); if let Some(node) = cn.get(&child.node_id()) { - let rect = Rect::new(0, 0, width, height).unwrap(); - node.content.set(rect); - node.position_content(); - if let Some(mono) = self.mono_child.get() { - if mono.node.node_id() == node.node.node_id() { - let body = self.mono_body.get(); - self.mono_content.set(rect.at_point(body.x1(), body.y1())); - } - } + self.update_child_size(node, width, height); } } fn node_child_active_changed(self: Rc, child: &dyn Node, active: bool, depth: u32) { - let node = match self.child_nodes.borrow().get(&child.node_id()) { - Some(l) => l.to_ref(), - None => return, - }; - if depth == 1 { - node.active.set(active); - } - if active { - node.focus_history - .set(Some(self.focus_history.add_last(node.clone()))); - } - // log::info!("node_child_active_changed"); - self.schedule_compute_render_data(); - if let Some(parent) = self.toplevel_data.parent.get() { - parent.node_child_active_changed(self.deref(), active, depth + 1); + if let Some(l) = self.child_nodes.borrow().get(&child.node_id()) { + self.update_child_active(l, active, depth); } } @@ -1314,7 +1333,7 @@ impl ContainingNode for ContainerNode { None => (false, false), Some(mc) => (true, mc.node.node_id() == old.node_id()), }; - self.discard_child_flags(&node); + self.discard_child_properties(&node); let link = node.append(ContainerChild { node: new.clone(), active: Cell::new(false), @@ -1327,11 +1346,10 @@ impl ContainingNode for ContainerNode { focus_history: Cell::new(None), attention_requested: Cell::new(false), }); - self.apply_child_flags(&link); if let Some(fh) = node.focus_history.take() { link.focus_history.set(Some(fh.append(link.to_ref()))); } - new.tl_set_visible(node.node.node_visible()); + let visible = node.node.node_visible(); drop(node); let mut body = None; if was_mc { @@ -1340,9 +1358,11 @@ impl ContainingNode for ContainerNode { } else if !have_mc { body = Some(link.body.get()); }; + let link_ref = link.to_ref(); self.child_nodes.borrow_mut().insert(new.node_id(), link); new.tl_set_parent(self.clone()); - new.clone().tl_set_workspace(&self.workspace.get()); + self.pull_child_properties(&link_ref); + new.tl_set_visible(visible); if let Some(body) = body { let body = body.move_(self.abs_x1.get(), self.abs_y1.get()); new.clone().tl_change_extents(&body); @@ -1355,7 +1375,7 @@ impl ContainingNode for ContainerNode { None => return, }; node.focus_history.set(None); - self.discard_child_flags(&node); + self.discard_child_properties(&node); if let Some(mono) = self.mono_child.get() { if mono.node.node_id() == child.node_id() { let mut new = self.focus_history.last().map(|n| n.deref().clone()); @@ -1419,6 +1439,10 @@ impl ContainingNode for ContainerNode { self.mod_attention_requests(set); self.schedule_compute_render_data(); } + + fn cnode_workspace(self: Rc) -> Rc { + self.workspace.get() + } } impl ToplevelNodeBase for ContainerNode { @@ -1434,7 +1458,7 @@ impl ToplevelNodeBase for ContainerNode { .map(|tl| tl.tl_into_node()) } - fn tl_set_workspace_ext(self: Rc, ws: &Rc) { + fn tl_set_workspace_ext(&self, ws: &Rc) { for child in self.children.iter() { child.node.clone().tl_set_workspace(ws); } diff --git a/src/tree/containing.rs b/src/tree/containing.rs index 5426f631..94ac7f4c 100644 --- a/src/tree/containing.rs +++ b/src/tree/containing.rs @@ -1,5 +1,5 @@ use { - crate::tree::{Node, ToplevelNode}, + crate::tree::{Node, ToplevelNode, WorkspaceNode}, std::rc::Rc, }; @@ -15,4 +15,5 @@ pub trait ContainingNode: Node { fn cnode_remove_child2(self: Rc, child: &dyn Node, preserve_focus: bool); fn cnode_accepts_child(&self, node: &dyn Node) -> bool; fn cnode_child_attention_request_changed(self: Rc, child: &dyn Node, set: bool); + fn cnode_workspace(self: Rc) -> Rc; } diff --git a/src/tree/float.rs b/src/tree/float.rs index 457ac09c..b0423d36 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -115,14 +115,13 @@ impl FloatNode { seats: Default::default(), attention_requested: Cell::new(false), }); - floater.apply_child_flags(); + floater.pull_child_properties(); floater .display_link .set(Some(state.root.stacked.add_last(floater.clone()))); floater .workspace_link .set(Some(ws.stacked.add_last(floater.clone()))); - child.clone().tl_set_workspace(ws); child.tl_set_parent(floater.clone()); child.tl_set_visible(floater.visible.get()); floater.schedule_layout(); @@ -349,7 +348,22 @@ impl FloatNode { self.stacked_set_visible(ws.stacked_visible()); } - fn apply_child_flags(&self) { + fn update_child_title(self: &Rc, title: &str) { + let mut t = self.title.borrow_mut(); + if t.deref() != title { + t.clear(); + t.push_str(title); + self.schedule_render_titles(); + } + } + + fn update_child_active(self: &Rc, active: bool) { + if self.active.replace(active) != active { + self.schedule_render_titles(); + } + } + + fn pull_child_properties(self: &Rc) { let child = match self.child.get() { None => return, Some(c) => c, @@ -360,11 +374,13 @@ impl FloatNode { if activation_requested { self.workspace .get() - .cnode_child_attention_request_changed(self, true); + .cnode_child_attention_request_changed(&**self, true); } + self.update_child_title(&data.title.borrow()); + self.update_child_active(data.active()); } - fn discard_child_flags(&self) { + fn discard_child_properties(&self) { if self.attention_requested.get() { self.workspace .get() @@ -407,12 +423,7 @@ impl Node for FloatNode { } fn node_child_title_changed(self: Rc, _child: &dyn Node, title: &str) { - let mut t = self.title.borrow_mut(); - if t.deref() != title { - t.clear(); - t.push_str(title); - self.schedule_render_titles(); - } + self.update_child_title(title); } fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec) -> FindTreeResult { @@ -441,9 +452,7 @@ impl Node for FloatNode { } fn node_child_active_changed(self: Rc, _child: &dyn Node, active: bool, _depth: u32) { - if self.active.replace(active) != active { - self.schedule_render_titles(); - } + self.update_child_active(active); } fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32, _bounds: Option<&Rect>) { @@ -546,16 +555,16 @@ impl ContainingNode for FloatNode { containing_node_impl!(); fn cnode_replace_child(self: Rc, _old: &dyn Node, new: Rc) { - self.discard_child_flags(); + self.discard_child_properties(); self.child.set(Some(new.clone())); - self.apply_child_flags(); new.tl_set_parent(self.clone()); - new.clone().tl_set_workspace(&self.workspace.get()); + self.pull_child_properties(); + new.tl_set_visible(self.visible.get()); self.schedule_layout(); } fn cnode_remove_child2(self: Rc, _child: &dyn Node, _preserve_focus: bool) { - self.discard_child_flags(); + self.discard_child_properties(); self.child.set(None); self.display_link.set(None); self.workspace_link.set(None); @@ -572,6 +581,10 @@ impl ContainingNode for FloatNode { .cnode_child_attention_request_changed(&*self, set); } } + + fn cnode_workspace(self: Rc) -> Rc { + self.workspace.get() + } } impl StackedNode for FloatNode { diff --git a/src/tree/toplevel.rs b/src/tree/toplevel.rs index d24869cf..e1201b8b 100644 --- a/src/tree/toplevel.rs +++ b/src/tree/toplevel.rs @@ -36,9 +36,8 @@ pub trait ToplevelNode: ToplevelNodeBase { fn tl_set_fullscreen(self: Rc, fullscreen: bool); fn tl_title_changed(&self); fn tl_set_parent(&self, parent: Rc); - fn tl_active_changed(&self); fn tl_extents_changed(&self); - fn tl_set_workspace(self: Rc, ws: &Rc); + fn tl_set_workspace(&self, ws: &Rc); fn tl_change_extents(self: Rc, rect: &Rect); fn tl_set_visible(&self, visible: bool); fn tl_destroy(&self); @@ -103,36 +102,19 @@ impl ToplevelNode for T { let data = self.tl_data(); data.parent.set(Some(parent.clone())); data.is_floating.set(parent.node_is_float()); - self.tl_extents_changed(); - self.tl_title_changed(); - self.tl_active_changed(); - } - - fn tl_active_changed(&self) { - let data = self.tl_data(); - let parent = match data.parent.get() { - Some(p) => p, - _ => return, - }; - let node = self.tl_as_node(); - if data.active.get() || data.active_surfaces.active() { - parent.clone().node_child_active_changed(node, true, 1); - } + self.tl_set_workspace(&parent.cnode_workspace()); } fn tl_extents_changed(&self) { let data = self.tl_data(); - let parent = match data.parent.get() { - Some(p) => p, - _ => return, - }; - let node = self.tl_as_node(); - let pos = data.pos.get(); - parent.node_child_size_changed(node, pos.width(), pos.height()); - data.state.tree_changed(); + if let Some(parent) = data.parent.get() { + let pos = data.pos.get(); + parent.node_child_size_changed(self, pos.width(), pos.height()); + data.state.tree_changed(); + } } - fn tl_set_workspace(self: Rc, ws: &Rc) { + fn tl_set_workspace(&self, ws: &Rc) { let data = self.tl_data(); data.workspace.set(Some(ws.clone())); self.tl_set_workspace_ext(ws); @@ -184,7 +166,7 @@ pub trait ToplevelNodeBase: Node { .or_else(|| self.tl_default_focus_child()) } - fn tl_set_workspace_ext(self: Rc, ws: &Rc) { + fn tl_set_workspace_ext(&self, ws: &Rc) { let _ = ws; } @@ -259,6 +241,10 @@ impl ToplevelData { } } + pub fn active(&self) -> bool { + self.active_surfaces.active() || self.active.get() + } + pub fn float_size(&self, ws: &WorkspaceNode) -> (i32, i32) { let output = ws.output.get().global.pos.get(); let mut width = self.float_width.get(); @@ -401,7 +387,6 @@ impl ToplevelData { self.is_fullscreen.set(true); node.tl_set_parent(ws.clone()); ws.set_fullscreen_node(&node); - node.clone().tl_set_workspace(ws); node.clone() .tl_change_extents(&ws.output.get().global.pos.get()); for seat in kb_foci { diff --git a/src/tree/workspace.rs b/src/tree/workspace.rs index 17f9d29f..6956ce8c 100644 --- a/src/tree/workspace.rs +++ b/src/tree/workspace.rs @@ -77,12 +77,11 @@ impl WorkspaceNode { pub fn set_container(self: &Rc, container: &Rc) { if let Some(prev) = self.container.get() { - self.discard_child_flags(&*prev); + self.discard_child_properties(&*prev); } - self.apply_child_flags(&**container); + self.pull_child_properties(&**container); let pos = self.position.get(); container.clone().tl_change_extents(&pos); - container.clone().tl_set_workspace(self); container.tl_set_parent(self.clone()); container.tl_set_visible(self.stacked_visible()); self.container.set(Some(container.clone())); @@ -136,9 +135,9 @@ impl WorkspaceNode { let mut plane_was_visible = visible; if let Some(prev) = self.fullscreen.set(Some(node.clone())) { plane_was_visible = false; - self.discard_child_flags(&*prev); + self.discard_child_properties(&*prev); } - self.apply_child_flags(&**node); + self.pull_child_properties(&**node); node.tl_set_visible(visible); if plane_was_visible { self.plane_set_visible(false); @@ -152,7 +151,7 @@ impl WorkspaceNode { pub fn remove_fullscreen_node(&self) { if let Some(node) = self.fullscreen.take() { - self.discard_child_flags(&*node); + self.discard_child_properties(&*node); if self.visible.get() { self.plane_set_visible(true); } @@ -164,13 +163,13 @@ impl WorkspaceNode { } } - fn apply_child_flags(&self, child: &dyn ToplevelNode) { + fn pull_child_properties(&self, child: &dyn ToplevelNode) { if child.tl_data().wants_attention.get() { self.mod_attention_requested(true); } } - fn discard_child_flags(&self, child: &dyn ToplevelNode) { + fn discard_child_properties(&self, child: &dyn ToplevelNode) { if child.tl_data().wants_attention.get() { self.mod_attention_requested(false); } @@ -279,7 +278,7 @@ impl ContainingNode for WorkspaceNode { fn cnode_remove_child2(self: Rc, child: &dyn Node, _preserve_focus: bool) { if let Some(container) = self.container.get() { if container.node_id() == child.node_id() { - self.discard_child_flags(&*container); + self.discard_child_properties(&*container); self.container.set(None); return; } @@ -300,4 +299,8 @@ impl ContainingNode for WorkspaceNode { fn cnode_child_attention_request_changed(self: Rc, _node: &dyn Node, set: bool) { self.mod_attention_requested(set); } + + fn cnode_workspace(self: Rc) -> Rc { + self + } }