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}