poll_integration/common/protocols/xdg_shell/
xdg_positioner.rs

1//! child surface positioner
2//!
3//! The xdg_positioner provides a collection of rules for the placement of a
4//! child surface relative to a parent surface. Rules can be defined to ensure
5//! the child surface remains within the visible area's borders, and to
6//! specify how the child surface changes its position, such as sliding along
7//! an axis, or flipping around a rectangle. These positioner-created rules are
8//! constrained by the requirement that a child surface must intersect with or
9//! be at least partially adjacent to its parent surface.
10//!
11//! See the various requests for details about possible rules.
12//!
13//! At the time of the request, the compositor makes a copy of the rules
14//! specified by the xdg_positioner. Thus, after the request is complete the
15//! xdg_positioner object can be destroyed or reused; further changes to the
16//! object will have no effect on previous usages.
17//!
18//! For an xdg_positioner object to be considered complete, it must have a
19//! non-zero size set by set_size, and a non-zero anchor rectangle set by
20//! set_anchor_rect. Passing an incomplete xdg_positioner object when
21//! positioning a surface raises an invalid_positioner error.
22
23use {super::super::all_types::*, ::wl_client::builder::prelude::*};
24
25static INTERFACE: wl_interface = wl_interface {
26    name: c"xdg_positioner".as_ptr(),
27    version: 6,
28    method_count: 10,
29    methods: {
30        static MESSAGES: [wl_message; 10] = [
31            wl_message {
32                name: c"destroy".as_ptr(),
33                signature: c"".as_ptr(),
34                types: {
35                    static TYPES: [Option<&'static wl_interface>; 0] = [];
36                    TYPES.as_ptr().cast()
37                },
38            },
39            wl_message {
40                name: c"set_size".as_ptr(),
41                signature: c"ii".as_ptr(),
42                types: {
43                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
44                    TYPES.as_ptr().cast()
45                },
46            },
47            wl_message {
48                name: c"set_anchor_rect".as_ptr(),
49                signature: c"iiii".as_ptr(),
50                types: {
51                    static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
52                    TYPES.as_ptr().cast()
53                },
54            },
55            wl_message {
56                name: c"set_anchor".as_ptr(),
57                signature: c"u".as_ptr(),
58                types: {
59                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
60                    TYPES.as_ptr().cast()
61                },
62            },
63            wl_message {
64                name: c"set_gravity".as_ptr(),
65                signature: c"u".as_ptr(),
66                types: {
67                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
68                    TYPES.as_ptr().cast()
69                },
70            },
71            wl_message {
72                name: c"set_constraint_adjustment".as_ptr(),
73                signature: c"u".as_ptr(),
74                types: {
75                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
76                    TYPES.as_ptr().cast()
77                },
78            },
79            wl_message {
80                name: c"set_offset".as_ptr(),
81                signature: c"ii".as_ptr(),
82                types: {
83                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
84                    TYPES.as_ptr().cast()
85                },
86            },
87            wl_message {
88                name: c"set_reactive".as_ptr(),
89                signature: c"".as_ptr(),
90                types: {
91                    static TYPES: [Option<&'static wl_interface>; 0] = [];
92                    TYPES.as_ptr().cast()
93                },
94            },
95            wl_message {
96                name: c"set_parent_size".as_ptr(),
97                signature: c"ii".as_ptr(),
98                types: {
99                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
100                    TYPES.as_ptr().cast()
101                },
102            },
103            wl_message {
104                name: c"set_parent_configure".as_ptr(),
105                signature: c"u".as_ptr(),
106                types: {
107                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
108                    TYPES.as_ptr().cast()
109                },
110            },
111        ];
112        MESSAGES.as_ptr()
113    },
114    event_count: 0,
115    events: ptr::null(),
116};
117
118/// An owned xdg_positioner proxy.
119///
120/// See the documentation of [the module][self] for the interface description.
121#[derive(Clone, Eq, PartialEq)]
122#[repr(transparent)]
123pub struct XdgPositioner {
124    /// This proxy has the interface INTERFACE.
125    proxy: UntypedOwnedProxy,
126}
127
128/// A borrowed xdg_positioner proxy.
129///
130/// See the documentation of [the module][self] for the interface description.
131#[derive(Eq, PartialEq)]
132#[repr(transparent)]
133pub struct XdgPositionerRef {
134    /// This proxy has the interface INTERFACE.
135    proxy: UntypedBorrowedProxy,
136}
137
138// SAFETY: XdgPositioner is a transparent wrapper around UntypedOwnedProxy
139unsafe impl UntypedOwnedProxyWrapper for XdgPositioner {}
140
141// SAFETY: - INTERFACE is a valid wl_interface
142//         - The only invariant is that self.proxy has a compatible interface
143unsafe impl OwnedProxy for XdgPositioner {
144    const INTERFACE: &'static str = "xdg_positioner";
145    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
146    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
147        private::EventHandler(private::NoOpEventHandler);
148    const MAX_VERSION: u32 = 6;
149
150    type Borrowed = XdgPositionerRef;
151    type Api = private::ProxyApi;
152    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
153}
154
155// SAFETY: XdgPositionerRef is a transparent wrapper around UntypedBorrowedProxy
156unsafe impl UntypedBorrowedProxyWrapper for XdgPositionerRef {}
157
158// SAFETY: - The only invariant is that self.proxy has a compatible interface
159unsafe impl BorrowedProxy for XdgPositionerRef {
160    type Owned = XdgPositioner;
161}
162
163impl Deref for XdgPositioner {
164    type Target = XdgPositionerRef;
165
166    fn deref(&self) -> &Self::Target {
167        proxy::low_level::deref(self)
168    }
169}
170
171mod private {
172    pub struct ProxyApi;
173
174    #[allow(dead_code)]
175    pub struct EventHandler<H>(pub(super) H);
176
177    #[allow(dead_code)]
178    pub struct NoOpEventHandler;
179}
180
181impl Debug for XdgPositioner {
182    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
183        write!(f, "xdg_positioner#{}", self.proxy.id())
184    }
185}
186
187impl Debug for XdgPositionerRef {
188    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
189        write!(f, "xdg_positioner#{}", self.proxy.id())
190    }
191}
192
193impl PartialEq<XdgPositionerRef> for XdgPositioner {
194    fn eq(&self, other: &XdgPositionerRef) -> bool {
195        self.proxy == other.proxy
196    }
197}
198
199impl PartialEq<XdgPositioner> for XdgPositionerRef {
200    fn eq(&self, other: &XdgPositioner) -> bool {
201        self.proxy == other.proxy
202    }
203}
204
205#[allow(dead_code)]
206impl XdgPositioner {
207    /// Since when the destroy request is available.
208    #[allow(dead_code)]
209    pub const REQ__DESTROY__SINCE: u32 = 1;
210
211    /// destroy the xdg_positioner object
212    ///
213    /// Notify the compositor that the xdg_positioner will no longer be used.
214    #[inline]
215    pub fn destroy(&self) {
216        let mut args = [];
217        // SAFETY: - self.proxy has the interface INTERFACE
218        //         - 0 < INTERFACE.method_count = 10
219        //         - the request signature is ``
220        unsafe {
221            self.proxy.send_destructor(0, &mut args);
222        }
223    }
224}
225
226#[allow(dead_code)]
227impl XdgPositionerRef {
228    /// set the size of the to-be positioned rectangle
229    ///
230    /// Set the size of the surface that is to be positioned with the positioner
231    /// object. The size is in surface-local coordinates and corresponds to the
232    /// window geometry. See xdg_surface.set_window_geometry.
233    ///
234    /// If a zero or negative size is set the invalid_input error is raised.
235    ///
236    /// # Arguments
237    ///
238    /// - `width`: width of positioned rectangle
239    /// - `height`: height of positioned rectangle
240    #[inline]
241    pub fn set_size(&self, width: i32, height: i32) {
242        let (arg0, arg1) = (width, height);
243        let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
244        // SAFETY: - self.proxy has the interface INTERFACE
245        //         - 1 < INTERFACE.method_count = 10
246        //         - the request signature is `ii`
247        unsafe {
248            self.proxy.send_request(1, &mut args);
249        }
250    }
251
252    /// set the anchor rectangle within the parent surface
253    ///
254    /// Specify the anchor rectangle within the parent surface that the child
255    /// surface will be placed relative to. The rectangle is relative to the
256    /// window geometry as defined by xdg_surface.set_window_geometry of the
257    /// parent surface.
258    ///
259    /// When the xdg_positioner object is used to position a child surface, the
260    /// anchor rectangle may not extend outside the window geometry of the
261    /// positioned child's parent surface.
262    ///
263    /// If a negative size is set the invalid_input error is raised.
264    ///
265    /// # Arguments
266    ///
267    /// - `x`: x position of anchor rectangle
268    /// - `y`: y position of anchor rectangle
269    /// - `width`: width of anchor rectangle
270    /// - `height`: height of anchor rectangle
271    #[inline]
272    pub fn set_anchor_rect(&self, x: i32, y: i32, width: i32, height: i32) {
273        let (arg0, arg1, arg2, arg3) = (x, y, width, height);
274        let mut args = [
275            wl_argument { i: arg0 },
276            wl_argument { i: arg1 },
277            wl_argument { i: arg2 },
278            wl_argument { i: arg3 },
279        ];
280        // SAFETY: - self.proxy has the interface INTERFACE
281        //         - 2 < INTERFACE.method_count = 10
282        //         - the request signature is `iiii`
283        unsafe {
284            self.proxy.send_request(2, &mut args);
285        }
286    }
287
288    /// set anchor rectangle anchor
289    ///
290    /// Defines the anchor point for the anchor rectangle. The specified anchor
291    /// is used derive an anchor point that the child surface will be
292    /// positioned relative to. If a corner anchor is set (e.g. 'top_left' or
293    /// 'bottom_right'), the anchor point will be at the specified corner;
294    /// otherwise, the derived anchor point will be centered on the specified
295    /// edge, or in the center of the anchor rectangle if no edge is specified.
296    ///
297    /// # Arguments
298    ///
299    /// - `anchor`: anchor
300    #[inline]
301    pub fn set_anchor(&self, anchor: XdgPositionerAnchor) {
302        let (arg0,) = (anchor,);
303        let mut args = [wl_argument { u: arg0.0 }];
304        // SAFETY: - self.proxy has the interface INTERFACE
305        //         - 3 < INTERFACE.method_count = 10
306        //         - the request signature is `u`
307        unsafe {
308            self.proxy.send_request(3, &mut args);
309        }
310    }
311
312    /// set child surface gravity
313    ///
314    /// Defines in what direction a surface should be positioned, relative to
315    /// the anchor point of the parent surface. If a corner gravity is
316    /// specified (e.g. 'bottom_right' or 'top_left'), then the child surface
317    /// will be placed towards the specified gravity; otherwise, the child
318    /// surface will be centered over the anchor point on any axis that had no
319    /// gravity specified. If the gravity is not in the ‘gravity’ enum, an
320    /// invalid_input error is raised.
321    ///
322    /// # Arguments
323    ///
324    /// - `gravity`: gravity direction
325    #[inline]
326    pub fn set_gravity(&self, gravity: XdgPositionerGravity) {
327        let (arg0,) = (gravity,);
328        let mut args = [wl_argument { u: arg0.0 }];
329        // SAFETY: - self.proxy has the interface INTERFACE
330        //         - 4 < INTERFACE.method_count = 10
331        //         - the request signature is `u`
332        unsafe {
333            self.proxy.send_request(4, &mut args);
334        }
335    }
336
337    /// set the adjustment to be done when constrained
338    ///
339    /// Specify how the window should be positioned if the originally intended
340    /// position caused the surface to be constrained, meaning at least
341    /// partially outside positioning boundaries set by the compositor. The
342    /// adjustment is set by constructing a bitmask describing the adjustment to
343    /// be made when the surface is constrained on that axis.
344    ///
345    /// If no bit for one axis is set, the compositor will assume that the child
346    /// surface should not change its position on that axis when constrained.
347    ///
348    /// If more than one bit for one axis is set, the order of how adjustments
349    /// are applied is specified in the corresponding adjustment descriptions.
350    ///
351    /// The default adjustment is none.
352    ///
353    /// # Arguments
354    ///
355    /// - `constraint_adjustment`: bit mask of constraint adjustments
356    #[inline]
357    pub fn set_constraint_adjustment(
358        &self,
359        constraint_adjustment: XdgPositionerConstraintAdjustment,
360    ) {
361        let (arg0,) = (constraint_adjustment,);
362        let mut args = [wl_argument { u: arg0.0 }];
363        // SAFETY: - self.proxy has the interface INTERFACE
364        //         - 5 < INTERFACE.method_count = 10
365        //         - the request signature is `u`
366        unsafe {
367            self.proxy.send_request(5, &mut args);
368        }
369    }
370
371    /// set surface position offset
372    ///
373    /// Specify the surface position offset relative to the position of the
374    /// anchor on the anchor rectangle and the anchor on the surface. For
375    /// example if the anchor of the anchor rectangle is at (x, y), the surface
376    /// has the gravity bottom|right, and the offset is (ox, oy), the calculated
377    /// surface position will be (x + ox, y + oy). The offset position of the
378    /// surface is the one used for constraint testing. See
379    /// set_constraint_adjustment.
380    ///
381    /// An example use case is placing a popup menu on top of a user interface
382    /// element, while aligning the user interface element of the parent surface
383    /// with some user interface element placed somewhere in the popup surface.
384    ///
385    /// # Arguments
386    ///
387    /// - `x`: surface position x offset
388    /// - `y`: surface position y offset
389    #[inline]
390    pub fn set_offset(&self, x: i32, y: i32) {
391        let (arg0, arg1) = (x, y);
392        let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
393        // SAFETY: - self.proxy has the interface INTERFACE
394        //         - 6 < INTERFACE.method_count = 10
395        //         - the request signature is `ii`
396        unsafe {
397            self.proxy.send_request(6, &mut args);
398        }
399    }
400
401    /// continuously reconstrain the surface
402    ///
403    /// When set reactive, the surface is reconstrained if the conditions used
404    /// for constraining changed, e.g. the parent window moved.
405    ///
406    /// If the conditions changed and the popup was reconstrained, an
407    /// xdg_popup.configure event is sent with updated geometry, followed by an
408    /// xdg_surface.configure event.
409    #[inline]
410    pub fn set_reactive(&self) {
411        let mut args = [];
412        // SAFETY: - self.proxy has the interface INTERFACE
413        //         - 7 < INTERFACE.method_count = 10
414        //         - the request signature is ``
415        unsafe {
416            self.proxy.send_request(7, &mut args);
417        }
418    }
419
420    ///
421    /// Set the parent window geometry the compositor should use when
422    /// positioning the popup. The compositor may use this information to
423    /// determine the future state the popup should be constrained using. If
424    /// this doesn't match the dimension of the parent the popup is eventually
425    /// positioned against, the behavior is undefined.
426    ///
427    /// The arguments are given in the surface-local coordinate space.
428    ///
429    /// # Arguments
430    ///
431    /// - `parent_width`: future window geometry width of parent
432    /// - `parent_height`: future window geometry height of parent
433    #[inline]
434    pub fn set_parent_size(&self, parent_width: i32, parent_height: i32) {
435        let (arg0, arg1) = (parent_width, parent_height);
436        let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
437        // SAFETY: - self.proxy has the interface INTERFACE
438        //         - 8 < INTERFACE.method_count = 10
439        //         - the request signature is `ii`
440        unsafe {
441            self.proxy.send_request(8, &mut args);
442        }
443    }
444
445    /// set parent configure this is a response to
446    ///
447    /// Set the serial of an xdg_surface.configure event this positioner will be
448    /// used in response to. The compositor may use this information together
449    /// with set_parent_size to determine what future state the popup should be
450    /// constrained using.
451    ///
452    /// # Arguments
453    ///
454    /// - `serial`: serial of parent configure event
455    #[inline]
456    pub fn set_parent_configure(&self, serial: u32) {
457        let (arg0,) = (serial,);
458        let mut args = [wl_argument { u: arg0 }];
459        // SAFETY: - self.proxy has the interface INTERFACE
460        //         - 9 < INTERFACE.method_count = 10
461        //         - the request signature is `u`
462        unsafe {
463            self.proxy.send_request(9, &mut args);
464        }
465    }
466}
467
468/// An event handler for [XdgPositioner] proxies.
469#[allow(dead_code)]
470pub trait XdgPositionerEventHandler {}
471
472impl XdgPositionerEventHandler for private::NoOpEventHandler {}
473
474// SAFETY: INTERFACE is a valid wl_interface
475unsafe impl<H> EventHandler for private::EventHandler<H>
476where
477    H: XdgPositionerEventHandler,
478{
479    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
480
481    #[allow(unused_variables)]
482    unsafe fn handle_event(
483        &self,
484        queue: &Queue,
485        slf: &UntypedBorrowedProxy,
486        opcode: u32,
487        args: *mut wl_argument,
488    ) {
489        invalid_opcode("xdg_positioner", opcode);
490    }
491}
492
493impl<H> CreateEventHandler<H> for private::ProxyApi
494where
495    H: XdgPositionerEventHandler,
496{
497    type EventHandler = private::EventHandler<H>;
498
499    #[inline]
500    fn create_event_handler(handler: H) -> Self::EventHandler {
501        private::EventHandler(handler)
502    }
503}
504
505impl XdgPositioner {
506    /// Since when the error.invalid_input enum variant is available.
507    #[allow(dead_code)]
508    pub const ENM__ERROR_INVALID_INPUT__SINCE: u32 = 1;
509
510    /// Since when the anchor.none enum variant is available.
511    #[allow(dead_code)]
512    pub const ENM__ANCHOR_NONE__SINCE: u32 = 1;
513    /// Since when the anchor.top enum variant is available.
514    #[allow(dead_code)]
515    pub const ENM__ANCHOR_TOP__SINCE: u32 = 1;
516    /// Since when the anchor.bottom enum variant is available.
517    #[allow(dead_code)]
518    pub const ENM__ANCHOR_BOTTOM__SINCE: u32 = 1;
519    /// Since when the anchor.left enum variant is available.
520    #[allow(dead_code)]
521    pub const ENM__ANCHOR_LEFT__SINCE: u32 = 1;
522    /// Since when the anchor.right enum variant is available.
523    #[allow(dead_code)]
524    pub const ENM__ANCHOR_RIGHT__SINCE: u32 = 1;
525    /// Since when the anchor.top_left enum variant is available.
526    #[allow(dead_code)]
527    pub const ENM__ANCHOR_TOP_LEFT__SINCE: u32 = 1;
528    /// Since when the anchor.bottom_left enum variant is available.
529    #[allow(dead_code)]
530    pub const ENM__ANCHOR_BOTTOM_LEFT__SINCE: u32 = 1;
531    /// Since when the anchor.top_right enum variant is available.
532    #[allow(dead_code)]
533    pub const ENM__ANCHOR_TOP_RIGHT__SINCE: u32 = 1;
534    /// Since when the anchor.bottom_right enum variant is available.
535    #[allow(dead_code)]
536    pub const ENM__ANCHOR_BOTTOM_RIGHT__SINCE: u32 = 1;
537
538    /// Since when the gravity.none enum variant is available.
539    #[allow(dead_code)]
540    pub const ENM__GRAVITY_NONE__SINCE: u32 = 1;
541    /// Since when the gravity.top enum variant is available.
542    #[allow(dead_code)]
543    pub const ENM__GRAVITY_TOP__SINCE: u32 = 1;
544    /// Since when the gravity.bottom enum variant is available.
545    #[allow(dead_code)]
546    pub const ENM__GRAVITY_BOTTOM__SINCE: u32 = 1;
547    /// Since when the gravity.left enum variant is available.
548    #[allow(dead_code)]
549    pub const ENM__GRAVITY_LEFT__SINCE: u32 = 1;
550    /// Since when the gravity.right enum variant is available.
551    #[allow(dead_code)]
552    pub const ENM__GRAVITY_RIGHT__SINCE: u32 = 1;
553    /// Since when the gravity.top_left enum variant is available.
554    #[allow(dead_code)]
555    pub const ENM__GRAVITY_TOP_LEFT__SINCE: u32 = 1;
556    /// Since when the gravity.bottom_left enum variant is available.
557    #[allow(dead_code)]
558    pub const ENM__GRAVITY_BOTTOM_LEFT__SINCE: u32 = 1;
559    /// Since when the gravity.top_right enum variant is available.
560    #[allow(dead_code)]
561    pub const ENM__GRAVITY_TOP_RIGHT__SINCE: u32 = 1;
562    /// Since when the gravity.bottom_right enum variant is available.
563    #[allow(dead_code)]
564    pub const ENM__GRAVITY_BOTTOM_RIGHT__SINCE: u32 = 1;
565
566    /// Since when the constraint_adjustment.none enum variant is available.
567    #[allow(dead_code)]
568    pub const ENM__CONSTRAINT_ADJUSTMENT_NONE__SINCE: u32 = 1;
569    /// Since when the constraint_adjustment.slide_x enum variant is available.
570    #[allow(dead_code)]
571    pub const ENM__CONSTRAINT_ADJUSTMENT_SLIDE_X__SINCE: u32 = 1;
572    /// Since when the constraint_adjustment.slide_y enum variant is available.
573    #[allow(dead_code)]
574    pub const ENM__CONSTRAINT_ADJUSTMENT_SLIDE_Y__SINCE: u32 = 1;
575    /// Since when the constraint_adjustment.flip_x enum variant is available.
576    #[allow(dead_code)]
577    pub const ENM__CONSTRAINT_ADJUSTMENT_FLIP_X__SINCE: u32 = 1;
578    /// Since when the constraint_adjustment.flip_y enum variant is available.
579    #[allow(dead_code)]
580    pub const ENM__CONSTRAINT_ADJUSTMENT_FLIP_Y__SINCE: u32 = 1;
581    /// Since when the constraint_adjustment.resize_x enum variant is available.
582    #[allow(dead_code)]
583    pub const ENM__CONSTRAINT_ADJUSTMENT_RESIZE_X__SINCE: u32 = 1;
584    /// Since when the constraint_adjustment.resize_y enum variant is available.
585    #[allow(dead_code)]
586    pub const ENM__CONSTRAINT_ADJUSTMENT_RESIZE_Y__SINCE: u32 = 1;
587}
588
589#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
590#[allow(dead_code)]
591pub struct XdgPositionerError(pub u32);
592
593impl XdgPositionerError {
594    /// invalid input provided
595    #[allow(dead_code)]
596    pub const INVALID_INPUT: Self = Self(0);
597}
598
599impl Debug for XdgPositionerError {
600    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
601        let name = match *self {
602            Self::INVALID_INPUT => "INVALID_INPUT",
603            _ => return Debug::fmt(&self.0, f),
604        };
605        f.write_str(name)
606    }
607}
608
609#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
610#[allow(dead_code)]
611pub struct XdgPositionerAnchor(pub u32);
612
613impl XdgPositionerAnchor {
614    #[allow(dead_code)]
615    pub const NONE: Self = Self(0);
616
617    #[allow(dead_code)]
618    pub const TOP: Self = Self(1);
619
620    #[allow(dead_code)]
621    pub const BOTTOM: Self = Self(2);
622
623    #[allow(dead_code)]
624    pub const LEFT: Self = Self(3);
625
626    #[allow(dead_code)]
627    pub const RIGHT: Self = Self(4);
628
629    #[allow(dead_code)]
630    pub const TOP_LEFT: Self = Self(5);
631
632    #[allow(dead_code)]
633    pub const BOTTOM_LEFT: Self = Self(6);
634
635    #[allow(dead_code)]
636    pub const TOP_RIGHT: Self = Self(7);
637
638    #[allow(dead_code)]
639    pub const BOTTOM_RIGHT: Self = Self(8);
640}
641
642impl Debug for XdgPositionerAnchor {
643    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
644        let name = match *self {
645            Self::NONE => "NONE",
646            Self::TOP => "TOP",
647            Self::BOTTOM => "BOTTOM",
648            Self::LEFT => "LEFT",
649            Self::RIGHT => "RIGHT",
650            Self::TOP_LEFT => "TOP_LEFT",
651            Self::BOTTOM_LEFT => "BOTTOM_LEFT",
652            Self::TOP_RIGHT => "TOP_RIGHT",
653            Self::BOTTOM_RIGHT => "BOTTOM_RIGHT",
654            _ => return Debug::fmt(&self.0, f),
655        };
656        f.write_str(name)
657    }
658}
659
660#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
661#[allow(dead_code)]
662pub struct XdgPositionerGravity(pub u32);
663
664impl XdgPositionerGravity {
665    #[allow(dead_code)]
666    pub const NONE: Self = Self(0);
667
668    #[allow(dead_code)]
669    pub const TOP: Self = Self(1);
670
671    #[allow(dead_code)]
672    pub const BOTTOM: Self = Self(2);
673
674    #[allow(dead_code)]
675    pub const LEFT: Self = Self(3);
676
677    #[allow(dead_code)]
678    pub const RIGHT: Self = Self(4);
679
680    #[allow(dead_code)]
681    pub const TOP_LEFT: Self = Self(5);
682
683    #[allow(dead_code)]
684    pub const BOTTOM_LEFT: Self = Self(6);
685
686    #[allow(dead_code)]
687    pub const TOP_RIGHT: Self = Self(7);
688
689    #[allow(dead_code)]
690    pub const BOTTOM_RIGHT: Self = Self(8);
691}
692
693impl Debug for XdgPositionerGravity {
694    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
695        let name = match *self {
696            Self::NONE => "NONE",
697            Self::TOP => "TOP",
698            Self::BOTTOM => "BOTTOM",
699            Self::LEFT => "LEFT",
700            Self::RIGHT => "RIGHT",
701            Self::TOP_LEFT => "TOP_LEFT",
702            Self::BOTTOM_LEFT => "BOTTOM_LEFT",
703            Self::TOP_RIGHT => "TOP_RIGHT",
704            Self::BOTTOM_RIGHT => "BOTTOM_RIGHT",
705            _ => return Debug::fmt(&self.0, f),
706        };
707        f.write_str(name)
708    }
709}
710
711/// constraint adjustments
712///
713/// The constraint adjustment value define ways the compositor will adjust
714/// the position of the surface, if the unadjusted position would result
715/// in the surface being partly constrained.
716///
717/// Whether a surface is considered 'constrained' is left to the compositor
718/// to determine. For example, the surface may be partly outside the
719/// compositor's defined 'work area', thus necessitating the child surface's
720/// position be adjusted until it is entirely inside the work area.
721///
722/// The adjustments can be combined, according to a defined precedence: 1)
723/// Flip, 2) Slide, 3) Resize.
724#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
725#[allow(dead_code)]
726pub struct XdgPositionerConstraintAdjustment(pub u32);
727
728/// An iterator over the set bits in a [XdgPositionerConstraintAdjustment].
729///
730/// You can construct this with the `IntoIterator` implementation of `XdgPositionerConstraintAdjustment`.
731#[derive(Clone, Debug)]
732pub struct XdgPositionerConstraintAdjustmentIter(pub u32);
733
734impl XdgPositionerConstraintAdjustment {
735    /// don't move the child surface when constrained
736    ///
737    /// Don't alter the surface position even if it is constrained on some
738    /// axis, for example partially outside the edge of an output.
739    #[allow(dead_code)]
740    pub const NONE: Self = Self(0);
741
742    /// move along the x axis until unconstrained
743    ///
744    /// Slide the surface along the x axis until it is no longer constrained.
745    ///
746    /// First try to slide towards the direction of the gravity on the x axis
747    /// until either the edge in the opposite direction of the gravity is
748    /// unconstrained or the edge in the direction of the gravity is
749    /// constrained.
750    ///
751    /// Then try to slide towards the opposite direction of the gravity on the
752    /// x axis until either the edge in the direction of the gravity is
753    /// unconstrained or the edge in the opposite direction of the gravity is
754    /// constrained.
755    #[allow(dead_code)]
756    pub const SLIDE_X: Self = Self(1);
757
758    /// move along the y axis until unconstrained
759    ///
760    /// Slide the surface along the y axis until it is no longer constrained.
761    ///
762    /// First try to slide towards the direction of the gravity on the y axis
763    /// until either the edge in the opposite direction of the gravity is
764    /// unconstrained or the edge in the direction of the gravity is
765    /// constrained.
766    ///
767    /// Then try to slide towards the opposite direction of the gravity on the
768    /// y axis until either the edge in the direction of the gravity is
769    /// unconstrained or the edge in the opposite direction of the gravity is
770    /// constrained.
771    #[allow(dead_code)]
772    pub const SLIDE_Y: Self = Self(2);
773
774    /// invert the anchor and gravity on the x axis
775    ///
776    /// Invert the anchor and gravity on the x axis if the surface is
777    /// constrained on the x axis. For example, if the left edge of the
778    /// surface is constrained, the gravity is 'left' and the anchor is
779    /// 'left', change the gravity to 'right' and the anchor to 'right'.
780    ///
781    /// If the adjusted position also ends up being constrained, the resulting
782    /// position of the flip_x adjustment will be the one before the
783    /// adjustment.
784    #[allow(dead_code)]
785    pub const FLIP_X: Self = Self(4);
786
787    /// invert the anchor and gravity on the y axis
788    ///
789    /// Invert the anchor and gravity on the y axis if the surface is
790    /// constrained on the y axis. For example, if the bottom edge of the
791    /// surface is constrained, the gravity is 'bottom' and the anchor is
792    /// 'bottom', change the gravity to 'top' and the anchor to 'top'.
793    ///
794    /// The adjusted position is calculated given the original anchor
795    /// rectangle and offset, but with the new flipped anchor and gravity
796    /// values.
797    ///
798    /// If the adjusted position also ends up being constrained, the resulting
799    /// position of the flip_y adjustment will be the one before the
800    /// adjustment.
801    #[allow(dead_code)]
802    pub const FLIP_Y: Self = Self(8);
803
804    /// horizontally resize the surface
805    ///
806    /// Resize the surface horizontally so that it is completely
807    /// unconstrained.
808    #[allow(dead_code)]
809    pub const RESIZE_X: Self = Self(16);
810
811    /// vertically resize the surface
812    ///
813    /// Resize the surface vertically so that it is completely unconstrained.
814    #[allow(dead_code)]
815    pub const RESIZE_Y: Self = Self(32);
816}
817
818#[allow(dead_code)]
819impl XdgPositionerConstraintAdjustment {
820    #[inline]
821    pub const fn empty() -> Self {
822        Self(0)
823    }
824
825    #[inline]
826    #[must_use]
827    pub const fn is_empty(self) -> bool {
828        self.0 == 0
829    }
830
831    #[inline]
832    #[must_use]
833    pub const fn contains(self, other: Self) -> bool {
834        self.0 & other.0 == other.0
835    }
836
837    #[inline]
838    #[must_use]
839    pub const fn intersects(self, other: Self) -> bool {
840        self.0 & other.0 != 0
841    }
842
843    #[inline]
844    pub const fn insert(&mut self, other: Self) {
845        *self = self.union(other);
846    }
847
848    #[inline]
849    pub const fn remove(&mut self, other: Self) {
850        *self = self.difference(other);
851    }
852
853    #[inline]
854    pub const fn toggle(&mut self, other: Self) {
855        *self = self.symmetric_difference(other);
856    }
857
858    #[inline]
859    pub const fn set(&mut self, other: Self, value: bool) {
860        if value {
861            self.insert(other);
862        } else {
863            self.remove(other);
864        }
865    }
866
867    #[inline]
868    #[must_use]
869    pub const fn intersection(self, other: Self) -> Self {
870        Self(self.0 & other.0)
871    }
872
873    #[inline]
874    #[must_use]
875    pub const fn union(self, other: Self) -> Self {
876        Self(self.0 | other.0)
877    }
878
879    #[inline]
880    #[must_use]
881    pub const fn difference(self, other: Self) -> Self {
882        Self(self.0 & !other.0)
883    }
884
885    #[inline]
886    #[must_use]
887    pub const fn complement(self) -> Self {
888        Self(!self.0)
889    }
890
891    #[inline]
892    #[must_use]
893    pub const fn symmetric_difference(self, other: Self) -> Self {
894        Self(self.0 ^ other.0)
895    }
896
897    #[inline]
898    pub const fn all_known() -> Self {
899        #[allow(clippy::eq_op, clippy::identity_op)]
900        Self(0 | 0 | 1 | 2 | 4 | 8 | 16 | 32)
901    }
902}
903
904impl Iterator for XdgPositionerConstraintAdjustmentIter {
905    type Item = XdgPositionerConstraintAdjustment;
906
907    fn next(&mut self) -> Option<Self::Item> {
908        if self.0 == 0 {
909            return None;
910        }
911        let bit = 1 << self.0.trailing_zeros();
912        self.0 &= !bit;
913        Some(XdgPositionerConstraintAdjustment(bit))
914    }
915}
916
917impl IntoIterator for XdgPositionerConstraintAdjustment {
918    type Item = XdgPositionerConstraintAdjustment;
919    type IntoIter = XdgPositionerConstraintAdjustmentIter;
920
921    fn into_iter(self) -> Self::IntoIter {
922        XdgPositionerConstraintAdjustmentIter(self.0)
923    }
924}
925
926impl BitAnd for XdgPositionerConstraintAdjustment {
927    type Output = Self;
928
929    fn bitand(self, rhs: Self) -> Self::Output {
930        self.intersection(rhs)
931    }
932}
933
934impl BitAndAssign for XdgPositionerConstraintAdjustment {
935    fn bitand_assign(&mut self, rhs: Self) {
936        *self = self.intersection(rhs);
937    }
938}
939
940impl BitOr for XdgPositionerConstraintAdjustment {
941    type Output = Self;
942
943    fn bitor(self, rhs: Self) -> Self::Output {
944        self.union(rhs)
945    }
946}
947
948impl BitOrAssign for XdgPositionerConstraintAdjustment {
949    fn bitor_assign(&mut self, rhs: Self) {
950        *self = self.union(rhs);
951    }
952}
953
954impl BitXor for XdgPositionerConstraintAdjustment {
955    type Output = Self;
956
957    fn bitxor(self, rhs: Self) -> Self::Output {
958        self.symmetric_difference(rhs)
959    }
960}
961
962impl BitXorAssign for XdgPositionerConstraintAdjustment {
963    fn bitxor_assign(&mut self, rhs: Self) {
964        *self = self.symmetric_difference(rhs);
965    }
966}
967
968impl Sub for XdgPositionerConstraintAdjustment {
969    type Output = Self;
970
971    fn sub(self, rhs: Self) -> Self::Output {
972        self.difference(rhs)
973    }
974}
975
976impl SubAssign for XdgPositionerConstraintAdjustment {
977    fn sub_assign(&mut self, rhs: Self) {
978        *self = self.difference(rhs);
979    }
980}
981
982impl Not for XdgPositionerConstraintAdjustment {
983    type Output = Self;
984
985    fn not(self) -> Self::Output {
986        self.complement()
987    }
988}
989
990impl Debug for XdgPositionerConstraintAdjustment {
991    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
992        let mut v = self.0;
993        let mut first = true;
994        if v & 1 == 1 {
995            v &= !1;
996            if first {
997                first = false;
998            } else {
999                f.write_str(" | ")?;
1000            }
1001            f.write_str("SLIDE_X")?;
1002        }
1003        if v & 2 == 2 {
1004            v &= !2;
1005            if first {
1006                first = false;
1007            } else {
1008                f.write_str(" | ")?;
1009            }
1010            f.write_str("SLIDE_Y")?;
1011        }
1012        if v & 4 == 4 {
1013            v &= !4;
1014            if first {
1015                first = false;
1016            } else {
1017                f.write_str(" | ")?;
1018            }
1019            f.write_str("FLIP_X")?;
1020        }
1021        if v & 8 == 8 {
1022            v &= !8;
1023            if first {
1024                first = false;
1025            } else {
1026                f.write_str(" | ")?;
1027            }
1028            f.write_str("FLIP_Y")?;
1029        }
1030        if v & 16 == 16 {
1031            v &= !16;
1032            if first {
1033                first = false;
1034            } else {
1035                f.write_str(" | ")?;
1036            }
1037            f.write_str("RESIZE_X")?;
1038        }
1039        if v & 32 == 32 {
1040            v &= !32;
1041            if first {
1042                first = false;
1043            } else {
1044                f.write_str(" | ")?;
1045            }
1046            f.write_str("RESIZE_Y")?;
1047        }
1048        if v != 0 {
1049            if first {
1050                first = false;
1051            } else {
1052                f.write_str(" | ")?;
1053            }
1054            write!(f, "0x{v:032x}")?;
1055        }
1056        if first {
1057            f.write_str("NONE")?;
1058        }
1059        Ok(())
1060    }
1061}
1062
1063/// Functional event handlers.
1064pub mod event_handlers {
1065    use super::*;
1066
1067    impl XdgPositioner {}
1068}