use super::*; impl ConfigProxyHandler { pub(super) fn tl_to_window(&self, tl: &dyn ToplevelNode) -> Window { self.tl_id_to_window(tl.tl_data().identifier.get()) } pub(super) fn tl_id_to_window(&self, tl: ToplevelIdentifier) -> Window { if let Some(win) = self.windows_from_tl_id.get(&tl) { return win; } let id = Window(self.window_ids.fetch_add(1)); self.windows_from_tl_id.set(tl, id); self.windows_to_tl_id.set(id, tl); id } pub(super) fn get_window(&self, window: Window) -> Result, CphError> { self.windows_to_tl_id .get(&window) .and_then(|id| self.state.toplevels.get(&id)) .and_then(|tl| tl.upgrade()) .ok_or(CphError::WindowDoesNotExist(window)) } pub(super) fn get_client(&self, client: ConfigClient) -> Result, CphError> { self.state .clients .get(ClientId::from_raw(client.0)) .ok() .ok_or(CphError::ClientDoesNotExist(client)) } pub(super) fn handle_get_clients(&self) { let mut clients = vec![]; for client in self.state.clients.clients.borrow().values() { clients.push(ConfigClient(client.data.id.raw())); } self.respond(Response::GetClients { clients }); } pub(super) fn handle_client_exists(&self, client: ConfigClient) { self.respond(Response::ClientExists { exists: self.get_client(client).is_ok(), }); } pub(super) fn handle_client_is_xwayland(&self, client: ConfigClient) -> Result<(), CphError> { self.respond(Response::ClientIsXwayland { is_xwayland: self.get_client(client)?.is_xwayland, }); Ok(()) } pub(super) fn handle_client_kill(&self, client: ConfigClient) { self.state.clients.kill(ClientId::from_raw(client.0)); } pub(super) fn handle_get_workspace_window(&self, ws: Workspace) -> Result<(), CphError> { let window = self .get_existing_workspace(ws)? .and_then(|ws| ws.container.get()) .map(|c| self.tl_to_window(&*c)) .unwrap_or(Window(0)); self.respond(Response::GetWorkspaceWindow { window }); Ok(()) } pub(super) fn handle_get_seat_keyboard_window(&self, seat: Seat) -> Result<(), CphError> { let window = self .get_seat(seat)? .get_keyboard_node() .node_toplevel() .map(|tl| self.tl_to_window(&*tl)) .unwrap_or(Window(0)); self.respond(Response::GetSeatKeyboardWindow { window }); Ok(()) } pub(super) fn handle_seat_focus_window(&self, seat: Seat, window_id: Window) -> Result<(), CphError> { let seat = self.get_seat(seat)?; let window = self.get_window(window_id)?; if !window.node_visible() { return Err(CphError::WindowNotVisible(window_id)); } seat.focus_toplevel(window); seat.maybe_schedule_warp_mouse_to_focus(); Ok(()) } pub(super) fn handle_get_window_title(&self, window: Window) -> Result<(), CphError> { let title = self.get_window(window)?.tl_data().title.borrow().clone(); self.respond(Response::GetWindowTitle { title }); Ok(()) } pub(super) fn handle_get_window_type(&self, window: Window) -> Result<(), CphError> { let kind = self.get_window(window)?.tl_data().kind.to_window_type(); self.respond(Response::GetWindowType { kind }); Ok(()) } pub(super) fn handle_get_content_type(&self, window: Window) -> Result<(), CphError> { let kind = self .get_window(window)? .tl_data() .content_type .get() .to_config(); self.respond(Response::GetContentType { kind }); Ok(()) } pub(super) fn handle_window_resize( &self, window: Window, dx1: i32, dy1: i32, dx2: i32, dy2: i32, ) -> Result<(), CphError> { self.state.with_layout_animations(|| { self.get_window(window)?.tl_resize(dx1, dy1, dx2, dy2); Ok(()) }) } pub(super) fn handle_window_exists(&self, window: Window) { self.respond(Response::WindowExists { exists: self.get_window(window).is_ok(), }); } pub(super) fn handle_get_window_id(&self, window: Window) -> Result<(), CphError> { let id = self .get_window(window)? .tl_data() .identifier .get() .to_string(); self.respond(Response::GetWindowId { id: id.to_string() }); Ok(()) } pub(super) fn handle_get_window_is_visible(&self, window: Window) -> Result<(), CphError> { let window = self.get_window(window)?; self.respond(Response::GetWindowIsVisible { visible: window.node_visible(), }); Ok(()) } pub(super) fn handle_get_window_client(&self, window: Window) -> Result<(), CphError> { let window = self.get_window(window)?; self.respond(Response::GetWindowClient { client: window .tl_data() .client .as_ref() .map(|c| ConfigClient(c.id.raw())) .unwrap_or(ConfigClient(0)), }); Ok(()) } pub(super) fn handle_get_window_parent(&self, window: Window) -> Result<(), CphError> { let window = self .get_window(window)? .tl_data() .parent .get() .and_then(|tl| tl.node_into_toplevel()) .map(|tl| self.tl_to_window(&*tl)) .unwrap_or(Window(0)); self.respond(Response::GetWindowParent { window }); Ok(()) } pub(super) fn handle_get_window_workspace(&self, window: Window) -> Result<(), CphError> { let workspace = self .get_window(window)? .tl_data() .workspace .get() .map(|ws| self.get_workspace_by_name(&ws.name)) .unwrap_or(Workspace(0)); self.respond(Response::GetWindowWorkspace { workspace }); Ok(()) } pub(super) fn handle_get_window_children(&self, window: Window) -> Result<(), CphError> { let mut windows = vec![]; if let Some(c) = self.get_window(window)?.node_into_container() { for c in c.children.iter() { windows.push(self.tl_to_window(&*c.node)); } } self.respond(Response::GetWindowChildren { windows }); Ok(()) } }