diff --git a/src/ifs/jay_compositor.rs b/src/ifs/jay_compositor.rs index 6afb5e1c..df3e1f7b 100644 --- a/src/ifs/jay_compositor.rs +++ b/src/ifs/jay_compositor.rs @@ -23,12 +23,12 @@ use { leaks::Tracker, object::{Object, Version}, screenshoter::take_screenshot, - utils::errorfmt::ErrorFmt, + utils::{errorfmt::ErrorFmt, toplevel_identifier::ToplevelIdentifier}, wire::{jay_compositor::*, JayCompositorId, JayScreenshotId}, }, bstr::ByteSlice, log::Level, - std::{cell::Cell, ops::Deref, rc::Rc}, + std::{cell::Cell, ops::Deref, rc::Rc, str::FromStr}, thiserror::Error, }; @@ -364,13 +364,7 @@ impl JayCompositorRequestHandler for JayCompositor { fn select_toplevel(&self, req: SelectToplevel, _slf: &Rc) -> Result<(), Self::Error> { let seat = self.client.lookup(req.seat)?; - let obj = Rc::new(JaySelectToplevel { - id: req.id, - client: self.client.clone(), - tracker: Default::default(), - destroyed: Cell::new(false), - version: self.version, - }); + let obj = JaySelectToplevel::new(&self.client, req.id, self.version); track!(self.client, obj); self.client.add_client_obj(&obj)?; let selector = JayToplevelSelector { @@ -423,6 +417,26 @@ impl JayCompositorRequestHandler for JayCompositor { self.client.add_client_obj(&obj)?; Ok(()) } + + fn get_toplevel(&self, req: GetToplevel<'_>, _slf: &Rc) -> Result<(), Self::Error> { + let obj = JaySelectToplevel::new(&self.client, req.id, self.version); + track!(self.client, obj); + self.client.add_client_obj(&obj)?; + let tl = match ToplevelIdentifier::from_str(req.toplevel_id) { + Ok(id) => self + .client + .state + .toplevels + .get(&id) + .and_then(|w| w.upgrade()), + Err(e) => { + log::error!("Could not parse toplevel id: {}", ErrorFmt(e)); + None + } + }; + obj.done(tl); + Ok(()) + } } object_base! { diff --git a/src/ifs/jay_select_toplevel.rs b/src/ifs/jay_select_toplevel.rs index 634d8c0c..6eb83067 100644 --- a/src/ifs/jay_select_toplevel.rs +++ b/src/ifs/jay_select_toplevel.rs @@ -39,26 +39,32 @@ impl Drop for JayToplevelSelector { if self.jst.destroyed.get() { return; } - let jtl = match self.tl.take() { + self.jst.done(self.tl.take()); + } +} + +impl JaySelectToplevel { + pub fn done(&self, tl: Option>) { + let jtl = match tl { None => None, Some(toplevel) => { - let id = match self.jst.client.new_id() { + let id = match self.client.new_id() { Ok(id) => id, Err(e) => { - self.jst.client.error(e); + self.client.error(e); return; } }; let jtl = Rc::new(JayToplevel { id, - client: self.jst.client.clone(), + client: self.client.clone(), tracker: Default::default(), toplevel, destroyed: Cell::new(false), - version: self.jst.version, + version: self.version, }); - track!(self.jst.client, jtl); - self.jst.client.add_server_obj(&jtl); + track!(self.client, jtl); + self.client.add_server_obj(&jtl); jtl.toplevel .tl_data() .jay_toplevels @@ -67,20 +73,28 @@ impl Drop for JayToplevelSelector { } }; match jtl { - None => self.jst.send_done(JayToplevelId::NONE), + None => self.send_done(JayToplevelId::NONE), Some(jtl) => { - self.jst.send_done(jtl.id); + self.send_done(jtl.id); if jtl.version >= ID_SINCE { jtl.send_id(); jtl.send_done(); } } } - let _ = self.jst.client.remove_obj(&*self.jst); + let _ = self.client.remove_obj(self); + } + + pub fn new(client: &Rc, id: JaySelectToplevelId, version: Version) -> Rc { + Rc::new(JaySelectToplevel { + id, + client: client.clone(), + tracker: Default::default(), + destroyed: Cell::new(false), + version, + }) } -} -impl JaySelectToplevel { fn send_done(&self, id: JayToplevelId) { self.client.event(Done { self_id: self.id, diff --git a/wire/jay_compositor.txt b/wire/jay_compositor.txt index 5116178f..84f70406 100644 --- a/wire/jay_compositor.txt +++ b/wire/jay_compositor.txt @@ -96,6 +96,11 @@ request get_xwayland (since = 11) { id: id(jay_xwayland), } +request get_toplevel (since = 12) { + id: id(jay_select_toplevel), + toplevel_id: str, +} + # events event client_id {