simple_window/common/protocols/wayland/wl_subsurface.rs
1//! sub-surface interface to a wl_surface
2//!
3//! An additional interface to a wl_surface object, which has been
4//! made a sub-surface. A sub-surface has one parent surface. A
5//! sub-surface's size and position are not limited to that of the parent.
6//! Particularly, a sub-surface is not automatically clipped to its
7//! parent's area.
8//!
9//! A sub-surface becomes mapped, when a non-NULL wl_buffer is applied
10//! and the parent surface is mapped. The order of which one happens
11//! first is irrelevant. A sub-surface is hidden if the parent becomes
12//! hidden, or if a NULL wl_buffer is applied. These rules apply
13//! recursively through the tree of surfaces.
14//!
15//! The behaviour of a wl_surface.commit request on a sub-surface
16//! depends on the sub-surface's mode. The possible modes are
17//! synchronized and desynchronized, see methods
18//! wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized
19//! mode caches the wl_surface state to be applied when the parent's
20//! state gets applied, and desynchronized mode applies the pending
21//! wl_surface state directly. A sub-surface is initially in the
22//! synchronized mode.
23//!
24//! Sub-surfaces also have another kind of state, which is managed by
25//! wl_subsurface requests, as opposed to wl_surface requests. This
26//! state includes the sub-surface position relative to the parent
27//! surface (wl_subsurface.set_position), and the stacking order of
28//! the parent and its sub-surfaces (wl_subsurface.place_above and
29//! .place_below). This state is applied when the parent surface's
30//! wl_surface state is applied, regardless of the sub-surface's mode.
31//! As the exception, set_sync and set_desync are effective immediately.
32//!
33//! The main surface can be thought to be always in desynchronized mode,
34//! since it does not have a parent in the sub-surfaces sense.
35//!
36//! Even if a sub-surface is in desynchronized mode, it will behave as
37//! in synchronized mode, if its parent surface behaves as in
38//! synchronized mode. This rule is applied recursively throughout the
39//! tree of surfaces. This means, that one can set a sub-surface into
40//! synchronized mode, and then assume that all its child and grand-child
41//! sub-surfaces are synchronized, too, without explicitly setting them.
42//!
43//! Destroying a sub-surface takes effect immediately. If you need to
44//! synchronize the removal of a sub-surface to the parent surface update,
45//! unmap the sub-surface first by attaching a NULL wl_buffer, update parent,
46//! and then destroy the sub-surface.
47//!
48//! If the parent wl_surface object is destroyed, the sub-surface is
49//! unmapped.
50//!
51//! A sub-surface never has the keyboard focus of any seat.
52//!
53//! The wl_surface.offset request is ignored: clients must use set_position
54//! instead to move the sub-surface.
55
56use {super::super::all_types::*, ::wl_client::builder::prelude::*};
57
58static INTERFACE: wl_interface = wl_interface {
59 name: c"wl_subsurface".as_ptr(),
60 version: 1,
61 method_count: 6,
62 methods: {
63 static MESSAGES: [wl_message; 6] = [
64 wl_message {
65 name: c"destroy".as_ptr(),
66 signature: c"".as_ptr(),
67 types: {
68 static TYPES: [Option<&'static wl_interface>; 0] = [];
69 TYPES.as_ptr().cast()
70 },
71 },
72 wl_message {
73 name: c"set_position".as_ptr(),
74 signature: c"ii".as_ptr(),
75 types: {
76 static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
77 TYPES.as_ptr().cast()
78 },
79 },
80 wl_message {
81 name: c"place_above".as_ptr(),
82 signature: c"o".as_ptr(),
83 types: {
84 static TYPES: [Option<&'static wl_interface>; 1] =
85 [Some(WlSurface::WL_INTERFACE)];
86 TYPES.as_ptr().cast()
87 },
88 },
89 wl_message {
90 name: c"place_below".as_ptr(),
91 signature: c"o".as_ptr(),
92 types: {
93 static TYPES: [Option<&'static wl_interface>; 1] =
94 [Some(WlSurface::WL_INTERFACE)];
95 TYPES.as_ptr().cast()
96 },
97 },
98 wl_message {
99 name: c"set_sync".as_ptr(),
100 signature: c"".as_ptr(),
101 types: {
102 static TYPES: [Option<&'static wl_interface>; 0] = [];
103 TYPES.as_ptr().cast()
104 },
105 },
106 wl_message {
107 name: c"set_desync".as_ptr(),
108 signature: c"".as_ptr(),
109 types: {
110 static TYPES: [Option<&'static wl_interface>; 0] = [];
111 TYPES.as_ptr().cast()
112 },
113 },
114 ];
115 MESSAGES.as_ptr()
116 },
117 event_count: 0,
118 events: ptr::null(),
119};
120
121/// An owned wl_subsurface proxy.
122///
123/// See the documentation of [the module][self] for the interface description.
124#[derive(Clone, Eq, PartialEq)]
125#[repr(transparent)]
126pub struct WlSubsurface {
127 /// This proxy has the interface INTERFACE.
128 proxy: UntypedOwnedProxy,
129}
130
131/// A borrowed wl_subsurface proxy.
132///
133/// See the documentation of [the module][self] for the interface description.
134#[derive(Eq, PartialEq)]
135#[repr(transparent)]
136pub struct WlSubsurfaceRef {
137 /// This proxy has the interface INTERFACE.
138 proxy: UntypedBorrowedProxy,
139}
140
141// SAFETY: WlSubsurface is a transparent wrapper around UntypedOwnedProxy
142unsafe impl UntypedOwnedProxyWrapper for WlSubsurface {}
143
144// SAFETY: - INTERFACE is a valid wl_interface
145// - The only invariant is that self.proxy has a compatible interface
146unsafe impl OwnedProxy for WlSubsurface {
147 const INTERFACE: &'static str = "wl_subsurface";
148 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
149 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
150 private::EventHandler(private::NoOpEventHandler);
151 const MAX_VERSION: u32 = 1;
152
153 type Borrowed = WlSubsurfaceRef;
154 type Api = private::ProxyApi;
155 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
156}
157
158// SAFETY: WlSubsurfaceRef is a transparent wrapper around UntypedBorrowedProxy
159unsafe impl UntypedBorrowedProxyWrapper for WlSubsurfaceRef {}
160
161// SAFETY: - The only invariant is that self.proxy has a compatible interface
162unsafe impl BorrowedProxy for WlSubsurfaceRef {
163 type Owned = WlSubsurface;
164}
165
166impl Deref for WlSubsurface {
167 type Target = WlSubsurfaceRef;
168
169 fn deref(&self) -> &Self::Target {
170 proxy::low_level::deref(self)
171 }
172}
173
174mod private {
175 pub struct ProxyApi;
176
177 #[allow(dead_code)]
178 pub struct EventHandler<H>(pub(super) H);
179
180 #[allow(dead_code)]
181 pub struct NoOpEventHandler;
182}
183
184impl Debug for WlSubsurface {
185 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
186 write!(f, "wl_subsurface#{}", self.proxy.id())
187 }
188}
189
190impl Debug for WlSubsurfaceRef {
191 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
192 write!(f, "wl_subsurface#{}", self.proxy.id())
193 }
194}
195
196impl PartialEq<WlSubsurfaceRef> for WlSubsurface {
197 fn eq(&self, other: &WlSubsurfaceRef) -> bool {
198 self.proxy == other.proxy
199 }
200}
201
202impl PartialEq<WlSubsurface> for WlSubsurfaceRef {
203 fn eq(&self, other: &WlSubsurface) -> bool {
204 self.proxy == other.proxy
205 }
206}
207
208#[allow(dead_code)]
209impl WlSubsurface {
210 /// Since when the destroy request is available.
211 #[allow(dead_code)]
212 pub const REQ__DESTROY__SINCE: u32 = 1;
213
214 /// remove sub-surface interface
215 ///
216 /// The sub-surface interface is removed from the wl_surface object
217 /// that was turned into a sub-surface with a
218 /// wl_subcompositor.get_subsurface request. The wl_surface's association
219 /// to the parent is deleted. The wl_surface is unmapped immediately.
220 #[inline]
221 pub fn destroy(&self) {
222 let mut args = [];
223 // SAFETY: - self.proxy has the interface INTERFACE
224 // - 0 < INTERFACE.method_count = 6
225 // - the request signature is ``
226 unsafe {
227 self.proxy.send_destructor(0, &mut args);
228 }
229 }
230}
231
232#[allow(dead_code)]
233impl WlSubsurfaceRef {
234 /// reposition the sub-surface
235 ///
236 /// This schedules a sub-surface position change.
237 /// The sub-surface will be moved so that its origin (top left
238 /// corner pixel) will be at the location x, y of the parent surface
239 /// coordinate system. The coordinates are not restricted to the parent
240 /// surface area. Negative values are allowed.
241 ///
242 /// The scheduled coordinates will take effect whenever the state of the
243 /// parent surface is applied.
244 ///
245 /// If more than one set_position request is invoked by the client before
246 /// the commit of the parent surface, the position of a new request always
247 /// replaces the scheduled position from any previous request.
248 ///
249 /// The initial position is 0, 0.
250 ///
251 /// # Arguments
252 ///
253 /// - `x`: x coordinate in the parent surface
254 /// - `y`: y coordinate in the parent surface
255 #[inline]
256 pub fn set_position(&self, x: i32, y: i32) {
257 let (arg0, arg1) = (x, y);
258 let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
259 // SAFETY: - self.proxy has the interface INTERFACE
260 // - 1 < INTERFACE.method_count = 6
261 // - the request signature is `ii`
262 unsafe {
263 self.proxy.send_request(1, &mut args);
264 }
265 }
266
267 /// restack the sub-surface
268 ///
269 /// This sub-surface is taken from the stack, and put back just
270 /// above the reference surface, changing the z-order of the sub-surfaces.
271 /// The reference surface must be one of the sibling surfaces, or the
272 /// parent surface. Using any other surface, including this sub-surface,
273 /// will cause a protocol error.
274 ///
275 /// The z-order is double-buffered. Requests are handled in order and
276 /// applied immediately to a pending state. The final pending state is
277 /// copied to the active state the next time the state of the parent
278 /// surface is applied.
279 ///
280 /// A new sub-surface is initially added as the top-most in the stack
281 /// of its siblings and parent.
282 ///
283 /// # Arguments
284 ///
285 /// - `sibling`: the reference surface
286 #[inline]
287 pub fn place_above(&self, sibling: &WlSurfaceRef) {
288 let (arg0,) = (sibling,);
289 let obj0_lock = proxy::lock(arg0);
290 let obj0 = check_argument_proxy("sibling", obj0_lock.wl_proxy());
291 let mut args = [wl_argument { o: obj0 }];
292 // SAFETY: - self.proxy has the interface INTERFACE
293 // - 2 < INTERFACE.method_count = 6
294 // - the request signature is `o`
295 unsafe {
296 self.proxy.send_request(2, &mut args);
297 }
298 }
299
300 /// restack the sub-surface
301 ///
302 /// The sub-surface is placed just below the reference surface.
303 /// See wl_subsurface.place_above.
304 ///
305 /// # Arguments
306 ///
307 /// - `sibling`: the reference surface
308 #[inline]
309 pub fn place_below(&self, sibling: &WlSurfaceRef) {
310 let (arg0,) = (sibling,);
311 let obj0_lock = proxy::lock(arg0);
312 let obj0 = check_argument_proxy("sibling", obj0_lock.wl_proxy());
313 let mut args = [wl_argument { o: obj0 }];
314 // SAFETY: - self.proxy has the interface INTERFACE
315 // - 3 < INTERFACE.method_count = 6
316 // - the request signature is `o`
317 unsafe {
318 self.proxy.send_request(3, &mut args);
319 }
320 }
321
322 /// set sub-surface to synchronized mode
323 ///
324 /// Change the commit behaviour of the sub-surface to synchronized
325 /// mode, also described as the parent dependent mode.
326 ///
327 /// In synchronized mode, wl_surface.commit on a sub-surface will
328 /// accumulate the committed state in a cache, but the state will
329 /// not be applied and hence will not change the compositor output.
330 /// The cached state is applied to the sub-surface immediately after
331 /// the parent surface's state is applied. This ensures atomic
332 /// updates of the parent and all its synchronized sub-surfaces.
333 /// Applying the cached state will invalidate the cache, so further
334 /// parent surface commits do not (re-)apply old state.
335 ///
336 /// See wl_subsurface for the recursive effect of this mode.
337 #[inline]
338 pub fn set_sync(&self) {
339 let mut args = [];
340 // SAFETY: - self.proxy has the interface INTERFACE
341 // - 4 < INTERFACE.method_count = 6
342 // - the request signature is ``
343 unsafe {
344 self.proxy.send_request(4, &mut args);
345 }
346 }
347
348 /// set sub-surface to desynchronized mode
349 ///
350 /// Change the commit behaviour of the sub-surface to desynchronized
351 /// mode, also described as independent or freely running mode.
352 ///
353 /// In desynchronized mode, wl_surface.commit on a sub-surface will
354 /// apply the pending state directly, without caching, as happens
355 /// normally with a wl_surface. Calling wl_surface.commit on the
356 /// parent surface has no effect on the sub-surface's wl_surface
357 /// state. This mode allows a sub-surface to be updated on its own.
358 ///
359 /// If cached state exists when wl_surface.commit is called in
360 /// desynchronized mode, the pending state is added to the cached
361 /// state, and applied as a whole. This invalidates the cache.
362 ///
363 /// Note: even if a sub-surface is set to desynchronized, a parent
364 /// sub-surface may override it to behave as synchronized. For details,
365 /// see wl_subsurface.
366 ///
367 /// If a surface's parent surface behaves as desynchronized, then
368 /// the cached state is applied on set_desync.
369 #[inline]
370 pub fn set_desync(&self) {
371 let mut args = [];
372 // SAFETY: - self.proxy has the interface INTERFACE
373 // - 5 < INTERFACE.method_count = 6
374 // - the request signature is ``
375 unsafe {
376 self.proxy.send_request(5, &mut args);
377 }
378 }
379}
380
381/// An event handler for [WlSubsurface] proxies.
382#[allow(dead_code)]
383pub trait WlSubsurfaceEventHandler {}
384
385impl WlSubsurfaceEventHandler for private::NoOpEventHandler {}
386
387// SAFETY: - INTERFACE is a valid wl_interface
388unsafe impl<H> EventHandler for private::EventHandler<H>
389where
390 H: WlSubsurfaceEventHandler,
391{
392 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
393
394 #[allow(unused_variables)]
395 unsafe fn handle_event(
396 &self,
397 queue: &Queue,
398 data: *mut u8,
399 slf: &UntypedBorrowedProxy,
400 opcode: u32,
401 args: *mut wl_argument,
402 ) {
403 invalid_opcode("wl_subsurface", opcode);
404 }
405}
406
407impl<H> CreateEventHandler<H> for private::ProxyApi
408where
409 H: WlSubsurfaceEventHandler,
410{
411 type EventHandler = private::EventHandler<H>;
412
413 #[inline]
414 fn create_event_handler(handler: H) -> Self::EventHandler {
415 private::EventHandler(handler)
416 }
417}
418
419impl WlSubsurface {
420 /// Since when the error.bad_surface enum variant is available.
421 #[allow(dead_code)]
422 pub const ENM__ERROR_BAD_SURFACE__SINCE: u32 = 1;
423}
424
425#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
426#[allow(dead_code)]
427pub struct WlSubsurfaceError(pub u32);
428
429impl WlSubsurfaceError {
430 /// wl_surface is not a sibling or the parent
431 #[allow(dead_code)]
432 pub const BAD_SURFACE: Self = Self(0);
433}
434
435impl Debug for WlSubsurfaceError {
436 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
437 let name = match *self {
438 Self::BAD_SURFACE => "BAD_SURFACE",
439 _ => return Debug::fmt(&self.0, f),
440 };
441 f.write_str(name)
442 }
443}
444
445/// Functional event handlers.
446pub mod event_handlers {
447 use super::*;
448
449 impl WlSubsurface {}
450}