use crate::cursor::KnownCursor; use crate::ifs::wl_output::WlOutputGlobal; use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal}; use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1; use crate::rect::Rect; use crate::render::Renderer; use crate::tree::walker::NodeVisitor; use crate::tree::{DisplayNode, FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode}; use crate::utils::clonecell::CloneCell; use crate::utils::linkedlist::LinkedList; use std::cell::{Cell, RefCell}; use std::fmt::{Debug, Formatter}; use std::ops::Deref; use std::rc::Rc; tree_id!(OutputNodeId); pub struct OutputNode { pub display: Rc, pub id: OutputNodeId, pub position: Cell, pub global: Rc, pub workspaces: RefCell>>, pub workspace: CloneCell>>, pub seat_state: NodeSeatState, pub layers: [LinkedList>; 4], } impl Debug for OutputNode { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("OutputNode").finish_non_exhaustive() } } impl Node for OutputNode { fn id(&self) -> NodeId { self.id.into() } fn seat_state(&self) -> &NodeSeatState { &self.seat_state } fn destroy_node(&self, detach: bool) { if detach { self.display.clone().remove_child(self); } let mut workspaces = self.workspaces.borrow_mut(); for workspace in workspaces.drain(..) { workspace.destroy_node(false); } self.seat_state.destroy_node(self); } fn visit(self: Rc, visitor: &mut dyn NodeVisitor) { visitor.visit_output(&self); } fn visit_children(&self, visitor: &mut dyn NodeVisitor) { let ws = self.workspaces.borrow_mut(); for ws in ws.deref() { visitor.visit_workspace(ws); } for layers in &self.layers { for surface in layers.iter() { visitor.visit_layer_surface(surface.deref()); } } } fn absolute_position(&self) -> Rect { self.position.get() } fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec) -> FindTreeResult { if let Some(ws) = self.workspace.get() { tree.push(FoundNode { node: ws.clone(), x, y, }); ws.find_tree_at(x, y, tree); } FindTreeResult::AcceptsInput } fn remove_child(self: Rc, _child: &dyn Node) { self.workspace.set(None); } fn pointer_focus(&self, seat: &Rc) { seat.set_known_cursor(KnownCursor::Default); } fn render(&self, renderer: &mut Renderer, x: i32, y: i32) { renderer.render_output(self, x, y); } fn is_output(&self) -> bool { true } fn into_output(self: Rc) -> Option> { Some(self) } fn change_extents(self: Rc, rect: &Rect) { self.position.set(*rect); if let Some(c) = self.workspace.get() { c.change_extents(rect); } for layer in &self.layers { for surface in layer.iter() { surface.deref().clone().change_extents(rect); } } } }