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