smithay_client_toolkit/
subcompositor.rs1use 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 pub fn subsurface_from_surface<State>(
47 &self,
48 surface: &WlSurface,
49 queue_handle: &QueueHandle<State>,
50 ) -> Option<WlSubsurface>
51 where
52 State: Dispatch<WlSurface, SurfaceData> + Dispatch<WlSubsurface, SubsurfaceData> + 'static,
53 {
54 let parent = surface.data::<SurfaceData>().unwrap().parent_surface();
55 let subsurface_data = SubsurfaceData::new(surface.clone());
56 parent.map(|parent| {
57 self.subcompositor.get_subsurface(surface, parent, queue_handle, subsurface_data)
58 })
59 }
60}
61
62impl<D> Dispatch<WlSubsurface, SubsurfaceData, D> for SubcompositorState
63where
64 D: Dispatch<WlSubsurface, SubsurfaceData>,
65{
66 fn event(
67 _: &mut D,
68 _: &WlSubsurface,
69 _: <WlSubsurface as Proxy>::Event,
70 _: &SubsurfaceData,
71 _: &Connection,
72 _: &QueueHandle<D>,
73 ) {
74 unreachable!("wl_subsurface has no events")
75 }
76}
77
78impl<D> Dispatch<WlSubcompositor, GlobalData, D> for SubcompositorState
79where
80 D: Dispatch<WlSubcompositor, GlobalData>,
81{
82 fn event(
83 _: &mut D,
84 _: &WlSubcompositor,
85 _: <WlSubcompositor as Proxy>::Event,
86 _: &GlobalData,
87 _: &Connection,
88 _: &QueueHandle<D>,
89 ) {
90 unreachable!("wl_subcompositor has no events")
91 }
92}
93
94#[derive(Debug)]
96pub struct SubsurfaceData {
97 surface: WlSurface,
99}
100
101impl SubsurfaceData {
102 pub(crate) fn new(surface: WlSurface) -> Self {
103 Self { surface }
104 }
105
106 pub fn surface(&self) -> &WlSurface {
108 &self.surface
109 }
110}
111
112#[macro_export]
113macro_rules! delegate_subcompositor {
114 ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
115 $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface: []);
116 $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface-only: $crate::subcompositor::SubsurfaceData);
117 };
118 ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty, subsurface: [$($subsurface: ty),*$(,)?]) => {
119 $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface: [ $($subsurface),* ]);
120 };
121 (@{$($ty:tt)*}; subsurface: []) => {
122 $crate::reexports::client::delegate_dispatch!($($ty)*:
123 [
124 $crate::reexports::client::protocol::wl_subcompositor::WlSubcompositor: $crate::globals::GlobalData
125 ] => $crate::subcompositor::SubcompositorState
126 );
127 };
128 (@{$($ty:tt)*}; subsurface-only: $subsurface:ty) => {
129 $crate::reexports::client::delegate_dispatch!($($ty)*:
130 [
131 $crate::reexports::client::protocol::wl_subsurface::WlSubsurface: $subsurface
132 ] => $crate::subcompositor::SubcompositorState
133 );
134 };
135 (@$ty:tt; subsurface: [ $($subsurface:ty),+ ]) => {
136 $crate::delegate_subcompositor!(@$ty; subsurface: []);
137 $( $crate::delegate_subcompositor!(@$ty; subsurface-only: $subsurface); )*
138 };
139}