Skip to main content

smithay_client_toolkit/
subcompositor.rs

1use crate::reexports::client::globals::{BindError, GlobalList};
2use crate::reexports::client::protocol::wl_compositor::WlCompositor;
3use crate::reexports::client::protocol::wl_subcompositor::WlSubcompositor;
4use crate::reexports::client::protocol::wl_subsurface::WlSubsurface;
5use crate::reexports::client::protocol::wl_surface::WlSurface;
6use crate::reexports::client::{Connection, Dispatch, Proxy, QueueHandle};
7
8use crate::compositor::SurfaceData;
9use crate::dispatch2::Dispatch2;
10use crate::globals::GlobalData;
11
12#[derive(Debug)]
13pub struct SubcompositorState {
14    compositor: WlCompositor,
15    subcompositor: WlSubcompositor,
16}
17
18impl SubcompositorState {
19    pub fn bind<State>(
20        compositor: WlCompositor,
21        globals: &GlobalList,
22        queue_handle: &QueueHandle<State>,
23    ) -> Result<Self, BindError>
24    where
25        State: Dispatch<WlSubcompositor, GlobalData, State> + 'static,
26    {
27        let subcompositor = globals.bind(queue_handle, 1..=1, GlobalData)?;
28        Ok(SubcompositorState { compositor, subcompositor })
29    }
30
31    pub fn create_subsurface<State>(
32        &self,
33        parent: WlSurface,
34        queue_handle: &QueueHandle<State>,
35    ) -> (WlSubsurface, WlSurface)
36    where
37        State:
38            Dispatch<WlSurface, SurfaceData<()>> + Dispatch<WlSubsurface, SubsurfaceData> + 'static,
39    {
40        let surface_data = SurfaceData::new(Some(parent.clone()), 1, ());
41        let surface = self.compositor.create_surface(queue_handle, surface_data);
42        let subsurface_data = SubsurfaceData::new(surface.clone());
43        let subsurface =
44            self.subcompositor.get_subsurface(&surface, &parent, queue_handle, subsurface_data);
45        (subsurface, surface)
46    }
47
48    pub fn subsurface_from_surface<State>(
49        &self,
50        surface: &WlSurface,
51        queue_handle: &QueueHandle<State>,
52    ) -> Option<WlSubsurface>
53    where
54        State:
55            Dispatch<WlSurface, SurfaceData<()>> + Dispatch<WlSubsurface, SubsurfaceData> + 'static,
56    {
57        let parent = surface.data::<SurfaceData<()>>().unwrap().parent_surface();
58        let subsurface_data = SubsurfaceData::new(surface.clone());
59        parent.map(|parent| {
60            self.subcompositor.get_subsurface(surface, parent, queue_handle, subsurface_data)
61        })
62    }
63}
64
65impl<D> Dispatch2<WlSubsurface, D> for SubsurfaceData {
66    fn event(
67        &self,
68        _: &mut D,
69        _: &WlSubsurface,
70        _: <WlSubsurface as Proxy>::Event,
71        _: &Connection,
72        _: &QueueHandle<D>,
73    ) {
74        unreachable!("wl_subsurface has no events")
75    }
76}
77
78impl<D> Dispatch2<WlSubcompositor, D> for GlobalData {
79    fn event(
80        &self,
81        _: &mut D,
82        _: &WlSubcompositor,
83        _: <WlSubcompositor as Proxy>::Event,
84        _: &Connection,
85        _: &QueueHandle<D>,
86    ) {
87        unreachable!("wl_subcompositor has no events")
88    }
89}
90
91/// The data assoctiated with the subsurface.
92#[derive(Debug)]
93pub struct SubsurfaceData {
94    /// The surface used when creating this subsurface.
95    surface: WlSurface,
96}
97
98impl SubsurfaceData {
99    pub(crate) fn new(surface: WlSurface) -> Self {
100        Self { surface }
101    }
102
103    /// Get the surface used when creating the given subsurface.
104    pub fn surface(&self) -> &WlSurface {
105        &self.surface
106    }
107}