use crate::ifs::wl_surface::SurfaceExt;
use crate::ifs::wl_surface::WlSurface;
use crate::ifs::wl_surface::WlSurfaceError;
use crate::ifs::wl_surface::x_surface::xwayland_surface_v1::XwaylandSurfaceV1;
use crate::ifs::wl_surface::x_surface::xwindow::Xwindow;
use crate::leaks::Tracker;
use crate::tree::Node;
use crate::tree::NodeBase;
use crate::tree::NodeLayerLink;
use crate::tree::ToplevelNode;
use crate::tree::ToplevelNodeBase;
use crate::tree::TreeTimeline::LiveTL;
use crate::tree::WorkspaceNode;
use crate::utils::clonecell::CloneCell;
use crate::wire::ObjectId;
use crate::xwayland::XWaylandEvent;
use std::rc::Rc;
pub mod xwayland_surface_v1;
pub mod xwindow;
pub struct XSurface {
pub surface: Rc<WlSurface>,
pub xwindow: CloneCell<Option<Rc<Xwindow>>>,
pub xwayland_surface: CloneCell<Option<Rc<XwaylandSurfaceV1>>>,
pub tracker: Tracker<Self>,
}
impl SurfaceExt for XSurface {
fn object_id(&self) -> Option<ObjectId> {
None
}
fn node_layer(&self) -> NodeLayerLink {
let Some(win) = self.xwindow.get() else {
return NodeLayerLink::Display;
};
win.node_layer()
}
fn after_apply_commit(self: Rc<Self>) {
if let Some(xwindow) = self.xwindow.get() {
xwindow.map_status_changed();
xwindow
.toplevel_data
.set_content_type(self.surface.content_type.get());
}
}
fn on_surface_destroy(&self) -> Result<(), WlSurfaceError> {
if self.xwayland_surface.is_some() {
return Err(WlSurfaceError::ReloObjectStillExists);
}
self.surface.unset_ext();
if let Some(xwindow) = self.xwindow.take() {
xwindow.destroy();
xwindow.data.surface_id.set(None);
xwindow
.data
.state
.xwayland
.queue
.push(XWaylandEvent::SurfaceDestroyed(
self.surface.id,
self.surface.xwayland_serial.get(),
));
}
Ok(())
}
fn extents_changed(&self) {
if let Some(xwindow) = self.xwindow.get() {
xwindow
.toplevel_data
.content_size
.set(self.surface.extents.get());
xwindow.tl_extents_changed();
}
}
fn focus_node(&self) -> Option<Rc<dyn Node>> {
if let Some(xwindow) = self.xwindow.get()
&& xwindow.tl_accepts_keyboard_focus()
{
return Some(xwindow.x.surface.clone());
}
None
}
fn into_xsurface(self: Rc<Self>) -> Option<Rc<XSurface>> {
Some(self)
}
fn workspace(&self) -> Option<Rc<WorkspaceNode>> {
self.xwindow.get()?.toplevel_data.workspace[LiveTL].get()
}
fn unmap(self: Rc<Self>) {
if let Some(xwindow) = self.xwindow.get() {
xwindow.map_status_changed_(true);
}
}
}