diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index ea698381..51c75309 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -1783,6 +1783,10 @@ impl Node for WlSurface { self.buffer_abs_pos.get() } + fn node_output(&self) -> Option> { + Some(self.output.get()) + } + fn node_active_changed(&self, active: bool) { if let Some(tl) = self.toplevel.get() { tl.tl_surface_active_changed(active); diff --git a/src/ifs/wl_surface/ext_session_lock_surface_v1.rs b/src/ifs/wl_surface/ext_session_lock_surface_v1.rs index 4c4cba36..64155afd 100644 --- a/src/ifs/wl_surface/ext_session_lock_surface_v1.rs +++ b/src/ifs/wl_surface/ext_session_lock_surface_v1.rs @@ -10,7 +10,7 @@ use { leaks::Tracker, object::{Object, Version}, rect::Rect, - tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor}, + tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor, OutputNode}, utils::numcell::NumCell, wire::{ExtSessionLockSurfaceV1Id, WlSurfaceId, ext_session_lock_surface_v1::*}, }, @@ -123,6 +123,10 @@ impl Node for ExtSessionLockSurfaceV1 { self.surface.node_absolute_position() } + fn node_output(&self) -> Option> { + self.output.node() + } + fn node_find_tree_at( &self, x: i32, diff --git a/src/ifs/wl_surface/tray.rs b/src/ifs/wl_surface/tray.rs index 273a8380..12d5aecb 100644 --- a/src/ifs/wl_surface/tray.rs +++ b/src/ifs/wl_surface/tray.rs @@ -292,6 +292,10 @@ impl Node for T { self.data().surface.node_absolute_position() } + fn node_output(&self) -> Option> { + self.data().output.node() + } + fn node_find_tree_at( &self, x: i32, diff --git a/src/ifs/wl_surface/x_surface/xwindow.rs b/src/ifs/wl_surface/x_surface/xwindow.rs index eb4981cf..9c8178ad 100644 --- a/src/ifs/wl_surface/x_surface/xwindow.rs +++ b/src/ifs/wl_surface/x_surface/xwindow.rs @@ -12,7 +12,7 @@ use { state::State, tree::{ ContainerSplit, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, - NodeVisitor, StackedNode, TileDragDestination, ToplevelData, ToplevelNode, + NodeVisitor, OutputNode, StackedNode, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase, WorkspaceNode, default_tile_drag_destination, }, utils::{clonecell::CloneCell, copyhashmap::CopyHashMap, linkedlist::LinkedNode}, @@ -346,6 +346,10 @@ impl Node for Xwindow { self.data.info.extents.get() } + fn node_output(&self) -> Option> { + self.toplevel_data.output_opt() + } + fn node_do_focus(self: Rc, seat: &Rc, _direction: Direction) { seat.focus_toplevel(self.clone()); } diff --git a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs index 270a8cdf..2fc5685e 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs @@ -314,6 +314,10 @@ impl Node for XdgPopup { self.xdg.absolute_desired_extents.get() } + fn node_output(&self) -> Option> { + self.xdg.workspace.get().map(|w| w.output.get()) + } + fn node_find_tree_at( &self, x: i32, diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index a3601367..cca80ab2 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -523,6 +523,10 @@ impl Node for XdgToplevel { self.xdg.absolute_desired_extents.get() } + fn node_output(&self) -> Option> { + self.toplevel_data.output_opt() + } + fn node_do_focus(self: Rc, seat: &Rc, _direction: Direction) { seat.focus_toplevel(self.clone()); } diff --git a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs index 5a347210..3c759a29 100644 --- a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs +++ b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs @@ -648,6 +648,10 @@ impl Node for ZwlrLayerSurfaceV1 { self.pos.get() } + fn node_output(&self) -> Option> { + self.output.node() + } + fn node_find_tree_at( &self, x: i32, diff --git a/src/tree.rs b/src/tree.rs index 136f1260..d35fb11d 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -122,6 +122,8 @@ pub trait Node: 'static { fn node_visit_children(&self, visitor: &mut dyn NodeVisitor); fn node_visible(&self) -> bool; fn node_absolute_position(&self) -> Rect; + #[expect(dead_code)] + fn node_output(&self) -> Option>; fn node_child_title_changed(self: Rc, child: &dyn Node, title: &str) { let _ = child; diff --git a/src/tree/container.rs b/src/tree/container.rs index 4faee9ce..237020d2 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -18,7 +18,7 @@ use { text::TextTexture, tree::{ ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, - TddType, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase, + OutputNode, TddType, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase, WorkspaceNode, default_tile_drag_bounds, walker::NodeVisitor, }, utils::{ @@ -1761,6 +1761,10 @@ impl Node for ContainerNode { fn node_is_container(&self) -> bool { true } + + fn node_output(&self) -> Option> { + self.toplevel_data.output_opt() + } } impl ContainingNode for ContainerNode { diff --git a/src/tree/display.rs b/src/tree/display.rs index 65bdcbf2..91b89433 100644 --- a/src/tree/display.rs +++ b/src/tree/display.rs @@ -146,6 +146,10 @@ impl Node for DisplayNode { self.extents.get() } + fn node_output(&self) -> Option> { + None + } + fn node_find_tree_at( &self, x: i32, diff --git a/src/tree/float.rs b/src/tree/float.rs index 34a67145..e75335ec 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -697,6 +697,10 @@ impl Node for FloatNode { self.position.get() } + fn node_output(&self) -> Option> { + Some(self.workspace.get().output.get()) + } + fn node_child_title_changed(self: Rc, _child: &dyn Node, title: &str) { self.update_child_title(title); } diff --git a/src/tree/output.rs b/src/tree/output.rs index b2af5cae..ce143a99 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -1343,6 +1343,10 @@ impl Node for OutputNode { self.global.pos.get() } + fn node_output(&self) -> Option> { + self.global.opt.node() + } + fn node_do_focus(self: Rc, seat: &Rc, direction: Direction) { if self.state.lock.locked.get() { if let Some(lock) = self.lock_surface.get() { diff --git a/src/tree/placeholder.rs b/src/tree/placeholder.rs index c80e67c4..f28eee0b 100644 --- a/src/tree/placeholder.rs +++ b/src/tree/placeholder.rs @@ -11,8 +11,8 @@ use { text::TextTexture, tree::{ ContainerSplit, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, - NodeVisitor, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase, - default_tile_drag_destination, + NodeVisitor, OutputNode, TileDragDestination, ToplevelData, ToplevelNode, + ToplevelNodeBase, default_tile_drag_destination, }, utils::{ asyncevent::AsyncEvent, errorfmt::ErrorFmt, on_drop_event::OnDropEvent, @@ -201,6 +201,10 @@ impl Node for PlaceholderNode { fn node_into_toplevel(self: Rc) -> Option> { Some(self) } + + fn node_output(&self) -> Option> { + self.toplevel.output_opt() + } } impl ToplevelNodeBase for PlaceholderNode { diff --git a/src/tree/toplevel.rs b/src/tree/toplevel.rs index dd962817..c8064465 100644 --- a/src/tree/toplevel.rs +++ b/src/tree/toplevel.rs @@ -600,12 +600,16 @@ impl ToplevelData { } pub fn output(&self) -> Rc { - match self.workspace.get() { + match self.output_opt() { None => self.state.dummy_output.get().unwrap(), - Some(ws) => ws.output.get(), + Some(o) => o, } } + pub fn output_opt(&self) -> Option> { + self.workspace.get().map(|ws| ws.output.get()) + } + pub fn desired_pixel_size(&self) -> (i32, i32) { let (dw, dh) = self.desired_extents.get().size(); if let Some(ws) = self.workspace.get() { diff --git a/src/tree/workspace.rs b/src/tree/workspace.rs index 2f70be3a..e694e5ec 100644 --- a/src/tree/workspace.rs +++ b/src/tree/workspace.rs @@ -298,6 +298,10 @@ impl Node for WorkspaceNode { self.position.get() } + fn node_output(&self) -> Option> { + Some(self.output.get()) + } + fn node_do_focus(self: Rc, seat: &Rc, direction: Direction) { if let Some(fs) = self.fullscreen.get() { fs.node_do_focus(seat, direction);