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}