simple_window/common/protocols_data/xdg_shell/
xdg_surface.rs

1//! desktop user interface surface base interface
2//!
3//! An interface that may be implemented by a wl_surface, for
4//! implementations that provide a desktop-style user interface.
5//!
6//! It provides a base set of functionality required to construct user
7//! interface elements requiring management by the compositor, such as
8//! toplevel windows, menus, etc. The types of functionality are split into
9//! xdg_surface roles.
10//!
11//! Creating an xdg_surface does not set the role for a wl_surface. In order
12//! to map an xdg_surface, the client must create a role-specific object
13//! using, e.g., get_toplevel, get_popup. The wl_surface for any given
14//! xdg_surface can have at most one role, and may not be assigned any role
15//! not based on xdg_surface.
16//!
17//! A role must be assigned before any other requests are made to the
18//! xdg_surface object.
19//!
20//! The client must call wl_surface.commit on the corresponding wl_surface
21//! for the xdg_surface state to take effect.
22//!
23//! Creating an xdg_surface from a wl_surface which has a buffer attached or
24//! committed is a client error, and any attempts by a client to attach or
25//! manipulate a buffer prior to the first xdg_surface.configure call must
26//! also be treated as errors.
27//!
28//! After creating a role-specific object and setting it up (e.g. by sending
29//! the title, app ID, size constraints, parent, etc), the client must
30//! perform an initial commit without any buffer attached. The compositor
31//! will reply with initial wl_surface state such as
32//! wl_surface.preferred_buffer_scale followed by an xdg_surface.configure
33//! event. The client must acknowledge it and is then allowed to attach a
34//! buffer to map the surface.
35//!
36//! Mapping an xdg_surface-based role surface is defined as making it
37//! possible for the surface to be shown by the compositor. Note that
38//! a mapped surface is not guaranteed to be visible once it is mapped.
39//!
40//! For an xdg_surface to be mapped by the compositor, the following
41//! conditions must be met:
42//! (1) the client has assigned an xdg_surface-based role to the surface
43//! (2) the client has set and committed the xdg_surface state and the
44//! 	  role-dependent state to the surface
45//! (3) the client has committed a buffer to the surface
46//!
47//! A newly-unmapped surface is considered to have met condition (1) out
48//! of the 3 required conditions for mapping a surface if its role surface
49//! has not been destroyed, i.e. the client must perform the initial commit
50//! again before attaching a buffer.
51
52use {super::super::all_types::*, ::wl_client::builder::prelude::*};
53
54static INTERFACE: wl_interface = wl_interface {
55    name: c"xdg_surface".as_ptr(),
56    version: 6,
57    method_count: 5,
58    methods: {
59        static MESSAGES: [wl_message; 5] = [
60            wl_message {
61                name: c"destroy".as_ptr(),
62                signature: c"".as_ptr(),
63                types: {
64                    static TYPES: [Option<&'static wl_interface>; 0] = [];
65                    TYPES.as_ptr().cast()
66                },
67            },
68            wl_message {
69                name: c"get_toplevel".as_ptr(),
70                signature: c"n".as_ptr(),
71                types: {
72                    static TYPES: [Option<&'static wl_interface>; 1] =
73                        [Some(XdgToplevel::WL_INTERFACE)];
74                    TYPES.as_ptr().cast()
75                },
76            },
77            wl_message {
78                name: c"get_popup".as_ptr(),
79                signature: c"n?oo".as_ptr(),
80                types: {
81                    static TYPES: [Option<&'static wl_interface>; 3] = [
82                        Some(XdgPopup::WL_INTERFACE),
83                        Some(XdgSurface::WL_INTERFACE),
84                        Some(XdgPositioner::WL_INTERFACE),
85                    ];
86                    TYPES.as_ptr().cast()
87                },
88            },
89            wl_message {
90                name: c"set_window_geometry".as_ptr(),
91                signature: c"iiii".as_ptr(),
92                types: {
93                    static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
94                    TYPES.as_ptr().cast()
95                },
96            },
97            wl_message {
98                name: c"ack_configure".as_ptr(),
99                signature: c"u".as_ptr(),
100                types: {
101                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
102                    TYPES.as_ptr().cast()
103                },
104            },
105        ];
106        MESSAGES.as_ptr()
107    },
108    event_count: 1,
109    events: {
110        static MESSAGES: [wl_message; 1] = [wl_message {
111            name: c"configure".as_ptr(),
112            signature: c"u".as_ptr(),
113            types: {
114                static TYPES: [Option<&'static wl_interface>; 1] = [None];
115                TYPES.as_ptr().cast()
116            },
117        }];
118        MESSAGES.as_ptr()
119    },
120};
121
122/// An owned xdg_surface proxy.
123///
124/// See the documentation of [the module][self] for the interface description.
125#[derive(Clone, Eq, PartialEq)]
126#[repr(transparent)]
127pub struct XdgSurface {
128    /// This proxy has the interface INTERFACE.
129    proxy: UntypedOwnedProxy,
130}
131
132/// A borrowed xdg_surface proxy.
133///
134/// See the documentation of [the module][self] for the interface description.
135#[derive(Eq, PartialEq)]
136#[repr(transparent)]
137pub struct XdgSurfaceRef {
138    /// This proxy has the interface INTERFACE.
139    proxy: UntypedBorrowedProxy,
140}
141
142// SAFETY: XdgSurface is a transparent wrapper around UntypedOwnedProxy
143unsafe impl UntypedOwnedProxyWrapper for XdgSurface {}
144
145// SAFETY: - INTERFACE is a valid wl_interface
146//         - The only invariant is that self.proxy has a compatible interface
147unsafe impl OwnedProxy for XdgSurface {
148    const INTERFACE: &'static str = "xdg_surface";
149    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
150    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
151        private::EventHandler(private::NoOpEventHandler);
152    const MAX_VERSION: u32 = 6;
153
154    type Borrowed = XdgSurfaceRef;
155    type Api = private::ProxyApi;
156    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
157}
158
159// SAFETY: XdgSurfaceRef is a transparent wrapper around UntypedBorrowedProxy
160unsafe impl UntypedBorrowedProxyWrapper for XdgSurfaceRef {}
161
162// SAFETY: - The only invariant is that self.proxy has a compatible interface
163unsafe impl BorrowedProxy for XdgSurfaceRef {
164    type Owned = XdgSurface;
165}
166
167impl Deref for XdgSurface {
168    type Target = XdgSurfaceRef;
169
170    fn deref(&self) -> &Self::Target {
171        proxy::low_level::deref(self)
172    }
173}
174
175mod private {
176    pub struct ProxyApi;
177
178    #[allow(dead_code)]
179    pub struct EventHandler<H>(pub(super) H);
180
181    #[allow(dead_code)]
182    pub struct NoOpEventHandler;
183}
184
185impl Debug for XdgSurface {
186    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
187        write!(f, "xdg_surface#{}", self.proxy.id())
188    }
189}
190
191impl Debug for XdgSurfaceRef {
192    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
193        write!(f, "xdg_surface#{}", self.proxy.id())
194    }
195}
196
197impl PartialEq<XdgSurfaceRef> for XdgSurface {
198    fn eq(&self, other: &XdgSurfaceRef) -> bool {
199        self.proxy == other.proxy
200    }
201}
202
203impl PartialEq<XdgSurface> for XdgSurfaceRef {
204    fn eq(&self, other: &XdgSurface) -> bool {
205        self.proxy == other.proxy
206    }
207}
208
209#[allow(dead_code)]
210impl XdgSurface {
211    /// Since when the destroy request is available.
212    #[allow(dead_code)]
213    pub const REQ__DESTROY__SINCE: u32 = 1;
214
215    /// destroy the xdg_surface
216    ///
217    /// Destroy the xdg_surface object. An xdg_surface must only be destroyed
218    /// after its role object has been destroyed, otherwise
219    /// a defunct_role_object error is raised.
220    #[inline]
221    pub fn destroy(&self) {
222        let mut args = [];
223        // SAFETY: - self.proxy has the interface INTERFACE
224        //         - 0 < INTERFACE.method_count = 5
225        //         - the request signature is ``
226        unsafe {
227            self.proxy.send_destructor(0, &mut args);
228        }
229    }
230
231    /// Since when the get_toplevel request is available.
232    #[allow(dead_code)]
233    pub const REQ__GET_TOPLEVEL__SINCE: u32 = 1;
234
235    /// assign the xdg_toplevel surface role
236    ///
237    /// This creates an xdg_toplevel object for the given xdg_surface and gives
238    /// the associated wl_surface the xdg_toplevel role.
239    ///
240    /// See the documentation of xdg_toplevel for more details about what an
241    /// xdg_toplevel is and how it is used.
242    #[inline]
243    pub fn get_toplevel(&self) -> XdgToplevel {
244        let mut args = [wl_argument { n: 0 }];
245        // SAFETY: - self.proxy has the interface INTERFACE
246        //         - 1 < INTERFACE.method_count = 5
247        //         - the request signature is `n`
248        //         - OwnedProxy::WL_INTERFACE is always a valid interface
249        let data = unsafe {
250            self.proxy
251                .send_constructor::<false>(1, &mut args, XdgToplevel::WL_INTERFACE, None)
252        };
253        // SAFETY: data has the interface XdgToplevel::WL_INTERFACE
254        unsafe { proxy::low_level::from_untyped_owned(data) }
255    }
256
257    /// Since when the get_popup request is available.
258    #[allow(dead_code)]
259    pub const REQ__GET_POPUP__SINCE: u32 = 1;
260
261    /// assign the xdg_popup surface role
262    ///
263    /// This creates an xdg_popup object for the given xdg_surface and gives
264    /// the associated wl_surface the xdg_popup role.
265    ///
266    /// If null is passed as a parent, a parent surface must be specified using
267    /// some other protocol, before committing the initial state.
268    ///
269    /// See the documentation of xdg_popup for more details about what an
270    /// xdg_popup is and how it is used.
271    ///
272    /// # Arguments
273    ///
274    /// - `parent`:
275    /// - `positioner`:
276    #[inline]
277    pub fn get_popup(
278        &self,
279        parent: Option<&XdgSurfaceRef>,
280        positioner: &XdgPositionerRef,
281    ) -> XdgPopup {
282        let (arg1, arg2) = (parent, positioner);
283        let obj1_lock = arg1.map(|arg1| proxy::lock(arg1));
284        let obj1 = obj1_lock
285            .map(|obj1_lock| check_argument_proxy("parent", obj1_lock.wl_proxy()))
286            .unwrap_or(ptr::null_mut());
287        let obj2_lock = proxy::lock(arg2);
288        let obj2 = check_argument_proxy("positioner", obj2_lock.wl_proxy());
289        let mut args = [
290            wl_argument { n: 0 },
291            wl_argument { o: obj1 },
292            wl_argument { o: obj2 },
293        ];
294        // SAFETY: - self.proxy has the interface INTERFACE
295        //         - 2 < INTERFACE.method_count = 5
296        //         - the request signature is `n?oo`
297        //         - OwnedProxy::WL_INTERFACE is always a valid interface
298        let data = unsafe {
299            self.proxy
300                .send_constructor::<false>(2, &mut args, XdgPopup::WL_INTERFACE, None)
301        };
302        // SAFETY: data has the interface XdgPopup::WL_INTERFACE
303        unsafe { proxy::low_level::from_untyped_owned(data) }
304    }
305}
306
307#[allow(dead_code)]
308impl XdgSurfaceRef {
309    /// assign the xdg_toplevel surface role
310    ///
311    /// This creates an xdg_toplevel object for the given xdg_surface and gives
312    /// the associated wl_surface the xdg_toplevel role.
313    ///
314    /// See the documentation of xdg_toplevel for more details about what an
315    /// xdg_toplevel is and how it is used.
316    ///
317    /// # Arguments
318    ///
319    /// - `_queue`: The queue that the returned proxy is assigned to.
320    #[inline]
321    pub fn get_toplevel(&self, _queue: &Queue) -> XdgToplevel {
322        let mut args = [wl_argument { n: 0 }];
323        // SAFETY: - self.proxy has the interface INTERFACE
324        //         - 1 < INTERFACE.method_count = 5
325        //         - the request signature is `n`
326        //         - OwnedProxy::WL_INTERFACE is always a valid interface
327        let data = unsafe {
328            self.proxy
329                .send_constructor(_queue, 1, &mut args, XdgToplevel::WL_INTERFACE, None)
330        };
331        // SAFETY: data has the interface XdgToplevel::WL_INTERFACE
332        unsafe { proxy::low_level::from_untyped_owned(data) }
333    }
334
335    /// assign the xdg_popup surface role
336    ///
337    /// This creates an xdg_popup object for the given xdg_surface and gives
338    /// the associated wl_surface the xdg_popup role.
339    ///
340    /// If null is passed as a parent, a parent surface must be specified using
341    /// some other protocol, before committing the initial state.
342    ///
343    /// See the documentation of xdg_popup for more details about what an
344    /// xdg_popup is and how it is used.
345    ///
346    /// # Arguments
347    ///
348    /// - `_queue`: The queue that the returned proxy is assigned to.
349    /// - `parent`:
350    /// - `positioner`:
351    #[inline]
352    pub fn get_popup(
353        &self,
354        _queue: &Queue,
355        parent: Option<&XdgSurfaceRef>,
356        positioner: &XdgPositionerRef,
357    ) -> XdgPopup {
358        let (arg1, arg2) = (parent, positioner);
359        let obj1_lock = arg1.map(|arg1| proxy::lock(arg1));
360        let obj1 = obj1_lock
361            .map(|obj1_lock| check_argument_proxy("parent", obj1_lock.wl_proxy()))
362            .unwrap_or(ptr::null_mut());
363        let obj2_lock = proxy::lock(arg2);
364        let obj2 = check_argument_proxy("positioner", obj2_lock.wl_proxy());
365        let mut args = [
366            wl_argument { n: 0 },
367            wl_argument { o: obj1 },
368            wl_argument { o: obj2 },
369        ];
370        // SAFETY: - self.proxy has the interface INTERFACE
371        //         - 2 < INTERFACE.method_count = 5
372        //         - the request signature is `n?oo`
373        //         - OwnedProxy::WL_INTERFACE is always a valid interface
374        let data = unsafe {
375            self.proxy
376                .send_constructor(_queue, 2, &mut args, XdgPopup::WL_INTERFACE, None)
377        };
378        // SAFETY: data has the interface XdgPopup::WL_INTERFACE
379        unsafe { proxy::low_level::from_untyped_owned(data) }
380    }
381
382    /// set the new window geometry
383    ///
384    /// The window geometry of a surface is its "visible bounds" from the
385    /// user's perspective. Client-side decorations often have invisible
386    /// portions like drop-shadows which should be ignored for the
387    /// purposes of aligning, placing and constraining windows.
388    ///
389    /// The window geometry is double-buffered state, see wl_surface.commit.
390    ///
391    /// When maintaining a position, the compositor should treat the (x, y)
392    /// coordinate of the window geometry as the top left corner of the window.
393    /// A client changing the (x, y) window geometry coordinate should in
394    /// general not alter the position of the window.
395    ///
396    /// Once the window geometry of the surface is set, it is not possible to
397    /// unset it, and it will remain the same until set_window_geometry is
398    /// called again, even if a new subsurface or buffer is attached.
399    ///
400    /// If never set, the value is the full bounds of the surface,
401    /// including any subsurfaces. This updates dynamically on every
402    /// commit. This unset is meant for extremely simple clients.
403    ///
404    /// The arguments are given in the surface-local coordinate space of
405    /// the wl_surface associated with this xdg_surface, and may extend outside
406    /// of the wl_surface itself to mark parts of the subsurface tree as part of
407    /// the window geometry.
408    ///
409    /// When applied, the effective window geometry will be the set window
410    /// geometry clamped to the bounding rectangle of the combined
411    /// geometry of the surface of the xdg_surface and the associated
412    /// subsurfaces.
413    ///
414    /// The effective geometry will not be recalculated unless a new call to
415    /// set_window_geometry is done and the new pending surface state is
416    /// subsequently applied.
417    ///
418    /// The width and height of the effective window geometry must be
419    /// greater than zero. Setting an invalid size will raise an
420    /// invalid_size error.
421    ///
422    /// # Arguments
423    ///
424    /// - `x`:
425    /// - `y`:
426    /// - `width`:
427    /// - `height`:
428    #[inline]
429    pub fn set_window_geometry(&self, x: i32, y: i32, width: i32, height: i32) {
430        let (arg0, arg1, arg2, arg3) = (x, y, width, height);
431        let mut args = [
432            wl_argument { i: arg0 },
433            wl_argument { i: arg1 },
434            wl_argument { i: arg2 },
435            wl_argument { i: arg3 },
436        ];
437        // SAFETY: - self.proxy has the interface INTERFACE
438        //         - 3 < INTERFACE.method_count = 5
439        //         - the request signature is `iiii`
440        unsafe {
441            self.proxy.send_request(3, &mut args);
442        }
443    }
444
445    /// ack a configure event
446    ///
447    /// When a configure event is received, if a client commits the
448    /// surface in response to the configure event, then the client
449    /// must make an ack_configure request sometime before the commit
450    /// request, passing along the serial of the configure event.
451    ///
452    /// For instance, for toplevel surfaces the compositor might use this
453    /// information to move a surface to the top left only when the client has
454    /// drawn itself for the maximized or fullscreen state.
455    ///
456    /// If the client receives multiple configure events before it
457    /// can respond to one, it only has to ack the last configure event.
458    /// Acking a configure event that was never sent raises an invalid_serial
459    /// error.
460    ///
461    /// A client is not required to commit immediately after sending
462    /// an ack_configure request - it may even ack_configure several times
463    /// before its next surface commit.
464    ///
465    /// A client may send multiple ack_configure requests before committing, but
466    /// only the last request sent before a commit indicates which configure
467    /// event the client really is responding to.
468    ///
469    /// Sending an ack_configure request consumes the serial number sent with
470    /// the request, as well as serial numbers sent by all configure events
471    /// sent on this xdg_surface prior to the configure event referenced by
472    /// the committed serial.
473    ///
474    /// It is an error to issue multiple ack_configure requests referencing a
475    /// serial from the same configure event, or to issue an ack_configure
476    /// request referencing a serial from a configure event issued before the
477    /// event identified by the last ack_configure request for the same
478    /// xdg_surface. Doing so will raise an invalid_serial error.
479    ///
480    /// # Arguments
481    ///
482    /// - `serial`: the serial from the configure event
483    #[inline]
484    pub fn ack_configure(&self, serial: u32) {
485        let (arg0,) = (serial,);
486        let mut args = [wl_argument { u: arg0 }];
487        // SAFETY: - self.proxy has the interface INTERFACE
488        //         - 4 < INTERFACE.method_count = 5
489        //         - the request signature is `u`
490        unsafe {
491            self.proxy.send_request(4, &mut args);
492        }
493    }
494}
495
496impl XdgSurface {
497    /// Since when the configure event is available.
498    #[allow(dead_code)]
499    pub const EVT__CONFIGURE__SINCE: u32 = 1;
500}
501
502/// An event handler for [XdgSurface] proxies.
503#[allow(dead_code)]
504pub trait XdgSurfaceEventHandler {
505    type Data: 'static;
506
507    /// suggest a surface change
508    ///
509    /// The configure event marks the end of a configure sequence. A configure
510    /// sequence is a set of one or more events configuring the state of the
511    /// xdg_surface, including the final xdg_surface.configure event.
512    ///
513    /// Where applicable, xdg_surface surface roles will during a configure
514    /// sequence extend this event as a latched state sent as events before the
515    /// xdg_surface.configure event. Such events should be considered to make up
516    /// a set of atomically applied configuration states, where the
517    /// xdg_surface.configure commits the accumulated state.
518    ///
519    /// Clients should arrange their surface for the new states, and then send
520    /// an ack_configure request with the serial sent in this configure event at
521    /// some point before committing the new surface.
522    ///
523    /// If the client receives multiple configure events before it can respond
524    /// to one, it is free to discard all but the last event it received.
525    ///
526    /// # Arguments
527    ///
528    /// - `serial`: serial of the configure event
529    #[inline]
530    fn configure(&self, _data: &mut Self::Data, _slf: &XdgSurfaceRef, serial: u32) {
531        let _ = serial;
532    }
533}
534
535impl XdgSurfaceEventHandler for private::NoOpEventHandler {
536    type Data = ();
537}
538
539// SAFETY: - INTERFACE is a valid wl_interface
540//         - mutable_type always returns the same value
541unsafe impl<H> EventHandler for private::EventHandler<H>
542where
543    H: XdgSurfaceEventHandler,
544{
545    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
546
547    #[inline]
548    fn mutable_type() -> Option<(TypeId, &'static str)> {
549        let id = TypeId::of::<H::Data>();
550        let name = std::any::type_name::<H::Data>();
551        Some((id, name))
552    }
553
554    #[allow(unused_variables)]
555    unsafe fn handle_event(
556        &self,
557        queue: &Queue,
558        data: *mut u8,
559        slf: &UntypedBorrowedProxy,
560        opcode: u32,
561        args: *mut wl_argument,
562    ) {
563        // SAFETY: This function requires that slf has the interface INTERFACE
564        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<XdgSurfaceRef>(slf) };
565        // SAFETY: This function requires that data is `&mut T` where `T`
566        //         has the type id returned by `Self::mutable_type`, i.e.,
567        //         `T = H::Data`.
568        let data: &mut H::Data = unsafe { &mut *data.cast() };
569        match opcode {
570            0 => {
571                // SAFETY: INTERFACE requires that there are 1 arguments
572                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
573                // SAFETY: - INTERFACE requires that args[0] contains a uint
574                let arg0 = unsafe { args[0].u };
575                self.0.configure(data, slf, arg0);
576            }
577            _ => {
578                invalid_opcode("xdg_surface", opcode);
579            }
580        }
581    }
582}
583
584impl<H> CreateEventHandler<H> for private::ProxyApi
585where
586    H: XdgSurfaceEventHandler,
587{
588    type EventHandler = private::EventHandler<H>;
589
590    #[inline]
591    fn create_event_handler(handler: H) -> Self::EventHandler {
592        private::EventHandler(handler)
593    }
594}
595
596impl XdgSurface {
597    /// Since when the error.not_constructed enum variant is available.
598    #[allow(dead_code)]
599    pub const ENM__ERROR_NOT_CONSTRUCTED__SINCE: u32 = 1;
600    /// Since when the error.already_constructed enum variant is available.
601    #[allow(dead_code)]
602    pub const ENM__ERROR_ALREADY_CONSTRUCTED__SINCE: u32 = 1;
603    /// Since when the error.unconfigured_buffer enum variant is available.
604    #[allow(dead_code)]
605    pub const ENM__ERROR_UNCONFIGURED_BUFFER__SINCE: u32 = 1;
606    /// Since when the error.invalid_serial enum variant is available.
607    #[allow(dead_code)]
608    pub const ENM__ERROR_INVALID_SERIAL__SINCE: u32 = 1;
609    /// Since when the error.invalid_size enum variant is available.
610    #[allow(dead_code)]
611    pub const ENM__ERROR_INVALID_SIZE__SINCE: u32 = 1;
612    /// Since when the error.defunct_role_object enum variant is available.
613    #[allow(dead_code)]
614    pub const ENM__ERROR_DEFUNCT_ROLE_OBJECT__SINCE: u32 = 1;
615}
616
617#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
618#[allow(dead_code)]
619pub struct XdgSurfaceError(pub u32);
620
621impl XdgSurfaceError {
622    /// Surface was not fully constructed
623    #[allow(dead_code)]
624    pub const NOT_CONSTRUCTED: Self = Self(1);
625
626    /// Surface was already constructed
627    #[allow(dead_code)]
628    pub const ALREADY_CONSTRUCTED: Self = Self(2);
629
630    /// Attaching a buffer to an unconfigured surface
631    #[allow(dead_code)]
632    pub const UNCONFIGURED_BUFFER: Self = Self(3);
633
634    /// Invalid serial number when acking a configure event
635    #[allow(dead_code)]
636    pub const INVALID_SERIAL: Self = Self(4);
637
638    /// Width or height was zero or negative
639    #[allow(dead_code)]
640    pub const INVALID_SIZE: Self = Self(5);
641
642    /// Surface was destroyed before its role object
643    #[allow(dead_code)]
644    pub const DEFUNCT_ROLE_OBJECT: Self = Self(6);
645}
646
647impl Debug for XdgSurfaceError {
648    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
649        let name = match *self {
650            Self::NOT_CONSTRUCTED => "NOT_CONSTRUCTED",
651            Self::ALREADY_CONSTRUCTED => "ALREADY_CONSTRUCTED",
652            Self::UNCONFIGURED_BUFFER => "UNCONFIGURED_BUFFER",
653            Self::INVALID_SERIAL => "INVALID_SERIAL",
654            Self::INVALID_SIZE => "INVALID_SIZE",
655            Self::DEFUNCT_ROLE_OBJECT => "DEFUNCT_ROLE_OBJECT",
656            _ => return Debug::fmt(&self.0, f),
657        };
658        f.write_str(name)
659    }
660}
661
662/// Functional event handlers.
663pub mod event_handlers {
664    use super::*;
665
666    /// Event handler for configure events.
667    pub struct Configure<T, F>(F, PhantomData<fn(&mut T)>);
668    impl<T, F> XdgSurfaceEventHandler for Configure<T, F>
669    where
670        T: 'static,
671        F: Fn(&mut T, &XdgSurfaceRef, u32),
672    {
673        type Data = T;
674
675        #[inline]
676        fn configure(&self, _data: &mut T, _slf: &XdgSurfaceRef, serial: u32) {
677            self.0(_data, _slf, serial)
678        }
679    }
680
681    impl XdgSurface {
682        /// Creates an event handler for configure events.
683        ///
684        /// The event handler ignores all other events.
685        #[allow(dead_code)]
686        pub fn on_configure<T, F>(f: F) -> Configure<T, F>
687        where
688            T: 'static,
689            F: Fn(&mut T, &XdgSurfaceRef, u32),
690        {
691            Configure(f, PhantomData)
692        }
693    }
694}