simple_window/common/protocols_data/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    type Data: 'static;
472}
473
474impl XdgPositionerEventHandler for private::NoOpEventHandler {
475    type Data = ();
476}
477
478// SAFETY: - INTERFACE is a valid wl_interface
479//         - mutable_type always returns the same value
480unsafe impl<H> EventHandler for private::EventHandler<H>
481where
482    H: XdgPositionerEventHandler,
483{
484    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
485
486    #[inline]
487    fn mutable_type() -> Option<(TypeId, &'static str)> {
488        let id = TypeId::of::<H::Data>();
489        let name = std::any::type_name::<H::Data>();
490        Some((id, name))
491    }
492
493    #[allow(unused_variables)]
494    unsafe fn handle_event(
495        &self,
496        queue: &Queue,
497        data: *mut u8,
498        slf: &UntypedBorrowedProxy,
499        opcode: u32,
500        args: *mut wl_argument,
501    ) {
502        invalid_opcode("xdg_positioner", opcode);
503    }
504}
505
506impl<H> CreateEventHandler<H> for private::ProxyApi
507where
508    H: XdgPositionerEventHandler,
509{
510    type EventHandler = private::EventHandler<H>;
511
512    #[inline]
513    fn create_event_handler(handler: H) -> Self::EventHandler {
514        private::EventHandler(handler)
515    }
516}
517
518impl XdgPositioner {
519    /// Since when the error.invalid_input enum variant is available.
520    #[allow(dead_code)]
521    pub const ENM__ERROR_INVALID_INPUT__SINCE: u32 = 1;
522
523    /// Since when the anchor.none enum variant is available.
524    #[allow(dead_code)]
525    pub const ENM__ANCHOR_NONE__SINCE: u32 = 1;
526    /// Since when the anchor.top enum variant is available.
527    #[allow(dead_code)]
528    pub const ENM__ANCHOR_TOP__SINCE: u32 = 1;
529    /// Since when the anchor.bottom enum variant is available.
530    #[allow(dead_code)]
531    pub const ENM__ANCHOR_BOTTOM__SINCE: u32 = 1;
532    /// Since when the anchor.left enum variant is available.
533    #[allow(dead_code)]
534    pub const ENM__ANCHOR_LEFT__SINCE: u32 = 1;
535    /// Since when the anchor.right enum variant is available.
536    #[allow(dead_code)]
537    pub const ENM__ANCHOR_RIGHT__SINCE: u32 = 1;
538    /// Since when the anchor.top_left enum variant is available.
539    #[allow(dead_code)]
540    pub const ENM__ANCHOR_TOP_LEFT__SINCE: u32 = 1;
541    /// Since when the anchor.bottom_left enum variant is available.
542    #[allow(dead_code)]
543    pub const ENM__ANCHOR_BOTTOM_LEFT__SINCE: u32 = 1;
544    /// Since when the anchor.top_right enum variant is available.
545    #[allow(dead_code)]
546    pub const ENM__ANCHOR_TOP_RIGHT__SINCE: u32 = 1;
547    /// Since when the anchor.bottom_right enum variant is available.
548    #[allow(dead_code)]
549    pub const ENM__ANCHOR_BOTTOM_RIGHT__SINCE: u32 = 1;
550
551    /// Since when the gravity.none enum variant is available.
552    #[allow(dead_code)]
553    pub const ENM__GRAVITY_NONE__SINCE: u32 = 1;
554    /// Since when the gravity.top enum variant is available.
555    #[allow(dead_code)]
556    pub const ENM__GRAVITY_TOP__SINCE: u32 = 1;
557    /// Since when the gravity.bottom enum variant is available.
558    #[allow(dead_code)]
559    pub const ENM__GRAVITY_BOTTOM__SINCE: u32 = 1;
560    /// Since when the gravity.left enum variant is available.
561    #[allow(dead_code)]
562    pub const ENM__GRAVITY_LEFT__SINCE: u32 = 1;
563    /// Since when the gravity.right enum variant is available.
564    #[allow(dead_code)]
565    pub const ENM__GRAVITY_RIGHT__SINCE: u32 = 1;
566    /// Since when the gravity.top_left enum variant is available.
567    #[allow(dead_code)]
568    pub const ENM__GRAVITY_TOP_LEFT__SINCE: u32 = 1;
569    /// Since when the gravity.bottom_left enum variant is available.
570    #[allow(dead_code)]
571    pub const ENM__GRAVITY_BOTTOM_LEFT__SINCE: u32 = 1;
572    /// Since when the gravity.top_right enum variant is available.
573    #[allow(dead_code)]
574    pub const ENM__GRAVITY_TOP_RIGHT__SINCE: u32 = 1;
575    /// Since when the gravity.bottom_right enum variant is available.
576    #[allow(dead_code)]
577    pub const ENM__GRAVITY_BOTTOM_RIGHT__SINCE: u32 = 1;
578
579    /// Since when the constraint_adjustment.none enum variant is available.
580    #[allow(dead_code)]
581    pub const ENM__CONSTRAINT_ADJUSTMENT_NONE__SINCE: u32 = 1;
582    /// Since when the constraint_adjustment.slide_x enum variant is available.
583    #[allow(dead_code)]
584    pub const ENM__CONSTRAINT_ADJUSTMENT_SLIDE_X__SINCE: u32 = 1;
585    /// Since when the constraint_adjustment.slide_y enum variant is available.
586    #[allow(dead_code)]
587    pub const ENM__CONSTRAINT_ADJUSTMENT_SLIDE_Y__SINCE: u32 = 1;
588    /// Since when the constraint_adjustment.flip_x enum variant is available.
589    #[allow(dead_code)]
590    pub const ENM__CONSTRAINT_ADJUSTMENT_FLIP_X__SINCE: u32 = 1;
591    /// Since when the constraint_adjustment.flip_y enum variant is available.
592    #[allow(dead_code)]
593    pub const ENM__CONSTRAINT_ADJUSTMENT_FLIP_Y__SINCE: u32 = 1;
594    /// Since when the constraint_adjustment.resize_x enum variant is available.
595    #[allow(dead_code)]
596    pub const ENM__CONSTRAINT_ADJUSTMENT_RESIZE_X__SINCE: u32 = 1;
597    /// Since when the constraint_adjustment.resize_y enum variant is available.
598    #[allow(dead_code)]
599    pub const ENM__CONSTRAINT_ADJUSTMENT_RESIZE_Y__SINCE: u32 = 1;
600}
601
602#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
603#[allow(dead_code)]
604pub struct XdgPositionerError(pub u32);
605
606impl XdgPositionerError {
607    /// invalid input provided
608    #[allow(dead_code)]
609    pub const INVALID_INPUT: Self = Self(0);
610}
611
612impl Debug for XdgPositionerError {
613    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
614        let name = match *self {
615            Self::INVALID_INPUT => "INVALID_INPUT",
616            _ => return Debug::fmt(&self.0, f),
617        };
618        f.write_str(name)
619    }
620}
621
622#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
623#[allow(dead_code)]
624pub struct XdgPositionerAnchor(pub u32);
625
626impl XdgPositionerAnchor {
627    #[allow(dead_code)]
628    pub const NONE: Self = Self(0);
629
630    #[allow(dead_code)]
631    pub const TOP: Self = Self(1);
632
633    #[allow(dead_code)]
634    pub const BOTTOM: Self = Self(2);
635
636    #[allow(dead_code)]
637    pub const LEFT: Self = Self(3);
638
639    #[allow(dead_code)]
640    pub const RIGHT: Self = Self(4);
641
642    #[allow(dead_code)]
643    pub const TOP_LEFT: Self = Self(5);
644
645    #[allow(dead_code)]
646    pub const BOTTOM_LEFT: Self = Self(6);
647
648    #[allow(dead_code)]
649    pub const TOP_RIGHT: Self = Self(7);
650
651    #[allow(dead_code)]
652    pub const BOTTOM_RIGHT: Self = Self(8);
653}
654
655impl Debug for XdgPositionerAnchor {
656    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
657        let name = match *self {
658            Self::NONE => "NONE",
659            Self::TOP => "TOP",
660            Self::BOTTOM => "BOTTOM",
661            Self::LEFT => "LEFT",
662            Self::RIGHT => "RIGHT",
663            Self::TOP_LEFT => "TOP_LEFT",
664            Self::BOTTOM_LEFT => "BOTTOM_LEFT",
665            Self::TOP_RIGHT => "TOP_RIGHT",
666            Self::BOTTOM_RIGHT => "BOTTOM_RIGHT",
667            _ => return Debug::fmt(&self.0, f),
668        };
669        f.write_str(name)
670    }
671}
672
673#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
674#[allow(dead_code)]
675pub struct XdgPositionerGravity(pub u32);
676
677impl XdgPositionerGravity {
678    #[allow(dead_code)]
679    pub const NONE: Self = Self(0);
680
681    #[allow(dead_code)]
682    pub const TOP: Self = Self(1);
683
684    #[allow(dead_code)]
685    pub const BOTTOM: Self = Self(2);
686
687    #[allow(dead_code)]
688    pub const LEFT: Self = Self(3);
689
690    #[allow(dead_code)]
691    pub const RIGHT: Self = Self(4);
692
693    #[allow(dead_code)]
694    pub const TOP_LEFT: Self = Self(5);
695
696    #[allow(dead_code)]
697    pub const BOTTOM_LEFT: Self = Self(6);
698
699    #[allow(dead_code)]
700    pub const TOP_RIGHT: Self = Self(7);
701
702    #[allow(dead_code)]
703    pub const BOTTOM_RIGHT: Self = Self(8);
704}
705
706impl Debug for XdgPositionerGravity {
707    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
708        let name = match *self {
709            Self::NONE => "NONE",
710            Self::TOP => "TOP",
711            Self::BOTTOM => "BOTTOM",
712            Self::LEFT => "LEFT",
713            Self::RIGHT => "RIGHT",
714            Self::TOP_LEFT => "TOP_LEFT",
715            Self::BOTTOM_LEFT => "BOTTOM_LEFT",
716            Self::TOP_RIGHT => "TOP_RIGHT",
717            Self::BOTTOM_RIGHT => "BOTTOM_RIGHT",
718            _ => return Debug::fmt(&self.0, f),
719        };
720        f.write_str(name)
721    }
722}
723
724/// constraint adjustments
725///
726/// The constraint adjustment value define ways the compositor will adjust
727/// the position of the surface, if the unadjusted position would result
728/// in the surface being partly constrained.
729///
730/// Whether a surface is considered 'constrained' is left to the compositor
731/// to determine. For example, the surface may be partly outside the
732/// compositor's defined 'work area', thus necessitating the child surface's
733/// position be adjusted until it is entirely inside the work area.
734///
735/// The adjustments can be combined, according to a defined precedence: 1)
736/// Flip, 2) Slide, 3) Resize.
737#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
738#[allow(dead_code)]
739pub struct XdgPositionerConstraintAdjustment(pub u32);
740
741/// An iterator over the set bits in a [XdgPositionerConstraintAdjustment].
742///
743/// You can construct this with the `IntoIterator` implementation of `XdgPositionerConstraintAdjustment`.
744#[derive(Clone, Debug)]
745pub struct XdgPositionerConstraintAdjustmentIter(pub u32);
746
747impl XdgPositionerConstraintAdjustment {
748    /// don't move the child surface when constrained
749    ///
750    /// Don't alter the surface position even if it is constrained on some
751    /// axis, for example partially outside the edge of an output.
752    #[allow(dead_code)]
753    pub const NONE: Self = Self(0);
754
755    /// move along the x axis until unconstrained
756    ///
757    /// Slide the surface along the x axis until it is no longer constrained.
758    ///
759    /// First try to slide towards the direction of the gravity on the x axis
760    /// until either the edge in the opposite direction of the gravity is
761    /// unconstrained or the edge in the direction of the gravity is
762    /// constrained.
763    ///
764    /// Then try to slide towards the opposite direction of the gravity on the
765    /// x axis until either the edge in the direction of the gravity is
766    /// unconstrained or the edge in the opposite direction of the gravity is
767    /// constrained.
768    #[allow(dead_code)]
769    pub const SLIDE_X: Self = Self(1);
770
771    /// move along the y axis until unconstrained
772    ///
773    /// Slide the surface along the y axis until it is no longer constrained.
774    ///
775    /// First try to slide towards the direction of the gravity on the y axis
776    /// until either the edge in the opposite direction of the gravity is
777    /// unconstrained or the edge in the direction of the gravity is
778    /// constrained.
779    ///
780    /// Then try to slide towards the opposite direction of the gravity on the
781    /// y axis until either the edge in the direction of the gravity is
782    /// unconstrained or the edge in the opposite direction of the gravity is
783    /// constrained.
784    #[allow(dead_code)]
785    pub const SLIDE_Y: Self = Self(2);
786
787    /// invert the anchor and gravity on the x axis
788    ///
789    /// Invert the anchor and gravity on the x axis if the surface is
790    /// constrained on the x axis. For example, if the left edge of the
791    /// surface is constrained, the gravity is 'left' and the anchor is
792    /// 'left', change the gravity to 'right' and the anchor to 'right'.
793    ///
794    /// If the adjusted position also ends up being constrained, the resulting
795    /// position of the flip_x adjustment will be the one before the
796    /// adjustment.
797    #[allow(dead_code)]
798    pub const FLIP_X: Self = Self(4);
799
800    /// invert the anchor and gravity on the y axis
801    ///
802    /// Invert the anchor and gravity on the y axis if the surface is
803    /// constrained on the y axis. For example, if the bottom edge of the
804    /// surface is constrained, the gravity is 'bottom' and the anchor is
805    /// 'bottom', change the gravity to 'top' and the anchor to 'top'.
806    ///
807    /// The adjusted position is calculated given the original anchor
808    /// rectangle and offset, but with the new flipped anchor and gravity
809    /// values.
810    ///
811    /// If the adjusted position also ends up being constrained, the resulting
812    /// position of the flip_y adjustment will be the one before the
813    /// adjustment.
814    #[allow(dead_code)]
815    pub const FLIP_Y: Self = Self(8);
816
817    /// horizontally resize the surface
818    ///
819    /// Resize the surface horizontally so that it is completely
820    /// unconstrained.
821    #[allow(dead_code)]
822    pub const RESIZE_X: Self = Self(16);
823
824    /// vertically resize the surface
825    ///
826    /// Resize the surface vertically so that it is completely unconstrained.
827    #[allow(dead_code)]
828    pub const RESIZE_Y: Self = Self(32);
829}
830
831#[allow(dead_code)]
832impl XdgPositionerConstraintAdjustment {
833    #[inline]
834    pub const fn empty() -> Self {
835        Self(0)
836    }
837
838    #[inline]
839    #[must_use]
840    pub const fn is_empty(self) -> bool {
841        self.0 == 0
842    }
843
844    #[inline]
845    #[must_use]
846    pub const fn contains(self, other: Self) -> bool {
847        self.0 & other.0 == other.0
848    }
849
850    #[inline]
851    #[must_use]
852    pub const fn intersects(self, other: Self) -> bool {
853        self.0 & other.0 != 0
854    }
855
856    #[inline]
857    pub const fn insert(&mut self, other: Self) {
858        *self = self.union(other);
859    }
860
861    #[inline]
862    pub const fn remove(&mut self, other: Self) {
863        *self = self.difference(other);
864    }
865
866    #[inline]
867    pub const fn toggle(&mut self, other: Self) {
868        *self = self.symmetric_difference(other);
869    }
870
871    #[inline]
872    pub const fn set(&mut self, other: Self, value: bool) {
873        if value {
874            self.insert(other);
875        } else {
876            self.remove(other);
877        }
878    }
879
880    #[inline]
881    #[must_use]
882    pub const fn intersection(self, other: Self) -> Self {
883        Self(self.0 & other.0)
884    }
885
886    #[inline]
887    #[must_use]
888    pub const fn union(self, other: Self) -> Self {
889        Self(self.0 | other.0)
890    }
891
892    #[inline]
893    #[must_use]
894    pub const fn difference(self, other: Self) -> Self {
895        Self(self.0 & !other.0)
896    }
897
898    #[inline]
899    #[must_use]
900    pub const fn complement(self) -> Self {
901        Self(!self.0)
902    }
903
904    #[inline]
905    #[must_use]
906    pub const fn symmetric_difference(self, other: Self) -> Self {
907        Self(self.0 ^ other.0)
908    }
909
910    #[inline]
911    pub const fn all_known() -> Self {
912        #[allow(clippy::eq_op, clippy::identity_op)]
913        Self(0 | 0 | 1 | 2 | 4 | 8 | 16 | 32)
914    }
915}
916
917impl Iterator for XdgPositionerConstraintAdjustmentIter {
918    type Item = XdgPositionerConstraintAdjustment;
919
920    fn next(&mut self) -> Option<Self::Item> {
921        if self.0 == 0 {
922            return None;
923        }
924        let bit = 1 << self.0.trailing_zeros();
925        self.0 &= !bit;
926        Some(XdgPositionerConstraintAdjustment(bit))
927    }
928}
929
930impl IntoIterator for XdgPositionerConstraintAdjustment {
931    type Item = XdgPositionerConstraintAdjustment;
932    type IntoIter = XdgPositionerConstraintAdjustmentIter;
933
934    fn into_iter(self) -> Self::IntoIter {
935        XdgPositionerConstraintAdjustmentIter(self.0)
936    }
937}
938
939impl BitAnd for XdgPositionerConstraintAdjustment {
940    type Output = Self;
941
942    fn bitand(self, rhs: Self) -> Self::Output {
943        self.intersection(rhs)
944    }
945}
946
947impl BitAndAssign for XdgPositionerConstraintAdjustment {
948    fn bitand_assign(&mut self, rhs: Self) {
949        *self = self.intersection(rhs);
950    }
951}
952
953impl BitOr for XdgPositionerConstraintAdjustment {
954    type Output = Self;
955
956    fn bitor(self, rhs: Self) -> Self::Output {
957        self.union(rhs)
958    }
959}
960
961impl BitOrAssign for XdgPositionerConstraintAdjustment {
962    fn bitor_assign(&mut self, rhs: Self) {
963        *self = self.union(rhs);
964    }
965}
966
967impl BitXor for XdgPositionerConstraintAdjustment {
968    type Output = Self;
969
970    fn bitxor(self, rhs: Self) -> Self::Output {
971        self.symmetric_difference(rhs)
972    }
973}
974
975impl BitXorAssign for XdgPositionerConstraintAdjustment {
976    fn bitxor_assign(&mut self, rhs: Self) {
977        *self = self.symmetric_difference(rhs);
978    }
979}
980
981impl Sub for XdgPositionerConstraintAdjustment {
982    type Output = Self;
983
984    fn sub(self, rhs: Self) -> Self::Output {
985        self.difference(rhs)
986    }
987}
988
989impl SubAssign for XdgPositionerConstraintAdjustment {
990    fn sub_assign(&mut self, rhs: Self) {
991        *self = self.difference(rhs);
992    }
993}
994
995impl Not for XdgPositionerConstraintAdjustment {
996    type Output = Self;
997
998    fn not(self) -> Self::Output {
999        self.complement()
1000    }
1001}
1002
1003impl Debug for XdgPositionerConstraintAdjustment {
1004    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1005        let mut v = self.0;
1006        let mut first = true;
1007        if v & 1 == 1 {
1008            v &= !1;
1009            if first {
1010                first = false;
1011            } else {
1012                f.write_str(" | ")?;
1013            }
1014            f.write_str("SLIDE_X")?;
1015        }
1016        if v & 2 == 2 {
1017            v &= !2;
1018            if first {
1019                first = false;
1020            } else {
1021                f.write_str(" | ")?;
1022            }
1023            f.write_str("SLIDE_Y")?;
1024        }
1025        if v & 4 == 4 {
1026            v &= !4;
1027            if first {
1028                first = false;
1029            } else {
1030                f.write_str(" | ")?;
1031            }
1032            f.write_str("FLIP_X")?;
1033        }
1034        if v & 8 == 8 {
1035            v &= !8;
1036            if first {
1037                first = false;
1038            } else {
1039                f.write_str(" | ")?;
1040            }
1041            f.write_str("FLIP_Y")?;
1042        }
1043        if v & 16 == 16 {
1044            v &= !16;
1045            if first {
1046                first = false;
1047            } else {
1048                f.write_str(" | ")?;
1049            }
1050            f.write_str("RESIZE_X")?;
1051        }
1052        if v & 32 == 32 {
1053            v &= !32;
1054            if first {
1055                first = false;
1056            } else {
1057                f.write_str(" | ")?;
1058            }
1059            f.write_str("RESIZE_Y")?;
1060        }
1061        if v != 0 {
1062            if first {
1063                first = false;
1064            } else {
1065                f.write_str(" | ")?;
1066            }
1067            write!(f, "0x{v:032x}")?;
1068        }
1069        if first {
1070            f.write_str("NONE")?;
1071        }
1072        Ok(())
1073    }
1074}
1075
1076/// Functional event handlers.
1077pub mod event_handlers {
1078    use super::*;
1079
1080    impl XdgPositioner {}
1081}