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::globals::GlobalData;
10
11#[derive(Debug)]
12pub struct SubcompositorState {
13 compositor: WlCompositor,
14 subcompositor: WlSubcompositor,
15}
16
17impl SubcompositorState {
18 pub fn bind<State>(
19 compositor: WlCompositor,
20 globals: &GlobalList,
21 queue_handle: &QueueHandle<State>,
22 ) -> Result<Self, BindError>
23 where
24 State: Dispatch<WlSubcompositor, GlobalData, State> + 'static,
25 {
26 let subcompositor = globals.bind(queue_handle, 1..=1, GlobalData)?;
27 Ok(SubcompositorState { compositor, subcompositor })
28 }
29
30 pub fn create_subsurface<State>(
31 &self,
32 parent: WlSurface,
33 queue_handle: &QueueHandle<State>,
34 ) -> (WlSubsurface, WlSurface)
35 where
36 State: Dispatch<WlSurface, SurfaceData> + Dispatch<WlSubsurface, SubsurfaceData> + 'static,
37 {
38 let surface_data = SurfaceData::new(Some(parent.clone()), 1);
39 let surface = self.compositor.create_surface(queue_handle, surface_data);
40 let subsurface_data = SubsurfaceData::new(surface.clone());
41 let subsurface =
42 self.subcompositor.get_subsurface(&surface, &parent, queue_handle, subsurface_data);
43 (subsurface, surface)
44 }
45}
46
47impl<D> Dispatch<WlSubsurface, SubsurfaceData, D> for SubcompositorState
48where
49 D: Dispatch<WlSubsurface, SubsurfaceData>,
50{
51 fn event(
52 _: &mut D,
53 _: &WlSubsurface,
54 _: <WlSubsurface as Proxy>::Event,
55 _: &SubsurfaceData,
56 _: &Connection,
57 _: &QueueHandle<D>,
58 ) {
59 unreachable!("wl_subsurface has no events")
60 }
61}
62
63impl<D> Dispatch<WlSubcompositor, GlobalData, D> for SubcompositorState
64where
65 D: Dispatch<WlSubcompositor, GlobalData>,
66{
67 fn event(
68 _: &mut D,
69 _: &WlSubcompositor,
70 _: <WlSubcompositor as Proxy>::Event,
71 _: &GlobalData,
72 _: &Connection,
73 _: &QueueHandle<D>,
74 ) {
75 unreachable!("wl_subcompositor has no events")
76 }
77}
78
79/// The data assoctiated with the subsurface.
80#[derive(Debug)]
81pub struct SubsurfaceData {
82 /// The surface used when creating this subsurface.
83 surface: WlSurface,
84}
85
86impl SubsurfaceData {
87 pub(crate) fn new(surface: WlSurface) -> Self {
88 Self { surface }
89 }
90
91 /// Get the surface used when creating the given subsurface.
92 pub fn surface(&self) -> &WlSurface {
93 &self.surface
94 }
95}
96
97#[macro_export]
98macro_rules! delegate_subcompositor {
99 ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
100 $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface: []);
101 $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface-only: $crate::subcompositor::SubsurfaceData);
102 };
103 ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty, subsurface: [$($subsurface: ty),*$(,)?]) => {
104 $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface: [ $($subsurface),* ]);
105 };
106 (@{$($ty:tt)*}; subsurface: []) => {
107 $crate::reexports::client::delegate_dispatch!($($ty)*:
108 [
109 $crate::reexports::client::protocol::wl_subcompositor::WlSubcompositor: $crate::globals::GlobalData
110 ] => $crate::subcompositor::SubcompositorState
111 );
112 };
113 (@{$($ty:tt)*}; subsurface-only: $subsurface:ty) => {
114 $crate::reexports::client::delegate_dispatch!($($ty)*:
115 [
116 $crate::reexports::client::protocol::wl_subsurface::WlSubsurface: $subsurface
117 ] => $crate::subcompositor::SubcompositorState
118 );
119 };
120 (@$ty:tt; subsurface: [ $($subsurface:ty),+ ]) => {
121 $crate::delegate_subcompositor!(@$ty; subsurface: []);
122 $( $crate::delegate_subcompositor!(@$ty; subsurface-only: $subsurface); )*
123 };
124}
125