use crate::client::CAP_FOREIGN_TOPLEVEL_MANAGER;
use crate::client::Client;
use crate::client::ClientCaps;
use crate::globals::Global;
use crate::globals::GlobalName;
use crate::ifs::wl_surface::x_surface::xwindow::Xwindow;
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel;
use crate::ifs::zwlr_foreign_toplevel_handle_v1::ZwlrForeignToplevelHandleV1;
use crate::leaks::Tracker;
use crate::object::BreakLoops;
use crate::object::Version;
use crate::tree::NodeVisitorBase;
use crate::tree::OutputNodeId;
use crate::tree::ToplevelOpt;
use crate::wire::ZwlrForeignToplevelManagerV1Id;
use crate::wire::zwlr_foreign_toplevel_manager_v1::*;
use jay_proc::Global;
use jay_proc::Object;
use std::cell::Cell;
use std::convert::Infallible;
use std::rc::Rc;
#[derive(Global)]
pub struct ZwlrForeignToplevelManagerV1Global {
name: GlobalName,
}
impl ZwlrForeignToplevelManagerV1Global {
pub fn new(name: GlobalName) -> Self {
Self { name }
}
fn bind_(
self: Rc<Self>,
id: ZwlrForeignToplevelManagerV1Id,
client: &Rc<Client>,
version: Version,
) -> Result<(), Infallible> {
let obj = Rc::new(ZwlrForeignToplevelManagerV1 {
id,
client: client.clone(),
tracker: Default::default(),
version,
});
track!(client, obj);
client.add_client_obj(&obj);
client
.state
.visit_all_nodes(&mut ZwlrToplevelVisitor { manager: &obj });
client.state.toplevel_managers.set((client.id, id), obj);
Ok(())
}
}
struct ZwlrToplevelVisitor<'a> {
manager: &'a ZwlrForeignToplevelManagerV1,
}
impl NodeVisitorBase for ZwlrToplevelVisitor<'_> {
fn visit_toplevel(&mut self, node: &Rc<XdgToplevel>) {
node.manager_send_to(self.manager);
}
fn visit_xwindow(&mut self, node: &Rc<Xwindow>) {
node.toplevel_data.manager_send(node.clone(), self.manager);
}
}
#[derive(Object)]
#[break_loops]
pub struct ZwlrForeignToplevelManagerV1 {
id: ZwlrForeignToplevelManagerV1Id,
client: Rc<Client>,
tracker: Tracker<Self>,
version: Version,
}
impl ZwlrForeignToplevelManagerV1 {
fn detach(&self) {
self.client
.state
.toplevel_managers
.remove(&(self.client.id, self.id));
}
}
impl ZwlrForeignToplevelManagerV1RequestHandler for ZwlrForeignToplevelManagerV1 {
type Error = Infallible;
fn stop(&self, _req: Stop, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.detach();
self.send_finished();
self.client.remove_obj(self);
Ok(())
}
}
impl ZwlrForeignToplevelManagerV1 {
fn send_finished(&self) {
self.client.event(Finished { self_id: self.id });
}
fn send_handle(&self, handle: &ZwlrForeignToplevelHandleV1) {
self.client.event(Toplevel {
self_id: self.id,
toplevel: handle.id,
});
}
pub fn publish_toplevel(&self, tl: ToplevelOpt) -> Rc<ZwlrForeignToplevelHandleV1> {
let id = self.client.new_id(self);
let handle = Rc::new(ZwlrForeignToplevelHandleV1 {
id,
client: self.client.clone(),
tracker: Default::default(),
version: self.version,
toplevel: tl,
output: Cell::new(OutputNodeId::none()),
});
track!(self.client, handle);
self.client.add_server_obj(&handle);
self.send_handle(&handle);
handle
}
}
impl Global for ZwlrForeignToplevelManagerV1Global {
fn version(&self) -> u32 {
3
}
fn required_caps(&self) -> ClientCaps {
CAP_FOREIGN_TOPLEVEL_MANAGER
}
}
impl BreakLoops for ZwlrForeignToplevelManagerV1 {
fn break_loops(self: Rc<Self>) {
self.detach();
}
}