smithay/wayland/xdg_foreign/
mod.rs1use std::{
33 collections::{HashMap, HashSet},
34 ops::Deref,
35};
36
37use rand::distr::{Alphanumeric, SampleString};
38use wayland_protocols::xdg::foreign::zv2::server::{
39 zxdg_exporter_v2::ZxdgExporterV2, zxdg_imported_v2::ZxdgImportedV2, zxdg_importer_v2::ZxdgImporterV2,
40};
41use wayland_server::{backend::GlobalId, protocol::wl_surface::WlSurface, DisplayHandle, GlobalDispatch};
42
43mod handlers;
44
45pub trait XdgForeignHandler: 'static {
47 fn xdg_foreign_state(&mut self) -> &mut XdgForeignState;
49}
50
51#[derive(Debug, Clone, Hash, PartialEq, Eq)]
55struct XdgForeignHandle(String);
56
57impl XdgForeignHandle {
58 fn new() -> Self {
59 Self(Alphanumeric.sample_string(&mut rand::rng(), 32))
60 }
61
62 fn as_str(&self) -> &str {
63 &self.0
64 }
65}
66
67impl Deref for XdgForeignHandle {
68 type Target = str;
69 fn deref(&self) -> &str {
70 &self.0
71 }
72}
73
74#[derive(Debug)]
76pub struct XdgExportedUserData {
77 handle: XdgForeignHandle,
78}
79
80#[derive(Debug)]
82pub struct XdgImportedUserData {
83 handle: XdgForeignHandle,
84}
85
86#[derive(Debug)]
87struct ExportedState {
88 exported_surface: WlSurface,
89 requested_child: Option<(WlSurface, ZxdgImportedV2)>,
90 imported_by: HashSet<ZxdgImportedV2>,
91}
92
93#[derive(Debug)]
95pub struct XdgForeignState {
96 exported: HashMap<XdgForeignHandle, ExportedState>,
97 exporter: GlobalId,
98 importer: GlobalId,
99}
100
101impl XdgForeignState {
102 pub fn new<D>(display: &DisplayHandle) -> Self
106 where
107 D: XdgForeignHandler,
108 D: GlobalDispatch<ZxdgExporterV2, ()>,
109 D: GlobalDispatch<ZxdgImporterV2, ()>,
110 {
111 let exporter = display.create_global::<D, ZxdgExporterV2, _>(1, ());
112 let importer = display.create_global::<D, ZxdgImporterV2, _>(1, ());
113
114 Self {
115 exported: HashMap::new(),
116 exporter,
117 importer,
118 }
119 }
120
121 pub fn exporter_global(&self) -> GlobalId {
123 self.exporter.clone()
124 }
125
126 pub fn importer_global(&self) -> GlobalId {
128 self.importer.clone()
129 }
130}
131
132#[macro_export]
137macro_rules! delegate_xdg_foreign {
138 ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
139 type __ZxdgExporterV2 =
140 $crate::reexports::wayland_protocols::xdg::foreign::zv2::server::zxdg_exporter_v2::ZxdgExporterV2;
141 type __ZxdgImporterV2 =
142 $crate::reexports::wayland_protocols::xdg::foreign::zv2::server::zxdg_importer_v2::ZxdgImporterV2;
143
144 type __ZxdgExportedV2 =
145 $crate::reexports::wayland_protocols::xdg::foreign::zv2::server::zxdg_exported_v2::ZxdgExportedV2;
146 type __ZxdgImportedV2 =
147 $crate::reexports::wayland_protocols::xdg::foreign::zv2::server::zxdg_imported_v2::ZxdgImportedV2;
148
149 $crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
150 [
151 __ZxdgExporterV2: ()
152 ] => $crate::wayland::xdg_foreign::XdgForeignState
153 );
154 $crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
155 [
156 __ZxdgImporterV2: ()
157 ] => $crate::wayland::xdg_foreign::XdgForeignState
158 );
159
160 $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
161 [
162 __ZxdgExporterV2: ()
163 ] => $crate::wayland::xdg_foreign::XdgForeignState
164 );
165 $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
166 [
167 __ZxdgImporterV2: ()
168 ] => $crate::wayland::xdg_foreign::XdgForeignState
169 );
170
171 $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
172 [
173 __ZxdgExportedV2: $crate::wayland::xdg_foreign::XdgExportedUserData
174 ] => $crate::wayland::xdg_foreign::XdgForeignState
175 );
176 $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
177 [
178 __ZxdgImportedV2: $crate::wayland::xdg_foreign::XdgImportedUserData
179 ] => $crate::wayland::xdg_foreign::XdgForeignState
180 );
181 };
182}