use { crate::{ client::{Client, ClientError}, ifs::{jay_workspace::JayWorkspace, wl_seat::WorkspaceSelector}, leaks::Tracker, object::{Object, Version}, tree::WorkspaceNode, utils::clonecell::CloneCell, wire::{JaySelectWorkspaceId, JayWorkspaceId, jay_select_workspace::*}, }, std::{cell::Cell, rc::Rc}, thiserror::Error, }; pub struct JaySelectWorkspace { pub id: JaySelectWorkspaceId, pub client: Rc, pub tracker: Tracker, pub destroyed: Cell, } pub struct JayWorkspaceSelector { pub ws: CloneCell>>, pub jsw: Rc, } impl WorkspaceSelector for JayWorkspaceSelector { fn set(&self, ws: Rc) { self.ws.set(Some(ws)); } } impl Drop for JayWorkspaceSelector { fn drop(&mut self) { if self.jsw.destroyed.get() { return; } match self.ws.take() { None => { self.jsw.send_cancelled(); } Some(ws) => { let id = match self.jsw.client.new_id() { Ok(id) => id, Err(e) => { self.jsw.client.error(e); return; } }; let jw = Rc::new(JayWorkspace { id, client: self.jsw.client.clone(), workspace: CloneCell::new(Some(ws.clone())), tracker: Default::default(), }); track!(self.jsw.client, jw); self.jsw.client.add_server_obj(&jw); self.jsw .send_selected(ws.output.get().global.name.raw(), id); ws.jay_workspaces .set((self.jsw.client.id, jw.id), jw.clone()); jw.send_initial_properties(&ws); } }; let _ = self.jsw.client.remove_obj(&*self.jsw); } } impl JaySelectWorkspace { fn send_cancelled(&self) { self.client.event(Cancelled { self_id: self.id }); } fn send_selected(&self, output: u32, id: JayWorkspaceId) { self.client.event(Selected { self_id: self.id, output, id, }); } } impl JaySelectWorkspaceRequestHandler for JaySelectWorkspace { type Error = JaySelectWorkspaceError; } object_base! { self = JaySelectWorkspace; version = Version(1); } impl Object for JaySelectWorkspace { fn break_loops(&self) { self.destroyed.set(true); } } simple_add_obj!(JaySelectWorkspace); #[derive(Debug, Error)] pub enum JaySelectWorkspaceError { #[error(transparent)] ClientError(Box), } efrom!(JaySelectWorkspaceError, ClientError);