simple_window/common/protocols_data/xdg_shell/
xdg_toplevel.rs

1//! toplevel surface
2//!
3//! This interface defines an xdg_surface role which allows a surface to,
4//! among other things, set window-like properties such as maximize,
5//! fullscreen, and minimize, set application-specific metadata like title and
6//! id, and well as trigger user interactive operations such as interactive
7//! resize and move.
8//!
9//! A xdg_toplevel by default is responsible for providing the full intended
10//! visual representation of the toplevel, which depending on the window
11//! state, may mean things like a title bar, window controls and drop shadow.
12//!
13//! Unmapping an xdg_toplevel means that the surface cannot be shown
14//! by the compositor until it is explicitly mapped again.
15//! All active operations (e.g., move, resize) are canceled and all
16//! attributes (e.g. title, state, stacking, ...) are discarded for
17//! an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
18//! the state it had right after xdg_surface.get_toplevel. The client
19//! can re-map the toplevel by performing a commit without any buffer
20//! attached, waiting for a configure event and handling it as usual (see
21//! xdg_surface description).
22//!
23//! Attaching a null buffer to a toplevel unmaps the surface.
24
25use {super::super::all_types::*, ::wl_client::builder::prelude::*};
26
27static INTERFACE: wl_interface = wl_interface {
28    name: c"xdg_toplevel".as_ptr(),
29    version: 6,
30    method_count: 14,
31    methods: {
32        static MESSAGES: [wl_message; 14] = [
33            wl_message {
34                name: c"destroy".as_ptr(),
35                signature: c"".as_ptr(),
36                types: {
37                    static TYPES: [Option<&'static wl_interface>; 0] = [];
38                    TYPES.as_ptr().cast()
39                },
40            },
41            wl_message {
42                name: c"set_parent".as_ptr(),
43                signature: c"?o".as_ptr(),
44                types: {
45                    static TYPES: [Option<&'static wl_interface>; 1] =
46                        [Some(XdgToplevel::WL_INTERFACE)];
47                    TYPES.as_ptr().cast()
48                },
49            },
50            wl_message {
51                name: c"set_title".as_ptr(),
52                signature: c"s".as_ptr(),
53                types: {
54                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
55                    TYPES.as_ptr().cast()
56                },
57            },
58            wl_message {
59                name: c"set_app_id".as_ptr(),
60                signature: c"s".as_ptr(),
61                types: {
62                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
63                    TYPES.as_ptr().cast()
64                },
65            },
66            wl_message {
67                name: c"show_window_menu".as_ptr(),
68                signature: c"ouii".as_ptr(),
69                types: {
70                    static TYPES: [Option<&'static wl_interface>; 4] =
71                        [Some(WlSeat::WL_INTERFACE), None, None, None];
72                    TYPES.as_ptr().cast()
73                },
74            },
75            wl_message {
76                name: c"move".as_ptr(),
77                signature: c"ou".as_ptr(),
78                types: {
79                    static TYPES: [Option<&'static wl_interface>; 2] =
80                        [Some(WlSeat::WL_INTERFACE), None];
81                    TYPES.as_ptr().cast()
82                },
83            },
84            wl_message {
85                name: c"resize".as_ptr(),
86                signature: c"ouu".as_ptr(),
87                types: {
88                    static TYPES: [Option<&'static wl_interface>; 3] =
89                        [Some(WlSeat::WL_INTERFACE), None, None];
90                    TYPES.as_ptr().cast()
91                },
92            },
93            wl_message {
94                name: c"set_max_size".as_ptr(),
95                signature: c"ii".as_ptr(),
96                types: {
97                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
98                    TYPES.as_ptr().cast()
99                },
100            },
101            wl_message {
102                name: c"set_min_size".as_ptr(),
103                signature: c"ii".as_ptr(),
104                types: {
105                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
106                    TYPES.as_ptr().cast()
107                },
108            },
109            wl_message {
110                name: c"set_maximized".as_ptr(),
111                signature: c"".as_ptr(),
112                types: {
113                    static TYPES: [Option<&'static wl_interface>; 0] = [];
114                    TYPES.as_ptr().cast()
115                },
116            },
117            wl_message {
118                name: c"unset_maximized".as_ptr(),
119                signature: c"".as_ptr(),
120                types: {
121                    static TYPES: [Option<&'static wl_interface>; 0] = [];
122                    TYPES.as_ptr().cast()
123                },
124            },
125            wl_message {
126                name: c"set_fullscreen".as_ptr(),
127                signature: c"?o".as_ptr(),
128                types: {
129                    static TYPES: [Option<&'static wl_interface>; 1] =
130                        [Some(WlOutput::WL_INTERFACE)];
131                    TYPES.as_ptr().cast()
132                },
133            },
134            wl_message {
135                name: c"unset_fullscreen".as_ptr(),
136                signature: c"".as_ptr(),
137                types: {
138                    static TYPES: [Option<&'static wl_interface>; 0] = [];
139                    TYPES.as_ptr().cast()
140                },
141            },
142            wl_message {
143                name: c"set_minimized".as_ptr(),
144                signature: c"".as_ptr(),
145                types: {
146                    static TYPES: [Option<&'static wl_interface>; 0] = [];
147                    TYPES.as_ptr().cast()
148                },
149            },
150        ];
151        MESSAGES.as_ptr()
152    },
153    event_count: 4,
154    events: {
155        static MESSAGES: [wl_message; 4] = [
156            wl_message {
157                name: c"configure".as_ptr(),
158                signature: c"iia".as_ptr(),
159                types: {
160                    static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
161                    TYPES.as_ptr().cast()
162                },
163            },
164            wl_message {
165                name: c"close".as_ptr(),
166                signature: c"".as_ptr(),
167                types: {
168                    static TYPES: [Option<&'static wl_interface>; 0] = [];
169                    TYPES.as_ptr().cast()
170                },
171            },
172            wl_message {
173                name: c"configure_bounds".as_ptr(),
174                signature: c"ii".as_ptr(),
175                types: {
176                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
177                    TYPES.as_ptr().cast()
178                },
179            },
180            wl_message {
181                name: c"wm_capabilities".as_ptr(),
182                signature: c"a".as_ptr(),
183                types: {
184                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
185                    TYPES.as_ptr().cast()
186                },
187            },
188        ];
189        MESSAGES.as_ptr()
190    },
191};
192
193/// An owned xdg_toplevel proxy.
194///
195/// See the documentation of [the module][self] for the interface description.
196#[derive(Clone, Eq, PartialEq)]
197#[repr(transparent)]
198pub struct XdgToplevel {
199    /// This proxy has the interface INTERFACE.
200    proxy: UntypedOwnedProxy,
201}
202
203/// A borrowed xdg_toplevel proxy.
204///
205/// See the documentation of [the module][self] for the interface description.
206#[derive(Eq, PartialEq)]
207#[repr(transparent)]
208pub struct XdgToplevelRef {
209    /// This proxy has the interface INTERFACE.
210    proxy: UntypedBorrowedProxy,
211}
212
213// SAFETY: XdgToplevel is a transparent wrapper around UntypedOwnedProxy
214unsafe impl UntypedOwnedProxyWrapper for XdgToplevel {}
215
216// SAFETY: - INTERFACE is a valid wl_interface
217//         - The only invariant is that self.proxy has a compatible interface
218unsafe impl OwnedProxy for XdgToplevel {
219    const INTERFACE: &'static str = "xdg_toplevel";
220    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
221    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
222        private::EventHandler(private::NoOpEventHandler);
223    const MAX_VERSION: u32 = 6;
224
225    type Borrowed = XdgToplevelRef;
226    type Api = private::ProxyApi;
227    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
228}
229
230// SAFETY: XdgToplevelRef is a transparent wrapper around UntypedBorrowedProxy
231unsafe impl UntypedBorrowedProxyWrapper for XdgToplevelRef {}
232
233// SAFETY: - The only invariant is that self.proxy has a compatible interface
234unsafe impl BorrowedProxy for XdgToplevelRef {
235    type Owned = XdgToplevel;
236}
237
238impl Deref for XdgToplevel {
239    type Target = XdgToplevelRef;
240
241    fn deref(&self) -> &Self::Target {
242        proxy::low_level::deref(self)
243    }
244}
245
246mod private {
247    pub struct ProxyApi;
248
249    #[allow(dead_code)]
250    pub struct EventHandler<H>(pub(super) H);
251
252    #[allow(dead_code)]
253    pub struct NoOpEventHandler;
254}
255
256impl Debug for XdgToplevel {
257    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
258        write!(f, "xdg_toplevel#{}", self.proxy.id())
259    }
260}
261
262impl Debug for XdgToplevelRef {
263    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
264        write!(f, "xdg_toplevel#{}", self.proxy.id())
265    }
266}
267
268impl PartialEq<XdgToplevelRef> for XdgToplevel {
269    fn eq(&self, other: &XdgToplevelRef) -> bool {
270        self.proxy == other.proxy
271    }
272}
273
274impl PartialEq<XdgToplevel> for XdgToplevelRef {
275    fn eq(&self, other: &XdgToplevel) -> bool {
276        self.proxy == other.proxy
277    }
278}
279
280#[allow(dead_code)]
281impl XdgToplevel {
282    /// Since when the destroy request is available.
283    #[allow(dead_code)]
284    pub const REQ__DESTROY__SINCE: u32 = 1;
285
286    /// destroy the xdg_toplevel
287    ///
288    /// This request destroys the role surface and unmaps the surface;
289    /// see "Unmapping" behavior in interface section for details.
290    #[inline]
291    pub fn destroy(&self) {
292        let mut args = [];
293        // SAFETY: - self.proxy has the interface INTERFACE
294        //         - 0 < INTERFACE.method_count = 14
295        //         - the request signature is ``
296        unsafe {
297            self.proxy.send_destructor(0, &mut args);
298        }
299    }
300}
301
302#[allow(dead_code)]
303impl XdgToplevelRef {
304    /// set the parent of this surface
305    ///
306    /// Set the "parent" of this surface. This surface should be stacked
307    /// above the parent surface and all other ancestor surfaces.
308    ///
309    /// Parent surfaces should be set on dialogs, toolboxes, or other
310    /// "auxiliary" surfaces, so that the parent is raised when the dialog
311    /// is raised.
312    ///
313    /// Setting a null parent for a child surface unsets its parent. Setting
314    /// a null parent for a surface which currently has no parent is a no-op.
315    ///
316    /// Only mapped surfaces can have child surfaces. Setting a parent which
317    /// is not mapped is equivalent to setting a null parent. If a surface
318    /// becomes unmapped, its children's parent is set to the parent of
319    /// the now-unmapped surface. If the now-unmapped surface has no parent,
320    /// its children's parent is unset. If the now-unmapped surface becomes
321    /// mapped again, its parent-child relationship is not restored.
322    ///
323    /// The parent toplevel must not be one of the child toplevel's
324    /// descendants, and the parent must be different from the child toplevel,
325    /// otherwise the invalid_parent protocol error is raised.
326    ///
327    /// # Arguments
328    ///
329    /// - `parent`:
330    #[inline]
331    pub fn set_parent(&self, parent: Option<&XdgToplevelRef>) {
332        let (arg0,) = (parent,);
333        let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
334        let obj0 = obj0_lock
335            .map(|obj0_lock| check_argument_proxy("parent", obj0_lock.wl_proxy()))
336            .unwrap_or(ptr::null_mut());
337        let mut args = [wl_argument { o: obj0 }];
338        // SAFETY: - self.proxy has the interface INTERFACE
339        //         - 1 < INTERFACE.method_count = 14
340        //         - the request signature is `?o`
341        unsafe {
342            self.proxy.send_request(1, &mut args);
343        }
344    }
345
346    /// set surface title
347    ///
348    /// Set a short title for the surface.
349    ///
350    /// This string may be used to identify the surface in a task bar,
351    /// window list, or other user interface elements provided by the
352    /// compositor.
353    ///
354    /// The string must be encoded in UTF-8.
355    ///
356    /// # Arguments
357    ///
358    /// - `title`:
359    #[inline]
360    pub fn set_title(&self, title: &str) {
361        let (arg0,) = (title,);
362        with_cstr_cache(|cache| {
363            let str0_offset = cache.len();
364            cache.extend_from_slice(arg0.as_bytes());
365            cache.push(0);
366            let str0 = cache[str0_offset..].as_ptr().cast();
367            let mut args = [wl_argument { s: str0 }];
368            // SAFETY: - self.proxy has the interface INTERFACE
369            //         - 2 < INTERFACE.method_count = 14
370            //         - the request signature is `s`
371            unsafe {
372                self.proxy.send_request(2, &mut args);
373            }
374        })
375    }
376
377    /// set application ID
378    ///
379    /// Set an application identifier for the surface.
380    ///
381    /// The app ID identifies the general class of applications to which
382    /// the surface belongs. The compositor can use this to group multiple
383    /// surfaces together, or to determine how to launch a new application.
384    ///
385    /// For D-Bus activatable applications, the app ID is used as the D-Bus
386    /// service name.
387    ///
388    /// The compositor shell will try to group application surfaces together
389    /// by their app ID. As a best practice, it is suggested to select app
390    /// ID's that match the basename of the application's .desktop file.
391    /// For example, "org.freedesktop.FooViewer" where the .desktop file is
392    /// "org.freedesktop.FooViewer.desktop".
393    ///
394    /// Like other properties, a set_app_id request can be sent after the
395    /// xdg_toplevel has been mapped to update the property.
396    ///
397    /// See the desktop-entry specification [0] for more details on
398    /// application identifiers and how they relate to well-known D-Bus
399    /// names and .desktop files.
400    ///
401    /// [0] https://standards.freedesktop.org/desktop-entry-spec/
402    ///
403    /// # Arguments
404    ///
405    /// - `app_id`:
406    #[inline]
407    pub fn set_app_id(&self, app_id: &str) {
408        let (arg0,) = (app_id,);
409        with_cstr_cache(|cache| {
410            let str0_offset = cache.len();
411            cache.extend_from_slice(arg0.as_bytes());
412            cache.push(0);
413            let str0 = cache[str0_offset..].as_ptr().cast();
414            let mut args = [wl_argument { s: str0 }];
415            // SAFETY: - self.proxy has the interface INTERFACE
416            //         - 3 < INTERFACE.method_count = 14
417            //         - the request signature is `s`
418            unsafe {
419                self.proxy.send_request(3, &mut args);
420            }
421        })
422    }
423
424    /// show the window menu
425    ///
426    /// Clients implementing client-side decorations might want to show
427    /// a context menu when right-clicking on the decorations, giving the
428    /// user a menu that they can use to maximize or minimize the window.
429    ///
430    /// This request asks the compositor to pop up such a window menu at
431    /// the given position, relative to the local surface coordinates of
432    /// the parent surface. There are no guarantees as to what menu items
433    /// the window menu contains, or even if a window menu will be drawn
434    /// at all.
435    ///
436    /// This request must be used in response to some sort of user action
437    /// like a button press, key press, or touch down event.
438    ///
439    /// # Arguments
440    ///
441    /// - `seat`: the wl_seat of the user event
442    /// - `serial`: the serial of the user event
443    /// - `x`: the x position to pop up the window menu at
444    /// - `y`: the y position to pop up the window menu at
445    #[inline]
446    pub fn show_window_menu(&self, seat: &WlSeatRef, serial: u32, x: i32, y: i32) {
447        let (arg0, arg1, arg2, arg3) = (seat, serial, x, y);
448        let obj0_lock = proxy::lock(arg0);
449        let obj0 = check_argument_proxy("seat", obj0_lock.wl_proxy());
450        let mut args = [
451            wl_argument { o: obj0 },
452            wl_argument { u: arg1 },
453            wl_argument { i: arg2 },
454            wl_argument { i: arg3 },
455        ];
456        // SAFETY: - self.proxy has the interface INTERFACE
457        //         - 4 < INTERFACE.method_count = 14
458        //         - the request signature is `ouii`
459        unsafe {
460            self.proxy.send_request(4, &mut args);
461        }
462    }
463
464    /// start an interactive move
465    ///
466    /// Start an interactive, user-driven move of the surface.
467    ///
468    /// This request must be used in response to some sort of user action
469    /// like a button press, key press, or touch down event. The passed
470    /// serial is used to determine the type of interactive move (touch,
471    /// pointer, etc).
472    ///
473    /// The server may ignore move requests depending on the state of
474    /// the surface (e.g. fullscreen or maximized), or if the passed serial
475    /// is no longer valid.
476    ///
477    /// If triggered, the surface will lose the focus of the device
478    /// (wl_pointer, wl_touch, etc) used for the move. It is up to the
479    /// compositor to visually indicate that the move is taking place, such as
480    /// updating a pointer cursor, during the move. There is no guarantee
481    /// that the device focus will return when the move is completed.
482    ///
483    /// # Arguments
484    ///
485    /// - `seat`: the wl_seat of the user event
486    /// - `serial`: the serial of the user event
487    #[inline]
488    pub fn r#move(&self, seat: &WlSeatRef, serial: u32) {
489        let (arg0, arg1) = (seat, serial);
490        let obj0_lock = proxy::lock(arg0);
491        let obj0 = check_argument_proxy("seat", obj0_lock.wl_proxy());
492        let mut args = [wl_argument { o: obj0 }, wl_argument { u: arg1 }];
493        // SAFETY: - self.proxy has the interface INTERFACE
494        //         - 5 < INTERFACE.method_count = 14
495        //         - the request signature is `ou`
496        unsafe {
497            self.proxy.send_request(5, &mut args);
498        }
499    }
500
501    /// start an interactive resize
502    ///
503    /// Start a user-driven, interactive resize of the surface.
504    ///
505    /// This request must be used in response to some sort of user action
506    /// like a button press, key press, or touch down event. The passed
507    /// serial is used to determine the type of interactive resize (touch,
508    /// pointer, etc).
509    ///
510    /// The server may ignore resize requests depending on the state of
511    /// the surface (e.g. fullscreen or maximized).
512    ///
513    /// If triggered, the client will receive configure events with the
514    /// "resize" state enum value and the expected sizes. See the "resize"
515    /// enum value for more details about what is required. The client
516    /// must also acknowledge configure events using "ack_configure". After
517    /// the resize is completed, the client will receive another "configure"
518    /// event without the resize state.
519    ///
520    /// If triggered, the surface also will lose the focus of the device
521    /// (wl_pointer, wl_touch, etc) used for the resize. It is up to the
522    /// compositor to visually indicate that the resize is taking place,
523    /// such as updating a pointer cursor, during the resize. There is no
524    /// guarantee that the device focus will return when the resize is
525    /// completed.
526    ///
527    /// The edges parameter specifies how the surface should be resized, and
528    /// is one of the values of the resize_edge enum. Values not matching
529    /// a variant of the enum will cause the invalid_resize_edge protocol error.
530    /// The compositor may use this information to update the surface position
531    /// for example when dragging the top left corner. The compositor may also
532    /// use this information to adapt its behavior, e.g. choose an appropriate
533    /// cursor image.
534    ///
535    /// # Arguments
536    ///
537    /// - `seat`: the wl_seat of the user event
538    /// - `serial`: the serial of the user event
539    /// - `edges`: which edge or corner is being dragged
540    #[inline]
541    pub fn resize(&self, seat: &WlSeatRef, serial: u32, edges: XdgToplevelResizeEdge) {
542        let (arg0, arg1, arg2) = (seat, serial, edges);
543        let obj0_lock = proxy::lock(arg0);
544        let obj0 = check_argument_proxy("seat", obj0_lock.wl_proxy());
545        let mut args = [
546            wl_argument { o: obj0 },
547            wl_argument { u: arg1 },
548            wl_argument { u: arg2.0 },
549        ];
550        // SAFETY: - self.proxy has the interface INTERFACE
551        //         - 6 < INTERFACE.method_count = 14
552        //         - the request signature is `ouu`
553        unsafe {
554            self.proxy.send_request(6, &mut args);
555        }
556    }
557
558    /// set the maximum size
559    ///
560    /// Set a maximum size for the window.
561    ///
562    /// The client can specify a maximum size so that the compositor does
563    /// not try to configure the window beyond this size.
564    ///
565    /// The width and height arguments are in window geometry coordinates.
566    /// See xdg_surface.set_window_geometry.
567    ///
568    /// Values set in this way are double-buffered, see wl_surface.commit.
569    ///
570    /// The compositor can use this information to allow or disallow
571    /// different states like maximize or fullscreen and draw accurate
572    /// animations.
573    ///
574    /// Similarly, a tiling window manager may use this information to
575    /// place and resize client windows in a more effective way.
576    ///
577    /// The client should not rely on the compositor to obey the maximum
578    /// size. The compositor may decide to ignore the values set by the
579    /// client and request a larger size.
580    ///
581    /// If never set, or a value of zero in the request, means that the
582    /// client has no expected maximum size in the given dimension.
583    /// As a result, a client wishing to reset the maximum size
584    /// to an unspecified state can use zero for width and height in the
585    /// request.
586    ///
587    /// Requesting a maximum size to be smaller than the minimum size of
588    /// a surface is illegal and will result in an invalid_size error.
589    ///
590    /// The width and height must be greater than or equal to zero. Using
591    /// strictly negative values for width or height will result in a
592    /// invalid_size error.
593    ///
594    /// # Arguments
595    ///
596    /// - `width`:
597    /// - `height`:
598    #[inline]
599    pub fn set_max_size(&self, width: i32, height: i32) {
600        let (arg0, arg1) = (width, height);
601        let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
602        // SAFETY: - self.proxy has the interface INTERFACE
603        //         - 7 < INTERFACE.method_count = 14
604        //         - the request signature is `ii`
605        unsafe {
606            self.proxy.send_request(7, &mut args);
607        }
608    }
609
610    /// set the minimum size
611    ///
612    /// Set a minimum size for the window.
613    ///
614    /// The client can specify a minimum size so that the compositor does
615    /// not try to configure the window below this size.
616    ///
617    /// The width and height arguments are in window geometry coordinates.
618    /// See xdg_surface.set_window_geometry.
619    ///
620    /// Values set in this way are double-buffered, see wl_surface.commit.
621    ///
622    /// The compositor can use this information to allow or disallow
623    /// different states like maximize or fullscreen and draw accurate
624    /// animations.
625    ///
626    /// Similarly, a tiling window manager may use this information to
627    /// place and resize client windows in a more effective way.
628    ///
629    /// The client should not rely on the compositor to obey the minimum
630    /// size. The compositor may decide to ignore the values set by the
631    /// client and request a smaller size.
632    ///
633    /// If never set, or a value of zero in the request, means that the
634    /// client has no expected minimum size in the given dimension.
635    /// As a result, a client wishing to reset the minimum size
636    /// to an unspecified state can use zero for width and height in the
637    /// request.
638    ///
639    /// Requesting a minimum size to be larger than the maximum size of
640    /// a surface is illegal and will result in an invalid_size error.
641    ///
642    /// The width and height must be greater than or equal to zero. Using
643    /// strictly negative values for width and height will result in a
644    /// invalid_size error.
645    ///
646    /// # Arguments
647    ///
648    /// - `width`:
649    /// - `height`:
650    #[inline]
651    pub fn set_min_size(&self, width: i32, height: i32) {
652        let (arg0, arg1) = (width, height);
653        let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
654        // SAFETY: - self.proxy has the interface INTERFACE
655        //         - 8 < INTERFACE.method_count = 14
656        //         - the request signature is `ii`
657        unsafe {
658            self.proxy.send_request(8, &mut args);
659        }
660    }
661
662    /// maximize the window
663    ///
664    /// Maximize the surface.
665    ///
666    /// After requesting that the surface should be maximized, the compositor
667    /// will respond by emitting a configure event. Whether this configure
668    /// actually sets the window maximized is subject to compositor policies.
669    /// The client must then update its content, drawing in the configured
670    /// state. The client must also acknowledge the configure when committing
671    /// the new content (see ack_configure).
672    ///
673    /// It is up to the compositor to decide how and where to maximize the
674    /// surface, for example which output and what region of the screen should
675    /// be used.
676    ///
677    /// If the surface was already maximized, the compositor will still emit
678    /// a configure event with the "maximized" state.
679    ///
680    /// If the surface is in a fullscreen state, this request has no direct
681    /// effect. It may alter the state the surface is returned to when
682    /// unmaximized unless overridden by the compositor.
683    #[inline]
684    pub fn set_maximized(&self) {
685        let mut args = [];
686        // SAFETY: - self.proxy has the interface INTERFACE
687        //         - 9 < INTERFACE.method_count = 14
688        //         - the request signature is ``
689        unsafe {
690            self.proxy.send_request(9, &mut args);
691        }
692    }
693
694    /// unmaximize the window
695    ///
696    /// Unmaximize the surface.
697    ///
698    /// After requesting that the surface should be unmaximized, the compositor
699    /// will respond by emitting a configure event. Whether this actually
700    /// un-maximizes the window is subject to compositor policies.
701    /// If available and applicable, the compositor will include the window
702    /// geometry dimensions the window had prior to being maximized in the
703    /// configure event. The client must then update its content, drawing it in
704    /// the configured state. The client must also acknowledge the configure
705    /// when committing the new content (see ack_configure).
706    ///
707    /// It is up to the compositor to position the surface after it was
708    /// unmaximized; usually the position the surface had before maximizing, if
709    /// applicable.
710    ///
711    /// If the surface was already not maximized, the compositor will still
712    /// emit a configure event without the "maximized" state.
713    ///
714    /// If the surface is in a fullscreen state, this request has no direct
715    /// effect. It may alter the state the surface is returned to when
716    /// unmaximized unless overridden by the compositor.
717    #[inline]
718    pub fn unset_maximized(&self) {
719        let mut args = [];
720        // SAFETY: - self.proxy has the interface INTERFACE
721        //         - 10 < INTERFACE.method_count = 14
722        //         - the request signature is ``
723        unsafe {
724            self.proxy.send_request(10, &mut args);
725        }
726    }
727
728    /// set the window as fullscreen on an output
729    ///
730    /// Make the surface fullscreen.
731    ///
732    /// After requesting that the surface should be fullscreened, the
733    /// compositor will respond by emitting a configure event. Whether the
734    /// client is actually put into a fullscreen state is subject to compositor
735    /// policies. The client must also acknowledge the configure when
736    /// committing the new content (see ack_configure).
737    ///
738    /// The output passed by the request indicates the client's preference as
739    /// to which display it should be set fullscreen on. If this value is NULL,
740    /// it's up to the compositor to choose which display will be used to map
741    /// this surface.
742    ///
743    /// If the surface doesn't cover the whole output, the compositor will
744    /// position the surface in the center of the output and compensate with
745    /// with border fill covering the rest of the output. The content of the
746    /// border fill is undefined, but should be assumed to be in some way that
747    /// attempts to blend into the surrounding area (e.g. solid black).
748    ///
749    /// If the fullscreened surface is not opaque, the compositor must make
750    /// sure that other screen content not part of the same surface tree (made
751    /// up of subsurfaces, popups or similarly coupled surfaces) are not
752    /// visible below the fullscreened surface.
753    ///
754    /// # Arguments
755    ///
756    /// - `output`:
757    #[inline]
758    pub fn set_fullscreen(&self, output: Option<&WlOutputRef>) {
759        let (arg0,) = (output,);
760        let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
761        let obj0 = obj0_lock
762            .map(|obj0_lock| check_argument_proxy("output", obj0_lock.wl_proxy()))
763            .unwrap_or(ptr::null_mut());
764        let mut args = [wl_argument { o: obj0 }];
765        // SAFETY: - self.proxy has the interface INTERFACE
766        //         - 11 < INTERFACE.method_count = 14
767        //         - the request signature is `?o`
768        unsafe {
769            self.proxy.send_request(11, &mut args);
770        }
771    }
772
773    /// unset the window as fullscreen
774    ///
775    /// Make the surface no longer fullscreen.
776    ///
777    /// After requesting that the surface should be unfullscreened, the
778    /// compositor will respond by emitting a configure event.
779    /// Whether this actually removes the fullscreen state of the client is
780    /// subject to compositor policies.
781    ///
782    /// Making a surface unfullscreen sets states for the surface based on the following:
783    /// * the state(s) it may have had before becoming fullscreen
784    /// * any state(s) decided by the compositor
785    /// * any state(s) requested by the client while the surface was fullscreen
786    ///
787    /// The compositor may include the previous window geometry dimensions in
788    /// the configure event, if applicable.
789    ///
790    /// The client must also acknowledge the configure when committing the new
791    /// content (see ack_configure).
792    #[inline]
793    pub fn unset_fullscreen(&self) {
794        let mut args = [];
795        // SAFETY: - self.proxy has the interface INTERFACE
796        //         - 12 < INTERFACE.method_count = 14
797        //         - the request signature is ``
798        unsafe {
799            self.proxy.send_request(12, &mut args);
800        }
801    }
802
803    /// set the window as minimized
804    ///
805    /// Request that the compositor minimize your surface. There is no
806    /// way to know if the surface is currently minimized, nor is there
807    /// any way to unset minimization on this surface.
808    ///
809    /// If you are looking to throttle redrawing when minimized, please
810    /// instead use the wl_surface.frame event for this, as this will
811    /// also work with live previews on windows in Alt-Tab, Expose or
812    /// similar compositor features.
813    #[inline]
814    pub fn set_minimized(&self) {
815        let mut args = [];
816        // SAFETY: - self.proxy has the interface INTERFACE
817        //         - 13 < INTERFACE.method_count = 14
818        //         - the request signature is ``
819        unsafe {
820            self.proxy.send_request(13, &mut args);
821        }
822    }
823}
824
825impl XdgToplevel {
826    /// Since when the configure event is available.
827    #[allow(dead_code)]
828    pub const EVT__CONFIGURE__SINCE: u32 = 1;
829
830    /// Since when the close event is available.
831    #[allow(dead_code)]
832    pub const EVT__CLOSE__SINCE: u32 = 1;
833
834    /// Since when the configure_bounds event is available.
835    #[allow(dead_code)]
836    pub const EVT__CONFIGURE_BOUNDS__SINCE: u32 = 4;
837
838    /// Since when the wm_capabilities event is available.
839    #[allow(dead_code)]
840    pub const EVT__WM_CAPABILITIES__SINCE: u32 = 5;
841}
842
843/// An event handler for [XdgToplevel] proxies.
844#[allow(dead_code)]
845pub trait XdgToplevelEventHandler {
846    type Data: 'static;
847
848    /// suggest a surface change
849    ///
850    /// This configure event asks the client to resize its toplevel surface or
851    /// to change its state. The configured state should not be applied
852    /// immediately. See xdg_surface.configure for details.
853    ///
854    /// The width and height arguments specify a hint to the window
855    /// about how its surface should be resized in window geometry
856    /// coordinates. See set_window_geometry.
857    ///
858    /// If the width or height arguments are zero, it means the client
859    /// should decide its own window dimension. This may happen when the
860    /// compositor needs to configure the state of the surface but doesn't
861    /// have any information about any previous or expected dimension.
862    ///
863    /// The states listed in the event specify how the width/height
864    /// arguments should be interpreted, and possibly how it should be
865    /// drawn.
866    ///
867    /// Clients must send an ack_configure in response to this event. See
868    /// xdg_surface.configure and xdg_surface.ack_configure for details.
869    ///
870    /// # Arguments
871    ///
872    /// - `width`:
873    /// - `height`:
874    /// - `states`:
875    #[inline]
876    fn configure(
877        &self,
878        _data: &mut Self::Data,
879        _slf: &XdgToplevelRef,
880        width: i32,
881        height: i32,
882        states: &[u8],
883    ) {
884        let _ = width;
885        let _ = height;
886        let _ = states;
887    }
888
889    /// surface wants to be closed
890    ///
891    /// The close event is sent by the compositor when the user
892    /// wants the surface to be closed. This should be equivalent to
893    /// the user clicking the close button in client-side decorations,
894    /// if your application has any.
895    ///
896    /// This is only a request that the user intends to close the
897    /// window. The client may choose to ignore this request, or show
898    /// a dialog to ask the user to save their data, etc.
899    #[inline]
900    fn close(&self, _data: &mut Self::Data, _slf: &XdgToplevelRef) {}
901
902    /// recommended window geometry bounds
903    ///
904    /// The configure_bounds event may be sent prior to a xdg_toplevel.configure
905    /// event to communicate the bounds a window geometry size is recommended
906    /// to constrain to.
907    ///
908    /// The passed width and height are in surface coordinate space. If width
909    /// and height are 0, it means bounds is unknown and equivalent to as if no
910    /// configure_bounds event was ever sent for this surface.
911    ///
912    /// The bounds can for example correspond to the size of a monitor excluding
913    /// any panels or other shell components, so that a surface isn't created in
914    /// a way that it cannot fit.
915    ///
916    /// The bounds may change at any point, and in such a case, a new
917    /// xdg_toplevel.configure_bounds will be sent, followed by
918    /// xdg_toplevel.configure and xdg_surface.configure.
919    ///
920    /// # Arguments
921    ///
922    /// - `width`:
923    /// - `height`:
924    #[inline]
925    fn configure_bounds(
926        &self,
927        _data: &mut Self::Data,
928        _slf: &XdgToplevelRef,
929        width: i32,
930        height: i32,
931    ) {
932        let _ = width;
933        let _ = height;
934    }
935
936    /// compositor capabilities
937    ///
938    /// This event advertises the capabilities supported by the compositor. If
939    /// a capability isn't supported, clients should hide or disable the UI
940    /// elements that expose this functionality. For instance, if the
941    /// compositor doesn't advertise support for minimized toplevels, a button
942    /// triggering the set_minimized request should not be displayed.
943    ///
944    /// The compositor will ignore requests it doesn't support. For instance,
945    /// a compositor which doesn't advertise support for minimized will ignore
946    /// set_minimized requests.
947    ///
948    /// Compositors must send this event once before the first
949    /// xdg_surface.configure event. When the capabilities change, compositors
950    /// must send this event again and then send an xdg_surface.configure
951    /// event.
952    ///
953    /// The configured state should not be applied immediately. See
954    /// xdg_surface.configure for details.
955    ///
956    /// The capabilities are sent as an array of 32-bit unsigned integers in
957    /// native endianness.
958    ///
959    /// # Arguments
960    ///
961    /// - `capabilities`: array of 32-bit capabilities
962    #[inline]
963    fn wm_capabilities(&self, _data: &mut Self::Data, _slf: &XdgToplevelRef, capabilities: &[u8]) {
964        let _ = capabilities;
965    }
966}
967
968impl XdgToplevelEventHandler for private::NoOpEventHandler {
969    type Data = ();
970}
971
972// SAFETY: - INTERFACE is a valid wl_interface
973//         - mutable_type always returns the same value
974unsafe impl<H> EventHandler for private::EventHandler<H>
975where
976    H: XdgToplevelEventHandler,
977{
978    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
979
980    #[inline]
981    fn mutable_type() -> Option<(TypeId, &'static str)> {
982        let id = TypeId::of::<H::Data>();
983        let name = std::any::type_name::<H::Data>();
984        Some((id, name))
985    }
986
987    #[allow(unused_variables)]
988    unsafe fn handle_event(
989        &self,
990        queue: &Queue,
991        data: *mut u8,
992        slf: &UntypedBorrowedProxy,
993        opcode: u32,
994        args: *mut wl_argument,
995    ) {
996        // SAFETY: This function requires that slf has the interface INTERFACE
997        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<XdgToplevelRef>(slf) };
998        // SAFETY: This function requires that data is `&mut T` where `T`
999        //         has the type id returned by `Self::mutable_type`, i.e.,
1000        //         `T = H::Data`.
1001        let data: &mut H::Data = unsafe { &mut *data.cast() };
1002        match opcode {
1003            0 => {
1004                // SAFETY: INTERFACE requires that there are 3 arguments
1005                let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
1006                // SAFETY: - INTERFACE requires that args[0] contains an int
1007                let arg0 = unsafe { args[0].i };
1008                // SAFETY: - INTERFACE requires that args[1] contains an int
1009                let arg1 = unsafe { args[1].i };
1010                // SAFETY: - INTERFACE requires that args[2] contains an array
1011                let arg2 = unsafe {
1012                    let a = &*args[2].a;
1013                    std::slice::from_raw_parts(a.data.cast(), a.size)
1014                };
1015                self.0.configure(data, slf, arg0, arg1, arg2);
1016            }
1017            1 => {
1018                self.0.close(data, slf);
1019            }
1020            2 => {
1021                // SAFETY: INTERFACE requires that there are 2 arguments
1022                let args = unsafe { &*args.cast::<[wl_argument; 2]>() };
1023                // SAFETY: - INTERFACE requires that args[0] contains an int
1024                let arg0 = unsafe { args[0].i };
1025                // SAFETY: - INTERFACE requires that args[1] contains an int
1026                let arg1 = unsafe { args[1].i };
1027                self.0.configure_bounds(data, slf, arg0, arg1);
1028            }
1029            3 => {
1030                // SAFETY: INTERFACE requires that there are 1 arguments
1031                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1032                // SAFETY: - INTERFACE requires that args[0] contains an array
1033                let arg0 = unsafe {
1034                    let a = &*args[0].a;
1035                    std::slice::from_raw_parts(a.data.cast(), a.size)
1036                };
1037                self.0.wm_capabilities(data, slf, arg0);
1038            }
1039            _ => {
1040                invalid_opcode("xdg_toplevel", opcode);
1041            }
1042        }
1043    }
1044}
1045
1046impl<H> CreateEventHandler<H> for private::ProxyApi
1047where
1048    H: XdgToplevelEventHandler,
1049{
1050    type EventHandler = private::EventHandler<H>;
1051
1052    #[inline]
1053    fn create_event_handler(handler: H) -> Self::EventHandler {
1054        private::EventHandler(handler)
1055    }
1056}
1057
1058impl XdgToplevel {
1059    /// Since when the error.invalid_resize_edge enum variant is available.
1060    #[allow(dead_code)]
1061    pub const ENM__ERROR_INVALID_RESIZE_EDGE__SINCE: u32 = 1;
1062    /// Since when the error.invalid_parent enum variant is available.
1063    #[allow(dead_code)]
1064    pub const ENM__ERROR_INVALID_PARENT__SINCE: u32 = 1;
1065    /// Since when the error.invalid_size enum variant is available.
1066    #[allow(dead_code)]
1067    pub const ENM__ERROR_INVALID_SIZE__SINCE: u32 = 1;
1068
1069    /// Since when the resize_edge.none enum variant is available.
1070    #[allow(dead_code)]
1071    pub const ENM__RESIZE_EDGE_NONE__SINCE: u32 = 1;
1072    /// Since when the resize_edge.top enum variant is available.
1073    #[allow(dead_code)]
1074    pub const ENM__RESIZE_EDGE_TOP__SINCE: u32 = 1;
1075    /// Since when the resize_edge.bottom enum variant is available.
1076    #[allow(dead_code)]
1077    pub const ENM__RESIZE_EDGE_BOTTOM__SINCE: u32 = 1;
1078    /// Since when the resize_edge.left enum variant is available.
1079    #[allow(dead_code)]
1080    pub const ENM__RESIZE_EDGE_LEFT__SINCE: u32 = 1;
1081    /// Since when the resize_edge.top_left enum variant is available.
1082    #[allow(dead_code)]
1083    pub const ENM__RESIZE_EDGE_TOP_LEFT__SINCE: u32 = 1;
1084    /// Since when the resize_edge.bottom_left enum variant is available.
1085    #[allow(dead_code)]
1086    pub const ENM__RESIZE_EDGE_BOTTOM_LEFT__SINCE: u32 = 1;
1087    /// Since when the resize_edge.right enum variant is available.
1088    #[allow(dead_code)]
1089    pub const ENM__RESIZE_EDGE_RIGHT__SINCE: u32 = 1;
1090    /// Since when the resize_edge.top_right enum variant is available.
1091    #[allow(dead_code)]
1092    pub const ENM__RESIZE_EDGE_TOP_RIGHT__SINCE: u32 = 1;
1093    /// Since when the resize_edge.bottom_right enum variant is available.
1094    #[allow(dead_code)]
1095    pub const ENM__RESIZE_EDGE_BOTTOM_RIGHT__SINCE: u32 = 1;
1096
1097    /// Since when the state.maximized enum variant is available.
1098    #[allow(dead_code)]
1099    pub const ENM__STATE_MAXIMIZED__SINCE: u32 = 1;
1100    /// Since when the state.fullscreen enum variant is available.
1101    #[allow(dead_code)]
1102    pub const ENM__STATE_FULLSCREEN__SINCE: u32 = 1;
1103    /// Since when the state.resizing enum variant is available.
1104    #[allow(dead_code)]
1105    pub const ENM__STATE_RESIZING__SINCE: u32 = 1;
1106    /// Since when the state.activated enum variant is available.
1107    #[allow(dead_code)]
1108    pub const ENM__STATE_ACTIVATED__SINCE: u32 = 1;
1109    /// Since when the state.tiled_left enum variant is available.
1110    #[allow(dead_code)]
1111    pub const ENM__STATE_TILED_LEFT__SINCE: u32 = 2;
1112    /// Since when the state.tiled_right enum variant is available.
1113    #[allow(dead_code)]
1114    pub const ENM__STATE_TILED_RIGHT__SINCE: u32 = 2;
1115    /// Since when the state.tiled_top enum variant is available.
1116    #[allow(dead_code)]
1117    pub const ENM__STATE_TILED_TOP__SINCE: u32 = 2;
1118    /// Since when the state.tiled_bottom enum variant is available.
1119    #[allow(dead_code)]
1120    pub const ENM__STATE_TILED_BOTTOM__SINCE: u32 = 2;
1121    /// Since when the state.suspended enum variant is available.
1122    #[allow(dead_code)]
1123    pub const ENM__STATE_SUSPENDED__SINCE: u32 = 6;
1124
1125    /// Since when the wm_capabilities.window_menu enum variant is available.
1126    #[allow(dead_code)]
1127    pub const ENM__WM_CAPABILITIES_WINDOW_MENU__SINCE: u32 = 1;
1128    /// Since when the wm_capabilities.maximize enum variant is available.
1129    #[allow(dead_code)]
1130    pub const ENM__WM_CAPABILITIES_MAXIMIZE__SINCE: u32 = 1;
1131    /// Since when the wm_capabilities.fullscreen enum variant is available.
1132    #[allow(dead_code)]
1133    pub const ENM__WM_CAPABILITIES_FULLSCREEN__SINCE: u32 = 1;
1134    /// Since when the wm_capabilities.minimize enum variant is available.
1135    #[allow(dead_code)]
1136    pub const ENM__WM_CAPABILITIES_MINIMIZE__SINCE: u32 = 1;
1137}
1138
1139#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1140#[allow(dead_code)]
1141pub struct XdgToplevelError(pub u32);
1142
1143impl XdgToplevelError {
1144    /// provided value is
1145    ///         not a valid variant of the resize_edge enum
1146    #[allow(dead_code)]
1147    pub const INVALID_RESIZE_EDGE: Self = Self(0);
1148
1149    /// invalid parent toplevel
1150    #[allow(dead_code)]
1151    pub const INVALID_PARENT: Self = Self(1);
1152
1153    /// client provided an invalid min or max size
1154    #[allow(dead_code)]
1155    pub const INVALID_SIZE: Self = Self(2);
1156}
1157
1158impl Debug for XdgToplevelError {
1159    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1160        let name = match *self {
1161            Self::INVALID_RESIZE_EDGE => "INVALID_RESIZE_EDGE",
1162            Self::INVALID_PARENT => "INVALID_PARENT",
1163            Self::INVALID_SIZE => "INVALID_SIZE",
1164            _ => return Debug::fmt(&self.0, f),
1165        };
1166        f.write_str(name)
1167    }
1168}
1169
1170/// edge values for resizing
1171///
1172/// These values are used to indicate which edge of a surface
1173/// is being dragged in a resize operation.
1174#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1175#[allow(dead_code)]
1176pub struct XdgToplevelResizeEdge(pub u32);
1177
1178impl XdgToplevelResizeEdge {
1179    #[allow(dead_code)]
1180    pub const NONE: Self = Self(0);
1181
1182    #[allow(dead_code)]
1183    pub const TOP: Self = Self(1);
1184
1185    #[allow(dead_code)]
1186    pub const BOTTOM: Self = Self(2);
1187
1188    #[allow(dead_code)]
1189    pub const LEFT: Self = Self(4);
1190
1191    #[allow(dead_code)]
1192    pub const TOP_LEFT: Self = Self(5);
1193
1194    #[allow(dead_code)]
1195    pub const BOTTOM_LEFT: Self = Self(6);
1196
1197    #[allow(dead_code)]
1198    pub const RIGHT: Self = Self(8);
1199
1200    #[allow(dead_code)]
1201    pub const TOP_RIGHT: Self = Self(9);
1202
1203    #[allow(dead_code)]
1204    pub const BOTTOM_RIGHT: Self = Self(10);
1205}
1206
1207impl Debug for XdgToplevelResizeEdge {
1208    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1209        let name = match *self {
1210            Self::NONE => "NONE",
1211            Self::TOP => "TOP",
1212            Self::BOTTOM => "BOTTOM",
1213            Self::LEFT => "LEFT",
1214            Self::TOP_LEFT => "TOP_LEFT",
1215            Self::BOTTOM_LEFT => "BOTTOM_LEFT",
1216            Self::RIGHT => "RIGHT",
1217            Self::TOP_RIGHT => "TOP_RIGHT",
1218            Self::BOTTOM_RIGHT => "BOTTOM_RIGHT",
1219            _ => return Debug::fmt(&self.0, f),
1220        };
1221        f.write_str(name)
1222    }
1223}
1224
1225/// types of state on the surface
1226///
1227/// The different state values used on the surface. This is designed for
1228/// state values like maximized, fullscreen. It is paired with the
1229/// configure event to ensure that both the client and the compositor
1230/// setting the state can be synchronized.
1231///
1232/// States set in this way are double-buffered, see wl_surface.commit.
1233#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1234#[allow(dead_code)]
1235pub struct XdgToplevelState(pub u32);
1236
1237impl XdgToplevelState {
1238    /// the surface is maximized
1239    ///
1240    /// the surface is maximized
1241    ///
1242    /// The surface is maximized. The window geometry specified in the configure
1243    /// event must be obeyed by the client, or the xdg_wm_base.invalid_surface_state
1244    /// error is raised.
1245    ///
1246    /// The client should draw without shadow or other
1247    /// decoration outside of the window geometry.
1248    #[allow(dead_code)]
1249    pub const MAXIMIZED: Self = Self(1);
1250
1251    /// the surface is fullscreen
1252    ///
1253    /// the surface is fullscreen
1254    ///
1255    /// The surface is fullscreen. The window geometry specified in the
1256    /// configure event is a maximum; the client cannot resize beyond it. For
1257    /// a surface to cover the whole fullscreened area, the geometry
1258    /// dimensions must be obeyed by the client. For more details, see
1259    /// xdg_toplevel.set_fullscreen.
1260    #[allow(dead_code)]
1261    pub const FULLSCREEN: Self = Self(2);
1262
1263    /// the surface is being resized
1264    ///
1265    /// the surface is being resized
1266    ///
1267    /// The surface is being resized. The window geometry specified in the
1268    /// configure event is a maximum; the client cannot resize beyond it.
1269    /// Clients that have aspect ratio or cell sizing configuration can use
1270    /// a smaller size, however.
1271    #[allow(dead_code)]
1272    pub const RESIZING: Self = Self(3);
1273
1274    /// the surface is now activated
1275    ///
1276    /// the surface is now activated
1277    ///
1278    /// Client window decorations should be painted as if the window is
1279    /// active. Do not assume this means that the window actually has
1280    /// keyboard or pointer focus.
1281    #[allow(dead_code)]
1282    pub const ACTIVATED: Self = Self(4);
1283
1284    /// the surface’s left edge is tiled
1285    ///
1286    /// The window is currently in a tiled layout and the left edge is
1287    /// considered to be adjacent to another part of the tiling grid.
1288    ///
1289    /// The client should draw without shadow or other decoration outside of
1290    /// the window geometry on the left edge.
1291    #[allow(dead_code)]
1292    pub const TILED_LEFT: Self = Self(5);
1293
1294    /// the surface’s right edge is tiled
1295    ///
1296    /// The window is currently in a tiled layout and the right edge is
1297    /// considered to be adjacent to another part of the tiling grid.
1298    ///
1299    /// The client should draw without shadow or other decoration outside of
1300    /// the window geometry on the right edge.
1301    #[allow(dead_code)]
1302    pub const TILED_RIGHT: Self = Self(6);
1303
1304    /// the surface’s top edge is tiled
1305    ///
1306    /// The window is currently in a tiled layout and the top edge is
1307    /// considered to be adjacent to another part of the tiling grid.
1308    ///
1309    /// The client should draw without shadow or other decoration outside of
1310    /// the window geometry on the top edge.
1311    #[allow(dead_code)]
1312    pub const TILED_TOP: Self = Self(7);
1313
1314    /// the surface’s bottom edge is tiled
1315    ///
1316    /// The window is currently in a tiled layout and the bottom edge is
1317    /// considered to be adjacent to another part of the tiling grid.
1318    ///
1319    /// The client should draw without shadow or other decoration outside of
1320    /// the window geometry on the bottom edge.
1321    #[allow(dead_code)]
1322    pub const TILED_BOTTOM: Self = Self(8);
1323
1324    /// surface repaint is suspended
1325    ///
1326    /// The surface is currently not ordinarily being repainted; for
1327    /// example because its content is occluded by another window, or its
1328    /// outputs are switched off due to screen locking.
1329    #[allow(dead_code)]
1330    pub const SUSPENDED: Self = Self(9);
1331}
1332
1333impl Debug for XdgToplevelState {
1334    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1335        let name = match *self {
1336            Self::MAXIMIZED => "MAXIMIZED",
1337            Self::FULLSCREEN => "FULLSCREEN",
1338            Self::RESIZING => "RESIZING",
1339            Self::ACTIVATED => "ACTIVATED",
1340            Self::TILED_LEFT => "TILED_LEFT",
1341            Self::TILED_RIGHT => "TILED_RIGHT",
1342            Self::TILED_TOP => "TILED_TOP",
1343            Self::TILED_BOTTOM => "TILED_BOTTOM",
1344            Self::SUSPENDED => "SUSPENDED",
1345            _ => return Debug::fmt(&self.0, f),
1346        };
1347        f.write_str(name)
1348    }
1349}
1350
1351#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1352#[allow(dead_code)]
1353pub struct XdgToplevelWmCapabilities(pub u32);
1354
1355impl XdgToplevelWmCapabilities {
1356    /// show_window_menu is available
1357    #[allow(dead_code)]
1358    pub const WINDOW_MENU: Self = Self(1);
1359
1360    /// set_maximized and unset_maximized are available
1361    #[allow(dead_code)]
1362    pub const MAXIMIZE: Self = Self(2);
1363
1364    /// set_fullscreen and unset_fullscreen are available
1365    #[allow(dead_code)]
1366    pub const FULLSCREEN: Self = Self(3);
1367
1368    /// set_minimized is available
1369    #[allow(dead_code)]
1370    pub const MINIMIZE: Self = Self(4);
1371}
1372
1373impl Debug for XdgToplevelWmCapabilities {
1374    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1375        let name = match *self {
1376            Self::WINDOW_MENU => "WINDOW_MENU",
1377            Self::MAXIMIZE => "MAXIMIZE",
1378            Self::FULLSCREEN => "FULLSCREEN",
1379            Self::MINIMIZE => "MINIMIZE",
1380            _ => return Debug::fmt(&self.0, f),
1381        };
1382        f.write_str(name)
1383    }
1384}
1385
1386/// Functional event handlers.
1387pub mod event_handlers {
1388    use super::*;
1389
1390    /// Event handler for configure events.
1391    pub struct Configure<T, F>(F, PhantomData<fn(&mut T)>);
1392    impl<T, F> XdgToplevelEventHandler for Configure<T, F>
1393    where
1394        T: 'static,
1395        F: Fn(&mut T, &XdgToplevelRef, i32, i32, &[u8]),
1396    {
1397        type Data = T;
1398
1399        #[inline]
1400        fn configure(
1401            &self,
1402            _data: &mut T,
1403            _slf: &XdgToplevelRef,
1404            width: i32,
1405            height: i32,
1406            states: &[u8],
1407        ) {
1408            self.0(_data, _slf, width, height, states)
1409        }
1410    }
1411
1412    /// Event handler for close events.
1413    pub struct Close<T, F>(F, PhantomData<fn(&mut T)>);
1414    impl<T, F> XdgToplevelEventHandler for Close<T, F>
1415    where
1416        T: 'static,
1417        F: Fn(&mut T, &XdgToplevelRef),
1418    {
1419        type Data = T;
1420
1421        #[inline]
1422        fn close(&self, _data: &mut T, _slf: &XdgToplevelRef) {
1423            self.0(_data, _slf)
1424        }
1425    }
1426
1427    /// Event handler for configure_bounds events.
1428    pub struct ConfigureBounds<T, F>(F, PhantomData<fn(&mut T)>);
1429    impl<T, F> XdgToplevelEventHandler for ConfigureBounds<T, F>
1430    where
1431        T: 'static,
1432        F: Fn(&mut T, &XdgToplevelRef, i32, i32),
1433    {
1434        type Data = T;
1435
1436        #[inline]
1437        fn configure_bounds(&self, _data: &mut T, _slf: &XdgToplevelRef, width: i32, height: i32) {
1438            self.0(_data, _slf, width, height)
1439        }
1440    }
1441
1442    /// Event handler for wm_capabilities events.
1443    pub struct WmCapabilities<T, F>(F, PhantomData<fn(&mut T)>);
1444    impl<T, F> XdgToplevelEventHandler for WmCapabilities<T, F>
1445    where
1446        T: 'static,
1447        F: Fn(&mut T, &XdgToplevelRef, &[u8]),
1448    {
1449        type Data = T;
1450
1451        #[inline]
1452        fn wm_capabilities(&self, _data: &mut T, _slf: &XdgToplevelRef, capabilities: &[u8]) {
1453            self.0(_data, _slf, capabilities)
1454        }
1455    }
1456
1457    impl XdgToplevel {
1458        /// Creates an event handler for configure events.
1459        ///
1460        /// The event handler ignores all other events.
1461        #[allow(dead_code)]
1462        pub fn on_configure<T, F>(f: F) -> Configure<T, F>
1463        where
1464            T: 'static,
1465            F: Fn(&mut T, &XdgToplevelRef, i32, i32, &[u8]),
1466        {
1467            Configure(f, PhantomData)
1468        }
1469
1470        /// Creates an event handler for close events.
1471        ///
1472        /// The event handler ignores all other events.
1473        #[allow(dead_code)]
1474        pub fn on_close<T, F>(f: F) -> Close<T, F>
1475        where
1476            T: 'static,
1477            F: Fn(&mut T, &XdgToplevelRef),
1478        {
1479            Close(f, PhantomData)
1480        }
1481
1482        /// Creates an event handler for configure_bounds events.
1483        ///
1484        /// The event handler ignores all other events.
1485        #[allow(dead_code)]
1486        pub fn on_configure_bounds<T, F>(f: F) -> ConfigureBounds<T, F>
1487        where
1488            T: 'static,
1489            F: Fn(&mut T, &XdgToplevelRef, i32, i32),
1490        {
1491            ConfigureBounds(f, PhantomData)
1492        }
1493
1494        /// Creates an event handler for wm_capabilities events.
1495        ///
1496        /// The event handler ignores all other events.
1497        #[allow(dead_code)]
1498        pub fn on_wm_capabilities<T, F>(f: F) -> WmCapabilities<T, F>
1499        where
1500            T: 'static,
1501            F: Fn(&mut T, &XdgToplevelRef, &[u8]),
1502        {
1503            WmCapabilities(f, PhantomData)
1504        }
1505    }
1506}