use { crate::{ backend::KeyState, client::{Client, ClientId}, fixed::Fixed, ifs::{ wl_seat::{wl_pointer::PendingScroll, Dnd, NodeSeatState, WlSeatGlobal}, wl_surface::WlSurface, }, rect::Rect, render::Renderer, utils::numcell::NumCell, xkbcommon::ModifierState, }, jay_config::Direction, std::{ fmt::{Debug, Display}, rc::Rc, }, }; pub use { container::*, display::*, float::*, fullscreen::*, output::*, placeholder::*, toplevel::*, walker::*, workspace::*, }; mod container; mod display; mod float; mod fullscreen; mod output; mod placeholder; mod toplevel; mod walker; mod workspace; pub struct NodeIds { next: NumCell, } impl Default for NodeIds { fn default() -> Self { Self { next: NumCell::new(1), } } } impl NodeIds { pub fn next>(&self) -> T { NodeId(self.next.fetch_add(1)).into() } } #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub struct NodeId(pub u32); impl NodeId { #[allow(dead_code)] pub fn raw(&self) -> u32 { self.0 } } impl Display for NodeId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Display::fmt(&self.0, f) } } #[derive(Copy, Clone, Eq, PartialEq)] pub enum FindTreeResult { AcceptsInput, Other, } impl FindTreeResult { pub fn accepts_input(self) -> bool { self == Self::AcceptsInput } } pub trait SizedNode: Sized + 'static { fn id(&self) -> NodeId; fn seat_state(&self) -> &NodeSeatState; fn destroy_node(&self, detach: bool); fn visit(self: &Rc, visitor: &mut dyn NodeVisitor); fn visit_children(&self, visitor: &mut dyn NodeVisitor); fn visible(&self) -> bool; fn parent(&self) -> Option>; fn last_active_child(self: &Rc) -> Rc { self.clone() } fn set_visible(&self, visible: bool) { let _ = visible; } fn get_workspace(&self) -> Option> { None } fn child_title_changed(self: &Rc, child: &dyn Node, title: &str) { let _ = child; let _ = title; } fn get_parent_mono(&self) -> Option { None } fn get_parent_split(&self) -> Option { None } fn set_parent_mono(&self, mono: bool) { let _ = mono; } fn set_parent_split(&self, split: ContainerSplit) { let _ = split; } fn get_mono(&self) -> Option { None } fn get_split(&self) -> Option { None } fn set_mono(self: &Rc, child: Option<&dyn Node>) { let _ = child; } fn set_split(self: &Rc, split: ContainerSplit) { let _ = split; } fn create_split(self: &Rc, split: ContainerSplit) { let _ = split; } fn focus_self(self: &Rc, seat: &Rc) { let _ = seat; } fn do_focus(self: &Rc, seat: &Rc, direction: Direction) { let _ = seat; let _ = direction; } fn close(self: &Rc) { // nothing } fn move_focus(self: &Rc, seat: &Rc, direction: Direction) { let _ = seat; let _ = direction; } fn move_self(self: &Rc, direction: Direction) { let _ = direction; } fn move_focus_from_child( self: &Rc, seat: &Rc, child: &dyn Node, direction: Direction, ) { let _ = seat; let _ = direction; let _ = child; } fn move_child(self: &Rc, child: Rc, direction: Direction) { let _ = direction; let _ = child; } fn absolute_position(&self) -> Rect { Rect::new_empty(0, 0) } fn absolute_position_constrains_input(&self) -> bool { true } fn active_changed(&self, active: bool) { let _ = active; } fn key(&self, seat: &WlSeatGlobal, key: u32, state: u32) { let _ = seat; let _ = key; let _ = state; } fn mods(&self, seat: &WlSeatGlobal, mods: ModifierState) { let _ = seat; let _ = mods; } fn button(self: &Rc, seat: &Rc, button: u32, state: KeyState, serial: u32) { let _ = seat; let _ = button; let _ = state; let _ = serial; } fn axis_event(self: &Rc, seat: &WlSeatGlobal, event: &PendingScroll) { let _ = seat; let _ = event; } fn focus(self: &Rc, seat: &Rc) { let _ = seat; } fn focus_parent(&self, seat: &Rc) { let _ = seat; } fn toggle_floating(self: &Rc, seat: &Rc) { let _ = seat; } fn unfocus(&self, seat: &WlSeatGlobal) { let _ = seat; } fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec) -> FindTreeResult { let _ = x; let _ = y; let _ = tree; FindTreeResult::Other } fn replace_child(self: &Rc, old: &dyn Node, new: Rc) { let _ = old; let _ = new; } fn remove_child(self: &Rc, child: &dyn Node) { self.remove_child2(child, false); } fn remove_child2(self: &Rc, child: &dyn Node, preserve_focus: bool) { let _ = child; let _ = preserve_focus; } fn child_size_changed(&self, child: &dyn Node, width: i32, height: i32) { let _ = (child, width, height); } fn child_active_changed(self: &Rc, child: &dyn Node, active: bool, depth: u32) { let _ = (child, active, depth); } fn leave(&self, seat: &WlSeatGlobal) { let _ = seat; } fn pointer_enter(self: &Rc, seat: &Rc, x: Fixed, y: Fixed) { let _ = seat; let _ = x; let _ = y; } fn pointer_unfocus(&self, seat: &Rc) { let _ = seat; } fn pointer_focus(&self, seat: &Rc) { let _ = seat; } fn pointer_motion(self: &Rc, seat: &Rc, x: Fixed, y: Fixed) { let _ = seat; let _ = x; let _ = y; } fn render(&self, renderer: &mut Renderer, x: i32, y: i32) { let _ = renderer; let _ = x; let _ = y; } fn into_float(self: &Rc) -> Option> { None } fn into_container(self: &Rc) -> Option> { None } fn into_workspace(self: &Rc) -> Option> { None } fn is_container(&self) -> bool { false } fn is_output(&self) -> bool { false } fn into_output(self: &Rc) -> Option> { None } fn accepts_child(&self, node: &dyn Node) -> bool { let _ = node; false } fn insert_child(self: &Rc, node: Rc, direction: Direction) { let _ = node; let _ = direction; } fn is_float(&self) -> bool { false } fn is_workspace(&self) -> bool { false } fn change_extents(self: &Rc, rect: &Rect) { let _ = rect; } fn set_workspace(self: &Rc, ws: &Rc) { let _ = ws; } fn set_parent(self: &Rc, parent: Rc) { let _ = parent; } fn client(&self) -> Option> { None } fn client_id(&self) -> Option { self.client().map(|c| c.id) } fn into_surface(self: &Rc) -> Option> { None } fn dnd_drop(&self, dnd: &Dnd) { let _ = dnd; } fn dnd_leave(&self, dnd: &Dnd) { let _ = dnd; } fn dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32) { let _ = dnd; let _ = x; let _ = y; let _ = serial; } fn dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) { let _ = dnd; let _ = x; let _ = y; } fn is_xwayland_surface(&self) -> bool { false } fn fullscreen(&self) -> bool { false } fn set_fullscreen(self: &Rc, fullscreen: bool) { let _ = fullscreen; } } pub trait Node { fn node_id(&self) -> NodeId; fn node_seat_state(&self) -> &NodeSeatState; fn node_destroy(&self, detach: bool); fn node_visit(self: Rc, visitor: &mut dyn NodeVisitor); fn node_visit_children(&self, visitor: &mut dyn NodeVisitor); fn node_visible(&self) -> bool; fn node_parent(&self) -> Option>; fn node_last_active_child(self: Rc) -> Rc; fn node_set_visible(&self, visible: bool); fn node_get_workspace(&self) -> Option>; fn node_child_title_changed(self: Rc, child: &dyn Node, title: &str); fn node_get_parent_mono(&self) -> Option; fn node_get_parent_split(&self) -> Option; fn node_set_parent_mono(&self, mono: bool); fn node_set_parent_split(&self, split: ContainerSplit); fn node_get_mono(&self) -> Option; fn node_get_split(&self) -> Option; fn node_set_mono(self: Rc, child: Option<&dyn Node>); fn node_set_split(self: Rc, split: ContainerSplit); fn node_create_split(self: Rc, split: ContainerSplit); fn node_focus_self(self: Rc, seat: &Rc); fn node_do_focus(self: Rc, seat: &Rc, direction: Direction); fn node_close(self: Rc); fn node_move_focus(self: Rc, seat: &Rc, direction: Direction); fn node_move_self(self: Rc, direction: Direction); fn node_move_focus_from_child( self: Rc, seat: &Rc, child: &dyn Node, direction: Direction, ); fn node_move_child(self: Rc, child: Rc, direction: Direction); fn node_absolute_position(&self) -> Rect; fn node_absolute_position_constrains_input(&self) -> bool; fn node_active_changed(&self, active: bool); fn node_key(&self, seat: &WlSeatGlobal, key: u32, state: u32); fn node_mods(&self, seat: &WlSeatGlobal, mods: ModifierState); fn node_button( self: Rc, seat: &Rc, button: u32, state: KeyState, serial: u32, ); fn node_axis_event(self: Rc, seat: &WlSeatGlobal, event: &PendingScroll); fn node_focus(self: Rc, seat: &Rc); fn node_focus_parent(&self, seat: &Rc); fn node_toggle_floating(self: Rc, seat: &Rc); fn node_unfocus(&self, seat: &WlSeatGlobal); fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec) -> FindTreeResult; fn node_replace_child(self: Rc, old: &dyn Node, new: Rc); fn node_remove_child(self: Rc, child: &dyn Node); fn node_remove_child2(self: Rc, child: &dyn Node, preserve_focus: bool); fn node_child_size_changed(&self, child: &dyn Node, width: i32, height: i32); fn node_child_active_changed(self: Rc, child: &dyn Node, active: bool, depth: u32); fn node_leave(&self, seat: &WlSeatGlobal); fn node_pointer_enter(self: Rc, seat: &Rc, x: Fixed, y: Fixed); fn node_pointer_unfocus(&self, seat: &Rc); fn node_pointer_focus(&self, seat: &Rc); fn node_pointer_motion(self: Rc, seat: &Rc, x: Fixed, y: Fixed); fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32); fn node_into_float(self: Rc) -> Option>; fn node_into_container(self: Rc) -> Option>; fn node_into_workspace(self: Rc) -> Option>; fn node_is_container(&self) -> bool; fn node_is_output(&self) -> bool; fn node_into_output(self: Rc) -> Option>; fn node_accepts_child(&self, node: &dyn Node) -> bool; fn node_insert_child(self: Rc, node: Rc, direction: Direction); fn node_is_float(&self) -> bool; fn node_is_workspace(&self) -> bool; fn node_change_extents(self: Rc, rect: &Rect); fn node_set_workspace(self: Rc, ws: &Rc); fn node_set_parent(self: Rc, parent: Rc); fn node_client(&self) -> Option>; fn node_client_id(&self) -> Option; fn node_is_xwayland_surface(&self) -> bool; fn node_into_surface(self: Rc) -> Option>; fn node_dnd_drop(&self, dnd: &Dnd); fn node_dnd_leave(&self, dnd: &Dnd); fn node_dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32); fn node_dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed); fn node_set_fullscreen(self: Rc, fullscreen: bool); fn node_fullscreen(&self) -> bool; } impl Node for T { fn node_id(&self) -> NodeId { ::id(self) } fn node_seat_state(&self) -> &NodeSeatState { ::seat_state(self) } fn node_destroy(&self, detach: bool) { ::destroy_node(self, detach) } fn node_visit(self: Rc, visitor: &mut dyn NodeVisitor) { ::visit(&self, visitor) } fn node_visit_children(&self, visitor: &mut dyn NodeVisitor) { ::visit_children(self, visitor) } fn node_visible(&self) -> bool { ::visible(self) } fn node_parent(&self) -> Option> { ::parent(self) } fn node_last_active_child(self: Rc) -> Rc { ::last_active_child(&self) } fn node_set_visible(&self, visible: bool) { ::set_visible(self, visible) } fn node_get_workspace(&self) -> Option> { ::get_workspace(self) } fn node_child_title_changed(self: Rc, child: &dyn Node, title: &str) { ::child_title_changed(&self, child, title) } fn node_get_parent_mono(&self) -> Option { ::get_parent_mono(self) } fn node_get_parent_split(&self) -> Option { ::get_parent_split(self) } fn node_set_parent_mono(&self, mono: bool) { ::set_parent_mono(self, mono) } fn node_set_parent_split(&self, split: ContainerSplit) { ::set_parent_split(self, split) } fn node_get_mono(&self) -> Option { ::get_mono(self) } fn node_get_split(&self) -> Option { ::get_split(self) } fn node_set_mono(self: Rc, child: Option<&dyn Node>) { ::set_mono(&self, child) } fn node_set_split(self: Rc, split: ContainerSplit) { ::set_split(&self, split) } fn node_create_split(self: Rc, split: ContainerSplit) { ::create_split(&self, split) } fn node_focus_self(self: Rc, seat: &Rc) { ::focus_self(&self, seat) } fn node_do_focus(self: Rc, seat: &Rc, direction: Direction) { ::do_focus(&self, seat, direction) } fn node_close(self: Rc) { ::close(&self) } fn node_move_focus(self: Rc, seat: &Rc, direction: Direction) { ::move_focus(&self, seat, direction) } fn node_move_self(self: Rc, direction: Direction) { ::move_self(&self, direction) } fn node_move_focus_from_child( self: Rc, seat: &Rc, child: &dyn Node, direction: Direction, ) { ::move_focus_from_child(&self, seat, child, direction) } fn node_move_child(self: Rc, child: Rc, direction: Direction) { ::move_child(&self, child, direction) } fn node_absolute_position(&self) -> Rect { ::absolute_position(self) } fn node_absolute_position_constrains_input(&self) -> bool { ::absolute_position_constrains_input(self) } fn node_active_changed(&self, active: bool) { ::active_changed(self, active) } fn node_key(&self, seat: &WlSeatGlobal, key: u32, state: u32) { ::key(self, seat, key, state) } fn node_mods(&self, seat: &WlSeatGlobal, mods: ModifierState) { ::mods(self, seat, mods) } fn node_button( self: Rc, seat: &Rc, button: u32, state: KeyState, serial: u32, ) { ::button(&self, seat, button, state, serial) } fn node_axis_event(self: Rc, seat: &WlSeatGlobal, event: &PendingScroll) { ::axis_event(&self, seat, event) } fn node_focus(self: Rc, seat: &Rc) { ::focus(&self, seat) } fn node_focus_parent(&self, seat: &Rc) { ::focus_parent(self, seat) } fn node_toggle_floating(self: Rc, seat: &Rc) { ::toggle_floating(&self, seat) } fn node_unfocus(&self, seat: &WlSeatGlobal) { ::unfocus(self, seat) } fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec) -> FindTreeResult { ::find_tree_at(self, x, y, tree) } fn node_replace_child(self: Rc, old: &dyn Node, new: Rc) { ::replace_child(&self, old, new) } fn node_remove_child(self: Rc, child: &dyn Node) { ::remove_child(&self, child) } fn node_remove_child2(self: Rc, child: &dyn Node, preserve_focus: bool) { ::remove_child2(&self, child, preserve_focus) } fn node_child_size_changed(&self, child: &dyn Node, width: i32, height: i32) { ::child_size_changed(self, child, width, height) } fn node_child_active_changed(self: Rc, child: &dyn Node, active: bool, depth: u32) { ::child_active_changed(&self, child, active, depth) } fn node_leave(&self, seat: &WlSeatGlobal) { ::leave(self, seat) } fn node_pointer_enter(self: Rc, seat: &Rc, x: Fixed, y: Fixed) { ::pointer_enter(&self, seat, x, y) } fn node_pointer_unfocus(&self, seat: &Rc) { ::pointer_unfocus(self, seat) } fn node_pointer_focus(&self, seat: &Rc) { ::pointer_focus(self, seat) } fn node_pointer_motion(self: Rc, seat: &Rc, x: Fixed, y: Fixed) { ::pointer_motion(&self, seat, x, y) } fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { ::render(self, renderer, x, y) } fn node_into_float(self: Rc) -> Option> { ::into_float(&self) } fn node_into_container(self: Rc) -> Option> { ::into_container(&self) } fn node_into_workspace(self: Rc) -> Option> { ::into_workspace(&self) } fn node_is_container(&self) -> bool { ::is_container(self) } fn node_is_output(&self) -> bool { ::is_output(self) } fn node_into_output(self: Rc) -> Option> { ::into_output(&self) } fn node_accepts_child(&self, node: &dyn Node) -> bool { ::accepts_child(self, node) } fn node_insert_child(self: Rc, node: Rc, direction: Direction) { ::insert_child(&self, node, direction) } fn node_is_float(&self) -> bool { ::is_float(self) } fn node_is_workspace(&self) -> bool { ::is_workspace(self) } fn node_change_extents(self: Rc, rect: &Rect) { ::change_extents(&self, rect) } fn node_set_workspace(self: Rc, ws: &Rc) { ::set_workspace(&self, ws) } fn node_set_parent(self: Rc, parent: Rc) { ::set_parent(&self, parent) } fn node_client(&self) -> Option> { ::client(self) } fn node_client_id(&self) -> Option { ::client_id(self) } fn node_is_xwayland_surface(&self) -> bool { ::is_xwayland_surface(self) } fn node_into_surface(self: Rc) -> Option> { ::into_surface(&self) } fn node_dnd_drop(&self, dnd: &Dnd) { ::dnd_drop(self, dnd) } fn node_dnd_leave(&self, dnd: &Dnd) { ::dnd_leave(self, dnd) } fn node_dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32) { ::dnd_enter(self, dnd, x, y, serial) } fn node_dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) { ::dnd_motion(self, dnd, x, y) } fn node_set_fullscreen(self: Rc, fullscreen: bool) { ::set_fullscreen(&self, fullscreen) } fn node_fullscreen(&self) -> bool { ::fullscreen(self) } } pub struct FoundNode { pub node: Rc, pub x: i32, pub y: i32, }