use crate::async_engine::{AsyncEngine, SpawnedFuture}; use crate::backend::{Backend, BackendEvent, InputDevice, InputDeviceId, InputDeviceIds, OutputId, OutputIds}; use crate::client::{Client, Clients}; use crate::config::ConfigProxy; use crate::cursor::ServerCursors; use crate::dbus::Dbus; use crate::event_loop::EventLoop; use crate::forker::ForkerProxy; use crate::globals::{Globals, GlobalsError, WaylandGlobal}; use crate::ifs::wl_output::WlOutputGlobal; use crate::ifs::wl_seat::{SeatIds, WlSeatGlobal}; use crate::ifs::wl_surface::NoneSurfaceExt; use crate::rect::Rect; use crate::render::RenderContext; use crate::theme::Theme; use crate::tree::{ ContainerNode, ContainerSplit, DisplayNode, FloatNode, Node, NodeIds, WorkspaceNode, }; use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; use crate::utils::fdcloser::FdCloser; use crate::utils::linkedlist::LinkedList; use crate::utils::numcell::NumCell; use crate::utils::queue::AsyncQueue; use crate::xkbcommon::XkbKeymap; use crate::{ErrorFmt, Wheel, XkbContext}; use ahash::AHashMap; use std::cell::{Cell, RefCell}; use std::rc::Rc; use std::sync::Arc; pub struct State { pub xkb_ctx: XkbContext, pub backend: CloneCell>>, pub forker: CloneCell>>, pub default_keymap: Rc, pub eng: Rc, pub el: Rc, pub render_ctx: CloneCell>>, pub cursors: CloneCell>>, pub wheel: Rc, pub clients: Clients, pub next_name: NumCell, pub globals: Globals, pub output_ids: OutputIds, pub seat_ids: SeatIds, pub input_device_ids: InputDeviceIds, pub node_ids: NodeIds, pub root: Rc, pub backend_events: AsyncQueue, pub output_handlers: RefCell>>, pub input_device_handlers: RefCell>, pub outputs: CopyHashMap>, pub seat_queue: LinkedList>, pub slow_clients: AsyncQueue>, pub none_surface_ext: Rc, pub tree_changed_sent: Cell, pub config: CloneCell>>, pub theme: Theme, pub pending_container_layout: AsyncQueue>, pub pending_container_titles: AsyncQueue>, pub pending_float_layout: AsyncQueue>, pub pending_float_titles: AsyncQueue>, pub dbus: Dbus, pub fdcloser: Arc, } pub struct InputDeviceData { pub handler: SpawnedFuture<()>, pub id: InputDeviceId, pub device: Rc, pub data: Rc, } pub struct DeviceHandlerData { pub seat: CloneCell>>, } impl State { pub fn set_render_ctx(&self, ctx: &Rc) { let cursors = match ServerCursors::load(ctx) { Ok(c) => Some(Rc::new(c)), Err(e) => { log::error!("Could not load the cursors: {}", ErrorFmt(e)); None } }; self.cursors.set(cursors); self.render_ctx.set(Some(ctx.clone())); } pub fn add_global(&self, global: &Rc) { self.globals.add_global(self, global) } pub fn remove_global(&self, global: &T) -> Result<(), GlobalsError> { self.globals.remove(self, global) } pub fn tree_changed(&self) { if self.tree_changed_sent.replace(true) { return; } let seats = self.globals.seats.lock(); for seat in seats.values() { seat.trigger_tree_changed(); } } pub fn map_tiled(self: &Rc, node: Rc) { let seat = self.seat_queue.last(); if let Some(seat) = seat { if let Some(prev) = seat.last_tiled_keyboard_toplevel(&*node) { if let Some(container) = prev.parent() { if let Some(container) = container.into_container() { container.add_child_after(prev.as_node(), node); return; } } } } let output = { let outputs = self.root.outputs.lock(); outputs.values().next().cloned() }; if let Some(output) = output { if let Some(workspace) = output.workspace.get() { if let Some(container) = workspace.container.get() { container.append_child(node); } else { let container = ContainerNode::new( self, &workspace, workspace.clone(), node, ContainerSplit::Horizontal, ); workspace.set_container(&container); }; return; } } todo!("map_tiled"); } pub fn map_floating( self: &Rc, node: Rc, mut width: i32, mut height: i32, workspace: &Rc, ) { node.clone().set_workspace(workspace); width += 2 * self.theme.border_width.get(); height += 2 * self.theme.border_width.get() + self.theme.title_height.get(); let output = workspace.output.get(); let output_rect = output.position.get(); let position = { let mut x1 = output_rect.x1(); let mut y1 = output_rect.y1(); if width < output_rect.width() { x1 += (output_rect.width() - width) as i32 / 2; } else { width = output_rect.width(); } if height < output_rect.height() { y1 += (output_rect.height() - height) as i32 / 2; } else { height = output_rect.height(); } Rect::new_sized(x1, y1, width, height).unwrap() }; FloatNode::new(self, workspace, position, node); } }