use { crate::{ client::Client, cursor::KnownCursor, fixed::Fixed, ifs::{ wl_seat::{NodeSeatState, WlSeatGlobal}, wl_surface::WlSurface, }, rect::Rect, state::State, tree::{ FindTreeResult, FoundNode, FullscreenNode, Node, NodeId, NodeVisitor, SizedNode, SizedToplevelNode, ToplevelData, WorkspaceNode, }, utils::clonecell::CloneCell, }, jay_config::Direction, std::{ cell::{Cell, RefCell}, ops::Deref, rc::Rc, }, }; tree_id!(DetachedNodeId); pub struct PlaceholderNode { id: DetachedNodeId, state: Rc, seat_state: NodeSeatState, parent: CloneCell>>, workspace: CloneCell>>, title: RefCell, visible: Cell, pos: Cell, client: Option>, toplevel: ToplevelData, active: Cell, destroyed: Cell, } impl PlaceholderNode { pub fn new_for(state: &Rc, node: Rc) -> Self { Self { id: state.node_ids.next(), state: state.clone(), seat_state: Default::default(), parent: Default::default(), workspace: Default::default(), title: RefCell::new(node.title()), visible: Default::default(), pos: Default::default(), client: node.as_node().node_client(), toplevel: Default::default(), active: Default::default(), destroyed: Default::default(), } } pub fn set_title(&self, title: &str) { *self.title.borrow_mut() = title.to_string(); if let Some(parent) = self.parent.get() { parent.node_child_title_changed(self, title); } } pub fn is_destroyed(&self) -> bool { self.destroyed.get() } } impl SizedNode for PlaceholderNode { fn id(&self) -> NodeId { self.id.into() } fn seat_state(&self) -> &NodeSeatState { &self.seat_state } fn destroy_node(&self, detach: bool) { if detach { if let Some(parent) = self.parent.get() { parent.node_remove_child(self); } } self.parent.take(); self.workspace.take(); self.seat_state.destroy_node(self); self.destroyed.set(true); } fn visit(self: &Rc, visitor: &mut dyn NodeVisitor) { visitor.visit_placeholder(self); } fn visit_children(&self, _visitor: &mut dyn NodeVisitor) { // nothing } fn visible(&self) -> bool { self.visible.get() } fn parent(&self) -> Option> { self.parent.get() } fn set_visible(&self, visible: bool) { self.visible.set(visible); } fn get_workspace(&self) -> Option> { self.workspace.get() } fn do_focus(self: &Rc, seat: &Rc, _direction: Direction) { seat.focus_toplevel(self.clone()); } fn close(self: &Rc) { let slf = self.clone(); self.state.run_toplevel.schedule(move || { slf.destroy_node(true); }); } fn absolute_position(&self) -> Rect { self.pos.get() } fn active_changed(&self, active: bool) { self.active.set(active); if let Some(parent) = self.parent.get() { parent.node_child_active_changed(self, active, 1); } } fn find_tree_at(&self, _x: i32, _y: i32, _tree: &mut Vec) -> FindTreeResult { FindTreeResult::AcceptsInput } fn pointer_enter(self: &Rc, seat: &Rc, _x: Fixed, _y: Fixed) { seat.set_known_cursor(KnownCursor::Default); seat.enter_toplevel(self.clone()); } fn change_extents(self: &Rc, rect: &Rect) { self.pos.set(*rect); } fn set_workspace(self: &Rc, ws: &Rc) { self.workspace.set(Some(ws.clone())); } fn set_parent(self: &Rc, parent: Rc) { self.parent.set(Some(parent.clone())); parent.node_child_title_changed(self.deref(), self.title.borrow_mut().deref()); } fn client(&self) -> Option> { self.client.clone() } } impl SizedToplevelNode for PlaceholderNode { fn data(&self) -> &ToplevelData { &self.toplevel } fn accepts_keyboard_focus(&self) -> bool { true } fn default_surface(&self) -> Option> { None } fn set_active(&self, _active: bool) { // nothing } fn activate(&self) { // nothing } fn set_fullscreen(self: &Rc, _fullscreen: bool) { // nothing } fn fullscreen(&self) -> bool { false } }