xdg_shell_client_protocol/xdg_shell_client_protocol.rs
1// GENERATED FILE -- DO NOT EDIT
2//
3// Copyright © 2008-2013 Kristian Høgsberg
4// Copyright © 2013 Rafael Antognolli
5// Copyright © 2013 Jasper St. Pierre
6// Copyright © 2010-2013 Intel Corporation
7// Copyright © 2015-2017 Samsung Electronics Co., Ltd
8// Copyright © 2015-2017 Red Hat Inc.
9//
10// Permission is hereby granted, free of charge, to any person obtaining a
11// copy of this software and associated documentation files (the "Software"),
12// to deal in the Software without restriction, including without limitation
13// the rights to use, copy, modify, merge, publish, distribute, sublicense,
14// and/or sell copies of the Software, and to permit persons to whom the
15// Software is furnished to do so, subject to the following conditions:
16//
17// The above copyright notice and this permission notice (including the next
18// paragraph) shall be included in all copies or substantial portions of the
19// Software.
20//
21// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27// DEALINGS IN THE SOFTWARE.
28
29#![allow(warnings)]
30#![allow(clippy::all)]
31use anyhow;
32#[allow(unused_imports)]
33use fuchsia_wayland_core::{Array, Enum, Fixed, NewId, NewObject};
34use fuchsia_wayland_core::{ArgKind, Arg, FromArgs, IntoMessage, Message,
35 MessageGroupSpec, MessageHeader, MessageSpec, MessageType,
36 ObjectId, EncodeError, DecodeError, Interface};
37pub mod xdg_wm_base {
38use super::*;
39
40/// create desktop-style surfaces
41///
42/// The xdg_wm_base interface is exposed as a global object enabling clients
43/// to turn their wl_surfaces into windows in a desktop environment. It
44/// defines the basic functionality needed for clients and the compositor to
45/// create windows that can be dragged, resized, maximized, etc, as well as
46/// creating transient windows such as popup menus.
47#[derive(Debug)]
48pub struct XdgWmBase;
49
50impl Interface for XdgWmBase {
51 const NAME: &'static str = "xdg_wm_base";
52 const VERSION: u32 = 3;
53 const REQUESTS: MessageGroupSpec = MessageGroupSpec(&[
54 // destroy
55 MessageSpec(&[
56 ]),
57 // create_positioner
58 MessageSpec(&[
59 ArgKind::NewId,
60 ]),
61 // get_xdg_surface
62 MessageSpec(&[
63 ArgKind::NewId,
64 ArgKind::Object,
65 ]),
66 // pong
67 MessageSpec(&[
68 ArgKind::Uint,
69 ]),
70 ]);
71 const EVENTS: MessageGroupSpec = MessageGroupSpec(&[
72 // ping
73 MessageSpec(&[
74 ArgKind::Uint,
75 ]),
76 ]);
77 type Incoming = Event;
78 type Outgoing = Request;
79}
80
81#[derive(Debug)]
82pub enum Request {
83
84 /// destroy xdg_wm_base
85 ///
86 /// Destroy this xdg_wm_base object.
87 ///
88 /// Destroying a bound xdg_wm_base object while there are surfaces
89 /// still alive created by this xdg_wm_base object instance is illegal
90 /// and will result in a protocol error.
91 Destroy,
92
93 /// create a positioner object
94 ///
95 /// Create a positioner object. A positioner object is used to position
96 /// surfaces relative to some parent surface. See the interface description
97 /// and xdg_surface.get_popup for details.
98 CreatePositioner {
99 id: NewId,
100 },
101
102 /// create a shell surface from a surface
103 ///
104 /// This creates an xdg_surface for the given surface. While xdg_surface
105 /// itself is not a role, the corresponding surface may only be assigned
106 /// a role extending xdg_surface, such as xdg_toplevel or xdg_popup.
107 ///
108 /// This creates an xdg_surface for the given surface. An xdg_surface is
109 /// used as basis to define a role to a given surface, such as xdg_toplevel
110 /// or xdg_popup. It also manages functionality shared between xdg_surface
111 /// based surface roles.
112 ///
113 /// See the documentation of xdg_surface for more details about what an
114 /// xdg_surface is and how it is used.
115 GetXdgSurface {
116 id: NewId,
117 surface: ObjectId,
118 },
119
120 /// respond to a ping event
121 ///
122 /// A client must respond to a ping event with a pong request or
123 /// the client may be deemed unresponsive. See xdg_wm_base.ping.
124 Pong {
125 /// serial of the ping event
126 serial: u32,
127 },
128}
129
130impl MessageType for Request {
131 fn log(&self, this: ObjectId) -> String {
132 match *self {
133 Request::Destroy {
134 } => {
135 format!("xdg_wm_base@{:?}::destroy()", this)
136 }
137 Request::CreatePositioner {
138 ref id,
139 } => {
140 format!("xdg_wm_base@{:?}::create_positioner(id: {:?})", this, id)
141 }
142 Request::GetXdgSurface {
143 ref id,
144 ref surface,
145 } => {
146 format!("xdg_wm_base@{:?}::get_xdg_surface(id: {:?}, surface: {:?})", this, id, surface)
147 }
148 Request::Pong {
149 ref serial,
150 } => {
151 format!("xdg_wm_base@{:?}::pong(serial: {:?})", this, serial)
152 }
153 }
154 }
155 fn message_name(&self) -> &'static std::ffi::CStr{
156 match *self {
157 Request::Destroy { .. } => c"xdg_wm_base::destroy",
158 Request::CreatePositioner { .. } => c"xdg_wm_base::create_positioner",
159 Request::GetXdgSurface { .. } => c"xdg_wm_base::get_xdg_surface",
160 Request::Pong { .. } => c"xdg_wm_base::pong",
161 }
162 }
163}
164#[derive(Debug)]
165pub enum Event {
166
167 /// check if the client is alive
168 ///
169 /// The ping event asks the client if it's still alive. Pass the
170 /// serial specified in the event back to the compositor by sending
171 /// a "pong" request back with the specified serial. See xdg_wm_base.pong.
172 ///
173 /// Compositors can use this to determine if the client is still
174 /// alive. It's unspecified what will happen if the client doesn't
175 /// respond to the ping request, or in what timeframe. Clients should
176 /// try to respond in a reasonable amount of time.
177 ///
178 /// A compositor is free to ping in any way it wants, but a client must
179 /// always respond to any xdg_wm_base object it created.
180 Ping {
181 /// pass this to the pong request
182 serial: u32,
183 },
184}
185
186impl MessageType for Event {
187 fn log(&self, this: ObjectId) -> String {
188 match *self {
189 Event::Ping {
190 ref serial,
191 } => {
192 format!("xdg_wm_base@{:?}::ping(serial: {:?})", this, serial)
193 }
194 }
195 }
196 fn message_name(&self) -> &'static std::ffi::CStr{
197 match *self {
198 Event::Ping { .. } => c"xdg_wm_base::ping",
199 }
200 }
201}
202impl IntoMessage for Request {
203 type Error = EncodeError;
204 fn into_message(self, id: u32) -> Result<Message, <Self as IntoMessage>::Error> {
205 let mut header = MessageHeader {
206 sender: id,
207 opcode: 0,
208 length: 0,
209 };
210 let mut msg = Message::new();
211 msg.write_header(&header)?;
212 match self {
213 Request::Destroy {
214 } => {
215 header.opcode = 0;
216 },
217 Request::CreatePositioner {
218 id,
219 } => {
220 msg.write_arg(Arg::NewId(id))?;
221 header.opcode = 1;
222 },
223 Request::GetXdgSurface {
224 id,
225 surface,
226 } => {
227 msg.write_arg(Arg::NewId(id))?;
228 msg.write_arg(Arg::Object(surface))?;
229 header.opcode = 2;
230 },
231 Request::Pong {
232 serial,
233 } => {
234 msg.write_arg(Arg::Uint(serial))?;
235 header.opcode = 3;
236 },
237 }
238 header.length = msg.bytes().len() as u16;
239 msg.rewind();
240 msg.write_header(&header)?;
241 Ok(msg)
242 }
243}
244impl FromArgs for Event {
245 fn from_args(op: u16, mut args: Vec<Arg>) -> Result<Self, anyhow::Error> {
246 match op {
247 0 /* ping */ => {
248 let mut iter = args.into_iter();
249 Ok(Event::Ping {
250 serial: iter.next()
251 .ok_or(DecodeError::InsufficientArgs)?
252 .as_uint()?,
253
254 })
255 },
256 _ => {
257 Err(DecodeError::InvalidOpcode(op).into())
258 },
259 }
260 }
261}
262#[derive(Copy, Clone, Debug, Eq, PartialEq)]
263#[repr(u32)]
264pub enum Error {
265 /// given wl_surface has another role,
266 Role = 0,
267 /// xdg_wm_base was destroyed before children,
268 DefunctSurfaces = 1,
269 /// the client tried to map or destroy a non-topmost popup,
270 NotTheTopmostPopup = 2,
271 /// the client specified an invalid popup parent surface,
272 InvalidPopupParent = 3,
273 /// the client provided an invalid surface state,
274 InvalidSurfaceState = 4,
275 /// the client provided an invalid positioner,
276 InvalidPositioner = 5,
277}
278
279impl Error {
280 pub fn from_bits(v: u32) -> Option<Self> {
281 match v {
282 0 => Some(Error::Role),
283 1 => Some(Error::DefunctSurfaces),
284 2 => Some(Error::NotTheTopmostPopup),
285 3 => Some(Error::InvalidPopupParent),
286 4 => Some(Error::InvalidSurfaceState),
287 5 => Some(Error::InvalidPositioner),
288 _ => None,
289 }
290 }
291
292 pub fn bits(&self) -> u32 {
293 *self as u32
294 }
295}
296impl Into<Arg> for Error {
297 fn into(self) -> Arg {
298 Arg::Uint(self.bits())
299 }
300}
301} // mod xdg_wm_base
302
303pub use crate::xdg_wm_base::XdgWmBase;
304pub use crate::xdg_wm_base::Request as XdgWmBaseRequest;
305pub use crate::xdg_wm_base::Event as XdgWmBaseEvent;
306pub mod xdg_positioner {
307use super::*;
308
309/// child surface positioner
310///
311/// The xdg_positioner provides a collection of rules for the placement of a
312/// child surface relative to a parent surface. Rules can be defined to ensure
313/// the child surface remains within the visible area's borders, and to
314/// specify how the child surface changes its position, such as sliding along
315/// an axis, or flipping around a rectangle. These positioner-created rules are
316/// constrained by the requirement that a child surface must intersect with or
317/// be at least partially adjacent to its parent surface.
318///
319/// See the various requests for details about possible rules.
320///
321/// At the time of the request, the compositor makes a copy of the rules
322/// specified by the xdg_positioner. Thus, after the request is complete the
323/// xdg_positioner object can be destroyed or reused; further changes to the
324/// object will have no effect on previous usages.
325///
326/// For an xdg_positioner object to be considered complete, it must have a
327/// non-zero size set by set_size, and a non-zero anchor rectangle set by
328/// set_anchor_rect. Passing an incomplete xdg_positioner object when
329/// positioning a surface raises an error.
330#[derive(Debug)]
331pub struct XdgPositioner;
332
333impl Interface for XdgPositioner {
334 const NAME: &'static str = "xdg_positioner";
335 const VERSION: u32 = 3;
336 const REQUESTS: MessageGroupSpec = MessageGroupSpec(&[
337 // destroy
338 MessageSpec(&[
339 ]),
340 // set_size
341 MessageSpec(&[
342 ArgKind::Int,
343 ArgKind::Int,
344 ]),
345 // set_anchor_rect
346 MessageSpec(&[
347 ArgKind::Int,
348 ArgKind::Int,
349 ArgKind::Int,
350 ArgKind::Int,
351 ]),
352 // set_anchor
353 MessageSpec(&[
354 ArgKind::Uint,
355 ]),
356 // set_gravity
357 MessageSpec(&[
358 ArgKind::Uint,
359 ]),
360 // set_constraint_adjustment
361 MessageSpec(&[
362 ArgKind::Uint,
363 ]),
364 // set_offset
365 MessageSpec(&[
366 ArgKind::Int,
367 ArgKind::Int,
368 ]),
369 // set_reactive
370 MessageSpec(&[
371 ]),
372 // set_parent_size
373 MessageSpec(&[
374 ArgKind::Int,
375 ArgKind::Int,
376 ]),
377 // set_parent_configure
378 MessageSpec(&[
379 ArgKind::Uint,
380 ]),
381 ]);
382 const EVENTS: MessageGroupSpec = MessageGroupSpec(&[
383 ]);
384 type Incoming = Event;
385 type Outgoing = Request;
386}
387
388#[derive(Debug)]
389pub enum Request {
390
391 /// destroy the xdg_positioner object
392 ///
393 /// Notify the compositor that the xdg_positioner will no longer be used.
394 Destroy,
395
396 /// set the size of the to-be positioned rectangle
397 ///
398 /// Set the size of the surface that is to be positioned with the positioner
399 /// object. The size is in surface-local coordinates and corresponds to the
400 /// window geometry. See xdg_surface.set_window_geometry.
401 ///
402 /// If a zero or negative size is set the invalid_input error is raised.
403 SetSize {
404 /// width of positioned rectangle
405 width: i32,
406 /// height of positioned rectangle
407 height: i32,
408 },
409
410 /// set the anchor rectangle within the parent surface
411 ///
412 /// Specify the anchor rectangle within the parent surface that the child
413 /// surface will be placed relative to. The rectangle is relative to the
414 /// window geometry as defined by xdg_surface.set_window_geometry of the
415 /// parent surface.
416 ///
417 /// When the xdg_positioner object is used to position a child surface, the
418 /// anchor rectangle may not extend outside the window geometry of the
419 /// positioned child's parent surface.
420 ///
421 /// If a negative size is set the invalid_input error is raised.
422 SetAnchorRect {
423 /// x position of anchor rectangle
424 x: i32,
425 /// y position of anchor rectangle
426 y: i32,
427 /// width of anchor rectangle
428 width: i32,
429 /// height of anchor rectangle
430 height: i32,
431 },
432
433 /// set anchor rectangle anchor
434 ///
435 /// Defines the anchor point for the anchor rectangle. The specified anchor
436 /// is used derive an anchor point that the child surface will be
437 /// positioned relative to. If a corner anchor is set (e.g. 'top_left' or
438 /// 'bottom_right'), the anchor point will be at the specified corner;
439 /// otherwise, the derived anchor point will be centered on the specified
440 /// edge, or in the center of the anchor rectangle if no edge is specified.
441 SetAnchor {
442 /// anchor
443 anchor: Anchor,
444 },
445
446 /// set child surface gravity
447 ///
448 /// Defines in what direction a surface should be positioned, relative to
449 /// the anchor point of the parent surface. If a corner gravity is
450 /// specified (e.g. 'bottom_right' or 'top_left'), then the child surface
451 /// will be placed towards the specified gravity; otherwise, the child
452 /// surface will be centered over the anchor point on any axis that had no
453 /// gravity specified.
454 SetGravity {
455 /// gravity direction
456 gravity: Gravity,
457 },
458
459 /// set the adjustment to be done when constrained
460 ///
461 /// Specify how the window should be positioned if the originally intended
462 /// position caused the surface to be constrained, meaning at least
463 /// partially outside positioning boundaries set by the compositor. The
464 /// adjustment is set by constructing a bitmask describing the adjustment to
465 /// be made when the surface is constrained on that axis.
466 ///
467 /// If no bit for one axis is set, the compositor will assume that the child
468 /// surface should not change its position on that axis when constrained.
469 ///
470 /// If more than one bit for one axis is set, the order of how adjustments
471 /// are applied is specified in the corresponding adjustment descriptions.
472 ///
473 /// The default adjustment is none.
474 SetConstraintAdjustment {
475 /// bit mask of constraint adjustments
476 constraint_adjustment: u32,
477 },
478
479 /// set surface position offset
480 ///
481 /// Specify the surface position offset relative to the position of the
482 /// anchor on the anchor rectangle and the anchor on the surface. For
483 /// example if the anchor of the anchor rectangle is at (x, y), the surface
484 /// has the gravity bottom|right, and the offset is (ox, oy), the calculated
485 /// surface position will be (x + ox, y + oy). The offset position of the
486 /// surface is the one used for constraint testing. See
487 /// set_constraint_adjustment.
488 ///
489 /// An example use case is placing a popup menu on top of a user interface
490 /// element, while aligning the user interface element of the parent surface
491 /// with some user interface element placed somewhere in the popup surface.
492 SetOffset {
493 /// surface position x offset
494 x: i32,
495 /// surface position y offset
496 y: i32,
497 },
498
499 /// continuously reconstrain the surface
500 ///
501 /// When set reactive, the surface is reconstrained if the conditions used
502 /// for constraining changed, e.g. the parent window moved.
503 ///
504 /// If the conditions changed and the popup was reconstrained, an
505 /// xdg_popup.configure event is sent with updated geometry, followed by an
506 /// xdg_surface.configure event.
507 SetReactive,
508
509 ///
510 /// Set the parent window geometry the compositor should use when
511 /// positioning the popup. The compositor may use this information to
512 /// determine the future state the popup should be constrained using. If
513 /// this doesn't match the dimension of the parent the popup is eventually
514 /// positioned against, the behavior is undefined.
515 ///
516 /// The arguments are given in the surface-local coordinate space.
517 SetParentSize {
518 /// future window geometry width of parent
519 parent_width: i32,
520 /// future window geometry height of parent
521 parent_height: i32,
522 },
523
524 /// set parent configure this is a response to
525 ///
526 /// Set the serial of an xdg_surface.configure event this positioner will be
527 /// used in response to. The compositor may use this information together
528 /// with set_parent_size to determine what future state the popup should be
529 /// constrained using.
530 SetParentConfigure {
531 /// serial of parent configure event
532 serial: u32,
533 },
534}
535
536impl MessageType for Request {
537 fn log(&self, this: ObjectId) -> String {
538 match *self {
539 Request::Destroy {
540 } => {
541 format!("xdg_positioner@{:?}::destroy()", this)
542 }
543 Request::SetSize {
544 ref width,
545 ref height,
546 } => {
547 format!("xdg_positioner@{:?}::set_size(width: {:?}, height: {:?})", this, width, height)
548 }
549 Request::SetAnchorRect {
550 ref x,
551 ref y,
552 ref width,
553 ref height,
554 } => {
555 format!("xdg_positioner@{:?}::set_anchor_rect(x: {:?}, y: {:?}, width: {:?}, height: {:?})", this, x, y, width, height)
556 }
557 Request::SetAnchor {
558 ref anchor,
559 } => {
560 format!("xdg_positioner@{:?}::set_anchor(anchor: {:?})", this, anchor)
561 }
562 Request::SetGravity {
563 ref gravity,
564 } => {
565 format!("xdg_positioner@{:?}::set_gravity(gravity: {:?})", this, gravity)
566 }
567 Request::SetConstraintAdjustment {
568 ref constraint_adjustment,
569 } => {
570 format!("xdg_positioner@{:?}::set_constraint_adjustment(constraint_adjustment: {:?})", this, constraint_adjustment)
571 }
572 Request::SetOffset {
573 ref x,
574 ref y,
575 } => {
576 format!("xdg_positioner@{:?}::set_offset(x: {:?}, y: {:?})", this, x, y)
577 }
578 Request::SetReactive {
579 } => {
580 format!("xdg_positioner@{:?}::set_reactive()", this)
581 }
582 Request::SetParentSize {
583 ref parent_width,
584 ref parent_height,
585 } => {
586 format!("xdg_positioner@{:?}::set_parent_size(parent_width: {:?}, parent_height: {:?})", this, parent_width, parent_height)
587 }
588 Request::SetParentConfigure {
589 ref serial,
590 } => {
591 format!("xdg_positioner@{:?}::set_parent_configure(serial: {:?})", this, serial)
592 }
593 }
594 }
595 fn message_name(&self) -> &'static std::ffi::CStr{
596 match *self {
597 Request::Destroy { .. } => c"xdg_positioner::destroy",
598 Request::SetSize { .. } => c"xdg_positioner::set_size",
599 Request::SetAnchorRect { .. } => c"xdg_positioner::set_anchor_rect",
600 Request::SetAnchor { .. } => c"xdg_positioner::set_anchor",
601 Request::SetGravity { .. } => c"xdg_positioner::set_gravity",
602 Request::SetConstraintAdjustment { .. } => c"xdg_positioner::set_constraint_adjustment",
603 Request::SetOffset { .. } => c"xdg_positioner::set_offset",
604 Request::SetReactive { .. } => c"xdg_positioner::set_reactive",
605 Request::SetParentSize { .. } => c"xdg_positioner::set_parent_size",
606 Request::SetParentConfigure { .. } => c"xdg_positioner::set_parent_configure",
607 }
608 }
609}
610#[derive(Debug)]
611pub enum Event {
612}
613
614impl MessageType for Event {
615 fn log(&self, this: ObjectId) -> String {
616 match *self {
617 }
618 }
619 fn message_name(&self) -> &'static std::ffi::CStr{
620 match *self {
621 }
622 }
623}
624impl IntoMessage for Request {
625 type Error = EncodeError;
626 fn into_message(self, id: u32) -> Result<Message, <Self as IntoMessage>::Error> {
627 let mut header = MessageHeader {
628 sender: id,
629 opcode: 0,
630 length: 0,
631 };
632 let mut msg = Message::new();
633 msg.write_header(&header)?;
634 match self {
635 Request::Destroy {
636 } => {
637 header.opcode = 0;
638 },
639 Request::SetSize {
640 width,
641 height,
642 } => {
643 msg.write_arg(Arg::Int(width))?;
644 msg.write_arg(Arg::Int(height))?;
645 header.opcode = 1;
646 },
647 Request::SetAnchorRect {
648 x,
649 y,
650 width,
651 height,
652 } => {
653 msg.write_arg(Arg::Int(x))?;
654 msg.write_arg(Arg::Int(y))?;
655 msg.write_arg(Arg::Int(width))?;
656 msg.write_arg(Arg::Int(height))?;
657 header.opcode = 2;
658 },
659 Request::SetAnchor {
660 anchor,
661 } => {
662 msg.write_arg(Arg::Uint(anchor.bits()))?;
663 header.opcode = 3;
664 },
665 Request::SetGravity {
666 gravity,
667 } => {
668 msg.write_arg(Arg::Uint(gravity.bits()))?;
669 header.opcode = 4;
670 },
671 Request::SetConstraintAdjustment {
672 constraint_adjustment,
673 } => {
674 msg.write_arg(Arg::Uint(constraint_adjustment))?;
675 header.opcode = 5;
676 },
677 Request::SetOffset {
678 x,
679 y,
680 } => {
681 msg.write_arg(Arg::Int(x))?;
682 msg.write_arg(Arg::Int(y))?;
683 header.opcode = 6;
684 },
685 Request::SetReactive {
686 } => {
687 header.opcode = 7;
688 },
689 Request::SetParentSize {
690 parent_width,
691 parent_height,
692 } => {
693 msg.write_arg(Arg::Int(parent_width))?;
694 msg.write_arg(Arg::Int(parent_height))?;
695 header.opcode = 8;
696 },
697 Request::SetParentConfigure {
698 serial,
699 } => {
700 msg.write_arg(Arg::Uint(serial))?;
701 header.opcode = 9;
702 },
703 }
704 header.length = msg.bytes().len() as u16;
705 msg.rewind();
706 msg.write_header(&header)?;
707 Ok(msg)
708 }
709}
710impl FromArgs for Event {
711 fn from_args(op: u16, mut args: Vec<Arg>) -> Result<Self, anyhow::Error> {
712 match op {
713 _ => {
714 Err(DecodeError::InvalidOpcode(op).into())
715 },
716 }
717 }
718}
719#[derive(Copy, Clone, Debug, Eq, PartialEq)]
720#[repr(u32)]
721pub enum Error {
722 /// invalid input provided,
723 InvalidInput = 0,
724}
725
726impl Error {
727 pub fn from_bits(v: u32) -> Option<Self> {
728 match v {
729 0 => Some(Error::InvalidInput),
730 _ => None,
731 }
732 }
733
734 pub fn bits(&self) -> u32 {
735 *self as u32
736 }
737}
738impl Into<Arg> for Error {
739 fn into(self) -> Arg {
740 Arg::Uint(self.bits())
741 }
742}
743#[derive(Copy, Clone, Debug, Eq, PartialEq)]
744#[repr(u32)]
745pub enum Anchor {
746 None = 0,
747 Top = 1,
748 Bottom = 2,
749 Left = 3,
750 Right = 4,
751 TopLeft = 5,
752 BottomLeft = 6,
753 TopRight = 7,
754 BottomRight = 8,
755}
756
757impl Anchor {
758 pub fn from_bits(v: u32) -> Option<Self> {
759 match v {
760 0 => Some(Anchor::None),
761 1 => Some(Anchor::Top),
762 2 => Some(Anchor::Bottom),
763 3 => Some(Anchor::Left),
764 4 => Some(Anchor::Right),
765 5 => Some(Anchor::TopLeft),
766 6 => Some(Anchor::BottomLeft),
767 7 => Some(Anchor::TopRight),
768 8 => Some(Anchor::BottomRight),
769 _ => None,
770 }
771 }
772
773 pub fn bits(&self) -> u32 {
774 *self as u32
775 }
776}
777impl Into<Arg> for Anchor {
778 fn into(self) -> Arg {
779 Arg::Uint(self.bits())
780 }
781}
782#[derive(Copy, Clone, Debug, Eq, PartialEq)]
783#[repr(u32)]
784pub enum Gravity {
785 None = 0,
786 Top = 1,
787 Bottom = 2,
788 Left = 3,
789 Right = 4,
790 TopLeft = 5,
791 BottomLeft = 6,
792 TopRight = 7,
793 BottomRight = 8,
794}
795
796impl Gravity {
797 pub fn from_bits(v: u32) -> Option<Self> {
798 match v {
799 0 => Some(Gravity::None),
800 1 => Some(Gravity::Top),
801 2 => Some(Gravity::Bottom),
802 3 => Some(Gravity::Left),
803 4 => Some(Gravity::Right),
804 5 => Some(Gravity::TopLeft),
805 6 => Some(Gravity::BottomLeft),
806 7 => Some(Gravity::TopRight),
807 8 => Some(Gravity::BottomRight),
808 _ => None,
809 }
810 }
811
812 pub fn bits(&self) -> u32 {
813 *self as u32
814 }
815}
816impl Into<Arg> for Gravity {
817 fn into(self) -> Arg {
818 Arg::Uint(self.bits())
819 }
820}
821::bitflags::bitflags! {
822
823 /// constraint adjustments
824 ///
825 /// The constraint adjustment value define ways the compositor will adjust
826 /// the position of the surface, if the unadjusted position would result
827 /// in the surface being partly constrained.
828 ///
829 /// Whether a surface is considered 'constrained' is left to the compositor
830 /// to determine. For example, the surface may be partly outside the
831 /// compositor's defined 'work area', thus necessitating the child surface's
832 /// position be adjusted until it is entirely inside the work area.
833 ///
834 /// The adjustments can be combined, according to a defined precedence: 1)
835 /// Flip, 2) Slide, 3) Resize.
836 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
837 pub struct ConstraintAdjustment: u32 {
838 const None = 0;
839 const SlideX = 1;
840 const SlideY = 2;
841 const FlipX = 4;
842 const FlipY = 8;
843 const ResizeX = 16;
844 const ResizeY = 32;
845 }
846}
847impl Into<Arg> for ConstraintAdjustment {
848 fn into(self) -> Arg {
849 Arg::Uint(self.bits())
850 }
851}
852} // mod xdg_positioner
853
854pub use crate::xdg_positioner::XdgPositioner;
855pub use crate::xdg_positioner::Request as XdgPositionerRequest;
856pub use crate::xdg_positioner::Event as XdgPositionerEvent;
857pub mod xdg_surface {
858use super::*;
859
860/// desktop user interface surface base interface
861///
862/// An interface that may be implemented by a wl_surface, for
863/// implementations that provide a desktop-style user interface.
864///
865/// It provides a base set of functionality required to construct user
866/// interface elements requiring management by the compositor, such as
867/// toplevel windows, menus, etc. The types of functionality are split into
868/// xdg_surface roles.
869///
870/// Creating an xdg_surface does not set the role for a wl_surface. In order
871/// to map an xdg_surface, the client must create a role-specific object
872/// using, e.g., get_toplevel, get_popup. The wl_surface for any given
873/// xdg_surface can have at most one role, and may not be assigned any role
874/// not based on xdg_surface.
875///
876/// A role must be assigned before any other requests are made to the
877/// xdg_surface object.
878///
879/// The client must call wl_surface.commit on the corresponding wl_surface
880/// for the xdg_surface state to take effect.
881///
882/// Creating an xdg_surface from a wl_surface which has a buffer attached or
883/// committed is a client error, and any attempts by a client to attach or
884/// manipulate a buffer prior to the first xdg_surface.configure call must
885/// also be treated as errors.
886///
887/// After creating a role-specific object and setting it up, the client must
888/// perform an initial commit without any buffer attached. The compositor
889/// will reply with an xdg_surface.configure event. The client must
890/// acknowledge it and is then allowed to attach a buffer to map the surface.
891///
892/// Mapping an xdg_surface-based role surface is defined as making it
893/// possible for the surface to be shown by the compositor. Note that
894/// a mapped surface is not guaranteed to be visible once it is mapped.
895///
896/// For an xdg_surface to be mapped by the compositor, the following
897/// conditions must be met:
898/// (1) the client has assigned an xdg_surface-based role to the surface
899/// (2) the client has set and committed the xdg_surface state and the
900/// role-dependent state to the surface
901/// (3) the client has committed a buffer to the surface
902///
903/// A newly-unmapped surface is considered to have met condition (1) out
904/// of the 3 required conditions for mapping a surface if its role surface
905/// has not been destroyed.
906#[derive(Debug)]
907pub struct XdgSurface;
908
909impl Interface for XdgSurface {
910 const NAME: &'static str = "xdg_surface";
911 const VERSION: u32 = 3;
912 const REQUESTS: MessageGroupSpec = MessageGroupSpec(&[
913 // destroy
914 MessageSpec(&[
915 ]),
916 // get_toplevel
917 MessageSpec(&[
918 ArgKind::NewId,
919 ]),
920 // get_popup
921 MessageSpec(&[
922 ArgKind::NewId,
923 ArgKind::Object,
924 ArgKind::Object,
925 ]),
926 // set_window_geometry
927 MessageSpec(&[
928 ArgKind::Int,
929 ArgKind::Int,
930 ArgKind::Int,
931 ArgKind::Int,
932 ]),
933 // ack_configure
934 MessageSpec(&[
935 ArgKind::Uint,
936 ]),
937 ]);
938 const EVENTS: MessageGroupSpec = MessageGroupSpec(&[
939 // configure
940 MessageSpec(&[
941 ArgKind::Uint,
942 ]),
943 ]);
944 type Incoming = Event;
945 type Outgoing = Request;
946}
947
948#[derive(Debug)]
949pub enum Request {
950
951 /// destroy the xdg_surface
952 ///
953 /// Destroy the xdg_surface object. An xdg_surface must only be destroyed
954 /// after its role object has been destroyed.
955 Destroy,
956
957 /// assign the xdg_toplevel surface role
958 ///
959 /// This creates an xdg_toplevel object for the given xdg_surface and gives
960 /// the associated wl_surface the xdg_toplevel role.
961 ///
962 /// See the documentation of xdg_toplevel for more details about what an
963 /// xdg_toplevel is and how it is used.
964 GetToplevel {
965 id: NewId,
966 },
967
968 /// assign the xdg_popup surface role
969 ///
970 /// This creates an xdg_popup object for the given xdg_surface and gives
971 /// the associated wl_surface the xdg_popup role.
972 ///
973 /// If null is passed as a parent, a parent surface must be specified using
974 /// some other protocol, before committing the initial state.
975 ///
976 /// See the documentation of xdg_popup for more details about what an
977 /// xdg_popup is and how it is used.
978 GetPopup {
979 id: NewId,
980 parent: ObjectId,
981 positioner: ObjectId,
982 },
983
984 /// set the new window geometry
985 ///
986 /// The window geometry of a surface is its "visible bounds" from the
987 /// user's perspective. Client-side decorations often have invisible
988 /// portions like drop-shadows which should be ignored for the
989 /// purposes of aligning, placing and constraining windows.
990 ///
991 /// The window geometry is double buffered, and will be applied at the
992 /// time wl_surface.commit of the corresponding wl_surface is called.
993 ///
994 /// When maintaining a position, the compositor should treat the (x, y)
995 /// coordinate of the window geometry as the top left corner of the window.
996 /// A client changing the (x, y) window geometry coordinate should in
997 /// general not alter the position of the window.
998 ///
999 /// Once the window geometry of the surface is set, it is not possible to
1000 /// unset it, and it will remain the same until set_window_geometry is
1001 /// called again, even if a new subsurface or buffer is attached.
1002 ///
1003 /// If never set, the value is the full bounds of the surface,
1004 /// including any subsurfaces. This updates dynamically on every
1005 /// commit. This unset is meant for extremely simple clients.
1006 ///
1007 /// The arguments are given in the surface-local coordinate space of
1008 /// the wl_surface associated with this xdg_surface.
1009 ///
1010 /// The width and height must be greater than zero. Setting an invalid size
1011 /// will raise an error. When applied, the effective window geometry will be
1012 /// the set window geometry clamped to the bounding rectangle of the
1013 /// combined geometry of the surface of the xdg_surface and the associated
1014 /// subsurfaces.
1015 SetWindowGeometry {
1016 x: i32,
1017 y: i32,
1018 width: i32,
1019 height: i32,
1020 },
1021
1022 /// ack a configure event
1023 ///
1024 /// When a configure event is received, if a client commits the
1025 /// surface in response to the configure event, then the client
1026 /// must make an ack_configure request sometime before the commit
1027 /// request, passing along the serial of the configure event.
1028 ///
1029 /// For instance, for toplevel surfaces the compositor might use this
1030 /// information to move a surface to the top left only when the client has
1031 /// drawn itself for the maximized or fullscreen state.
1032 ///
1033 /// If the client receives multiple configure events before it
1034 /// can respond to one, it only has to ack the last configure event.
1035 ///
1036 /// A client is not required to commit immediately after sending
1037 /// an ack_configure request - it may even ack_configure several times
1038 /// before its next surface commit.
1039 ///
1040 /// A client may send multiple ack_configure requests before committing, but
1041 /// only the last request sent before a commit indicates which configure
1042 /// event the client really is responding to.
1043 AckConfigure {
1044 /// the serial from the configure event
1045 serial: u32,
1046 },
1047}
1048
1049impl MessageType for Request {
1050 fn log(&self, this: ObjectId) -> String {
1051 match *self {
1052 Request::Destroy {
1053 } => {
1054 format!("xdg_surface@{:?}::destroy()", this)
1055 }
1056 Request::GetToplevel {
1057 ref id,
1058 } => {
1059 format!("xdg_surface@{:?}::get_toplevel(id: {:?})", this, id)
1060 }
1061 Request::GetPopup {
1062 ref id,
1063 ref parent,
1064 ref positioner,
1065 } => {
1066 format!("xdg_surface@{:?}::get_popup(id: {:?}, parent: {:?}, positioner: {:?})", this, id, parent, positioner)
1067 }
1068 Request::SetWindowGeometry {
1069 ref x,
1070 ref y,
1071 ref width,
1072 ref height,
1073 } => {
1074 format!("xdg_surface@{:?}::set_window_geometry(x: {:?}, y: {:?}, width: {:?}, height: {:?})", this, x, y, width, height)
1075 }
1076 Request::AckConfigure {
1077 ref serial,
1078 } => {
1079 format!("xdg_surface@{:?}::ack_configure(serial: {:?})", this, serial)
1080 }
1081 }
1082 }
1083 fn message_name(&self) -> &'static std::ffi::CStr{
1084 match *self {
1085 Request::Destroy { .. } => c"xdg_surface::destroy",
1086 Request::GetToplevel { .. } => c"xdg_surface::get_toplevel",
1087 Request::GetPopup { .. } => c"xdg_surface::get_popup",
1088 Request::SetWindowGeometry { .. } => c"xdg_surface::set_window_geometry",
1089 Request::AckConfigure { .. } => c"xdg_surface::ack_configure",
1090 }
1091 }
1092}
1093#[derive(Debug)]
1094pub enum Event {
1095
1096 /// suggest a surface change
1097 ///
1098 /// The configure event marks the end of a configure sequence. A configure
1099 /// sequence is a set of one or more events configuring the state of the
1100 /// xdg_surface, including the final xdg_surface.configure event.
1101 ///
1102 /// Where applicable, xdg_surface surface roles will during a configure
1103 /// sequence extend this event as a latched state sent as events before the
1104 /// xdg_surface.configure event. Such events should be considered to make up
1105 /// a set of atomically applied configuration states, where the
1106 /// xdg_surface.configure commits the accumulated state.
1107 ///
1108 /// Clients should arrange their surface for the new states, and then send
1109 /// an ack_configure request with the serial sent in this configure event at
1110 /// some point before committing the new surface.
1111 ///
1112 /// If the client receives multiple configure events before it can respond
1113 /// to one, it is free to discard all but the last event it received.
1114 Configure {
1115 /// serial of the configure event
1116 serial: u32,
1117 },
1118}
1119
1120impl MessageType for Event {
1121 fn log(&self, this: ObjectId) -> String {
1122 match *self {
1123 Event::Configure {
1124 ref serial,
1125 } => {
1126 format!("xdg_surface@{:?}::configure(serial: {:?})", this, serial)
1127 }
1128 }
1129 }
1130 fn message_name(&self) -> &'static std::ffi::CStr{
1131 match *self {
1132 Event::Configure { .. } => c"xdg_surface::configure",
1133 }
1134 }
1135}
1136impl IntoMessage for Request {
1137 type Error = EncodeError;
1138 fn into_message(self, id: u32) -> Result<Message, <Self as IntoMessage>::Error> {
1139 let mut header = MessageHeader {
1140 sender: id,
1141 opcode: 0,
1142 length: 0,
1143 };
1144 let mut msg = Message::new();
1145 msg.write_header(&header)?;
1146 match self {
1147 Request::Destroy {
1148 } => {
1149 header.opcode = 0;
1150 },
1151 Request::GetToplevel {
1152 id,
1153 } => {
1154 msg.write_arg(Arg::NewId(id))?;
1155 header.opcode = 1;
1156 },
1157 Request::GetPopup {
1158 id,
1159 parent,
1160 positioner,
1161 } => {
1162 msg.write_arg(Arg::NewId(id))?;
1163 msg.write_arg(Arg::Object(parent))?;
1164 msg.write_arg(Arg::Object(positioner))?;
1165 header.opcode = 2;
1166 },
1167 Request::SetWindowGeometry {
1168 x,
1169 y,
1170 width,
1171 height,
1172 } => {
1173 msg.write_arg(Arg::Int(x))?;
1174 msg.write_arg(Arg::Int(y))?;
1175 msg.write_arg(Arg::Int(width))?;
1176 msg.write_arg(Arg::Int(height))?;
1177 header.opcode = 3;
1178 },
1179 Request::AckConfigure {
1180 serial,
1181 } => {
1182 msg.write_arg(Arg::Uint(serial))?;
1183 header.opcode = 4;
1184 },
1185 }
1186 header.length = msg.bytes().len() as u16;
1187 msg.rewind();
1188 msg.write_header(&header)?;
1189 Ok(msg)
1190 }
1191}
1192impl FromArgs for Event {
1193 fn from_args(op: u16, mut args: Vec<Arg>) -> Result<Self, anyhow::Error> {
1194 match op {
1195 0 /* configure */ => {
1196 let mut iter = args.into_iter();
1197 Ok(Event::Configure {
1198 serial: iter.next()
1199 .ok_or(DecodeError::InsufficientArgs)?
1200 .as_uint()?,
1201
1202 })
1203 },
1204 _ => {
1205 Err(DecodeError::InvalidOpcode(op).into())
1206 },
1207 }
1208 }
1209}
1210#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1211#[repr(u32)]
1212pub enum Error {
1213 NotConstructed = 1,
1214 AlreadyConstructed = 2,
1215 UnconfiguredBuffer = 3,
1216}
1217
1218impl Error {
1219 pub fn from_bits(v: u32) -> Option<Self> {
1220 match v {
1221 1 => Some(Error::NotConstructed),
1222 2 => Some(Error::AlreadyConstructed),
1223 3 => Some(Error::UnconfiguredBuffer),
1224 _ => None,
1225 }
1226 }
1227
1228 pub fn bits(&self) -> u32 {
1229 *self as u32
1230 }
1231}
1232impl Into<Arg> for Error {
1233 fn into(self) -> Arg {
1234 Arg::Uint(self.bits())
1235 }
1236}
1237} // mod xdg_surface
1238
1239pub use crate::xdg_surface::XdgSurface;
1240pub use crate::xdg_surface::Request as XdgSurfaceRequest;
1241pub use crate::xdg_surface::Event as XdgSurfaceEvent;
1242pub mod xdg_toplevel {
1243use super::*;
1244
1245/// toplevel surface
1246///
1247/// This interface defines an xdg_surface role which allows a surface to,
1248/// among other things, set window-like properties such as maximize,
1249/// fullscreen, and minimize, set application-specific metadata like title and
1250/// id, and well as trigger user interactive operations such as interactive
1251/// resize and move.
1252///
1253/// Unmapping an xdg_toplevel means that the surface cannot be shown
1254/// by the compositor until it is explicitly mapped again.
1255/// All active operations (e.g., move, resize) are canceled and all
1256/// attributes (e.g. title, state, stacking, ...) are discarded for
1257/// an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
1258/// the state it had right after xdg_surface.get_toplevel. The client
1259/// can re-map the toplevel by perfoming a commit without any buffer
1260/// attached, waiting for a configure event and handling it as usual (see
1261/// xdg_surface description).
1262///
1263/// Attaching a null buffer to a toplevel unmaps the surface.
1264#[derive(Debug)]
1265pub struct XdgToplevel;
1266
1267impl Interface for XdgToplevel {
1268 const NAME: &'static str = "xdg_toplevel";
1269 const VERSION: u32 = 3;
1270 const REQUESTS: MessageGroupSpec = MessageGroupSpec(&[
1271 // destroy
1272 MessageSpec(&[
1273 ]),
1274 // set_parent
1275 MessageSpec(&[
1276 ArgKind::Object,
1277 ]),
1278 // set_title
1279 MessageSpec(&[
1280 ArgKind::String,
1281 ]),
1282 // set_app_id
1283 MessageSpec(&[
1284 ArgKind::String,
1285 ]),
1286 // show_window_menu
1287 MessageSpec(&[
1288 ArgKind::Object,
1289 ArgKind::Uint,
1290 ArgKind::Int,
1291 ArgKind::Int,
1292 ]),
1293 // move
1294 MessageSpec(&[
1295 ArgKind::Object,
1296 ArgKind::Uint,
1297 ]),
1298 // resize
1299 MessageSpec(&[
1300 ArgKind::Object,
1301 ArgKind::Uint,
1302 ArgKind::Uint,
1303 ]),
1304 // set_max_size
1305 MessageSpec(&[
1306 ArgKind::Int,
1307 ArgKind::Int,
1308 ]),
1309 // set_min_size
1310 MessageSpec(&[
1311 ArgKind::Int,
1312 ArgKind::Int,
1313 ]),
1314 // set_maximized
1315 MessageSpec(&[
1316 ]),
1317 // unset_maximized
1318 MessageSpec(&[
1319 ]),
1320 // set_fullscreen
1321 MessageSpec(&[
1322 ArgKind::Object,
1323 ]),
1324 // unset_fullscreen
1325 MessageSpec(&[
1326 ]),
1327 // set_minimized
1328 MessageSpec(&[
1329 ]),
1330 ]);
1331 const EVENTS: MessageGroupSpec = MessageGroupSpec(&[
1332 // configure
1333 MessageSpec(&[
1334 ArgKind::Int,
1335 ArgKind::Int,
1336 ArgKind::Array,
1337 ]),
1338 // close
1339 MessageSpec(&[
1340 ]),
1341 ]);
1342 type Incoming = Event;
1343 type Outgoing = Request;
1344}
1345
1346#[derive(Debug)]
1347pub enum Request {
1348
1349 /// destroy the xdg_toplevel
1350 ///
1351 /// This request destroys the role surface and unmaps the surface;
1352 /// see "Unmapping" behavior in interface section for details.
1353 Destroy,
1354
1355 /// set the parent of this surface
1356 ///
1357 /// Set the "parent" of this surface. This surface should be stacked
1358 /// above the parent surface and all other ancestor surfaces.
1359 ///
1360 /// Parent windows should be set on dialogs, toolboxes, or other
1361 /// "auxiliary" surfaces, so that the parent is raised when the dialog
1362 /// is raised.
1363 ///
1364 /// Setting a null parent for a child window removes any parent-child
1365 /// relationship for the child. Setting a null parent for a window which
1366 /// currently has no parent is a no-op.
1367 ///
1368 /// If the parent is unmapped then its children are managed as
1369 /// though the parent of the now-unmapped parent has become the
1370 /// parent of this surface. If no parent exists for the now-unmapped
1371 /// parent then the children are managed as though they have no
1372 /// parent surface.
1373 SetParent {
1374 parent: ObjectId,
1375 },
1376
1377 /// set surface title
1378 ///
1379 /// Set a short title for the surface.
1380 ///
1381 /// This string may be used to identify the surface in a task bar,
1382 /// window list, or other user interface elements provided by the
1383 /// compositor.
1384 ///
1385 /// The string must be encoded in UTF-8.
1386 SetTitle {
1387 title: String,
1388 },
1389
1390 /// set application ID
1391 ///
1392 /// Set an application identifier for the surface.
1393 ///
1394 /// The app ID identifies the general class of applications to which
1395 /// the surface belongs. The compositor can use this to group multiple
1396 /// surfaces together, or to determine how to launch a new application.
1397 ///
1398 /// For D-Bus activatable applications, the app ID is used as the D-Bus
1399 /// service name.
1400 ///
1401 /// The compositor shell will try to group application surfaces together
1402 /// by their app ID. As a best practice, it is suggested to select app
1403 /// ID's that match the basename of the application's .desktop file.
1404 /// For example, "org.freedesktop.FooViewer" where the .desktop file is
1405 /// "org.freedesktop.FooViewer.desktop".
1406 ///
1407 /// Like other properties, a set_app_id request can be sent after the
1408 /// xdg_toplevel has been mapped to update the property.
1409 ///
1410 /// See the desktop-entry specification [0] for more details on
1411 /// application identifiers and how they relate to well-known D-Bus
1412 /// names and .desktop files.
1413 ///
1414 /// [0] http://standards.freedesktop.org/desktop-entry-spec/
1415 SetAppId {
1416 app_id: String,
1417 },
1418
1419 /// show the window menu
1420 ///
1421 /// Clients implementing client-side decorations might want to show
1422 /// a context menu when right-clicking on the decorations, giving the
1423 /// user a menu that they can use to maximize or minimize the window.
1424 ///
1425 /// This request asks the compositor to pop up such a window menu at
1426 /// the given position, relative to the local surface coordinates of
1427 /// the parent surface. There are no guarantees as to what menu items
1428 /// the window menu contains.
1429 ///
1430 /// This request must be used in response to some sort of user action
1431 /// like a button press, key press, or touch down event.
1432 ShowWindowMenu {
1433 /// the wl_seat of the user event
1434 seat: ObjectId,
1435 /// the serial of the user event
1436 serial: u32,
1437 /// the x position to pop up the window menu at
1438 x: i32,
1439 /// the y position to pop up the window menu at
1440 y: i32,
1441 },
1442
1443 /// start an interactive move
1444 ///
1445 /// Start an interactive, user-driven move of the surface.
1446 ///
1447 /// This request must be used in response to some sort of user action
1448 /// like a button press, key press, or touch down event. The passed
1449 /// serial is used to determine the type of interactive move (touch,
1450 /// pointer, etc).
1451 ///
1452 /// The server may ignore move requests depending on the state of
1453 /// the surface (e.g. fullscreen or maximized), or if the passed serial
1454 /// is no longer valid.
1455 ///
1456 /// If triggered, the surface will lose the focus of the device
1457 /// (wl_pointer, wl_touch, etc) used for the move. It is up to the
1458 /// compositor to visually indicate that the move is taking place, such as
1459 /// updating a pointer cursor, during the move. There is no guarantee
1460 /// that the device focus will return when the move is completed.
1461 Move {
1462 /// the wl_seat of the user event
1463 seat: ObjectId,
1464 /// the serial of the user event
1465 serial: u32,
1466 },
1467
1468 /// start an interactive resize
1469 ///
1470 /// Start a user-driven, interactive resize of the surface.
1471 ///
1472 /// This request must be used in response to some sort of user action
1473 /// like a button press, key press, or touch down event. The passed
1474 /// serial is used to determine the type of interactive resize (touch,
1475 /// pointer, etc).
1476 ///
1477 /// The server may ignore resize requests depending on the state of
1478 /// the surface (e.g. fullscreen or maximized).
1479 ///
1480 /// If triggered, the client will receive configure events with the
1481 /// "resize" state enum value and the expected sizes. See the "resize"
1482 /// enum value for more details about what is required. The client
1483 /// must also acknowledge configure events using "ack_configure". After
1484 /// the resize is completed, the client will receive another "configure"
1485 /// event without the resize state.
1486 ///
1487 /// If triggered, the surface also will lose the focus of the device
1488 /// (wl_pointer, wl_touch, etc) used for the resize. It is up to the
1489 /// compositor to visually indicate that the resize is taking place,
1490 /// such as updating a pointer cursor, during the resize. There is no
1491 /// guarantee that the device focus will return when the resize is
1492 /// completed.
1493 ///
1494 /// The edges parameter specifies how the surface should be resized,
1495 /// and is one of the values of the resize_edge enum. The compositor
1496 /// may use this information to update the surface position for
1497 /// example when dragging the top left corner. The compositor may also
1498 /// use this information to adapt its behavior, e.g. choose an
1499 /// appropriate cursor image.
1500 Resize {
1501 /// the wl_seat of the user event
1502 seat: ObjectId,
1503 /// the serial of the user event
1504 serial: u32,
1505 /// which edge or corner is being dragged
1506 edges: ResizeEdge,
1507 },
1508
1509 /// set the maximum size
1510 ///
1511 /// Set a maximum size for the window.
1512 ///
1513 /// The client can specify a maximum size so that the compositor does
1514 /// not try to configure the window beyond this size.
1515 ///
1516 /// The width and height arguments are in window geometry coordinates.
1517 /// See xdg_surface.set_window_geometry.
1518 ///
1519 /// Values set in this way are double-buffered. They will get applied
1520 /// on the next commit.
1521 ///
1522 /// The compositor can use this information to allow or disallow
1523 /// different states like maximize or fullscreen and draw accurate
1524 /// animations.
1525 ///
1526 /// Similarly, a tiling window manager may use this information to
1527 /// place and resize client windows in a more effective way.
1528 ///
1529 /// The client should not rely on the compositor to obey the maximum
1530 /// size. The compositor may decide to ignore the values set by the
1531 /// client and request a larger size.
1532 ///
1533 /// If never set, or a value of zero in the request, means that the
1534 /// client has no expected maximum size in the given dimension.
1535 /// As a result, a client wishing to reset the maximum size
1536 /// to an unspecified state can use zero for width and height in the
1537 /// request.
1538 ///
1539 /// Requesting a maximum size to be smaller than the minimum size of
1540 /// a surface is illegal and will result in a protocol error.
1541 ///
1542 /// The width and height must be greater than or equal to zero. Using
1543 /// strictly negative values for width and height will result in a
1544 /// protocol error.
1545 SetMaxSize {
1546 width: i32,
1547 height: i32,
1548 },
1549
1550 /// set the minimum size
1551 ///
1552 /// Set a minimum size for the window.
1553 ///
1554 /// The client can specify a minimum size so that the compositor does
1555 /// not try to configure the window below this size.
1556 ///
1557 /// The width and height arguments are in window geometry coordinates.
1558 /// See xdg_surface.set_window_geometry.
1559 ///
1560 /// Values set in this way are double-buffered. They will get applied
1561 /// on the next commit.
1562 ///
1563 /// The compositor can use this information to allow or disallow
1564 /// different states like maximize or fullscreen and draw accurate
1565 /// animations.
1566 ///
1567 /// Similarly, a tiling window manager may use this information to
1568 /// place and resize client windows in a more effective way.
1569 ///
1570 /// The client should not rely on the compositor to obey the minimum
1571 /// size. The compositor may decide to ignore the values set by the
1572 /// client and request a smaller size.
1573 ///
1574 /// If never set, or a value of zero in the request, means that the
1575 /// client has no expected minimum size in the given dimension.
1576 /// As a result, a client wishing to reset the minimum size
1577 /// to an unspecified state can use zero for width and height in the
1578 /// request.
1579 ///
1580 /// Requesting a minimum size to be larger than the maximum size of
1581 /// a surface is illegal and will result in a protocol error.
1582 ///
1583 /// The width and height must be greater than or equal to zero. Using
1584 /// strictly negative values for width and height will result in a
1585 /// protocol error.
1586 SetMinSize {
1587 width: i32,
1588 height: i32,
1589 },
1590
1591 /// maximize the window
1592 ///
1593 /// Maximize the surface.
1594 ///
1595 /// After requesting that the surface should be maximized, the compositor
1596 /// will respond by emitting a configure event. Whether this configure
1597 /// actually sets the window maximized is subject to compositor policies.
1598 /// The client must then update its content, drawing in the configured
1599 /// state. The client must also acknowledge the configure when committing
1600 /// the new content (see ack_configure).
1601 ///
1602 /// It is up to the compositor to decide how and where to maximize the
1603 /// surface, for example which output and what region of the screen should
1604 /// be used.
1605 ///
1606 /// If the surface was already maximized, the compositor will still emit
1607 /// a configure event with the "maximized" state.
1608 ///
1609 /// If the surface is in a fullscreen state, this request has no direct
1610 /// effect. It may alter the state the surface is returned to when
1611 /// unmaximized unless overridden by the compositor.
1612 SetMaximized,
1613
1614 /// unmaximize the window
1615 ///
1616 /// Unmaximize the surface.
1617 ///
1618 /// After requesting that the surface should be unmaximized, the compositor
1619 /// will respond by emitting a configure event. Whether this actually
1620 /// un-maximizes the window is subject to compositor policies.
1621 /// If available and applicable, the compositor will include the window
1622 /// geometry dimensions the window had prior to being maximized in the
1623 /// configure event. The client must then update its content, drawing it in
1624 /// the configured state. The client must also acknowledge the configure
1625 /// when committing the new content (see ack_configure).
1626 ///
1627 /// It is up to the compositor to position the surface after it was
1628 /// unmaximized; usually the position the surface had before maximizing, if
1629 /// applicable.
1630 ///
1631 /// If the surface was already not maximized, the compositor will still
1632 /// emit a configure event without the "maximized" state.
1633 ///
1634 /// If the surface is in a fullscreen state, this request has no direct
1635 /// effect. It may alter the state the surface is returned to when
1636 /// unmaximized unless overridden by the compositor.
1637 UnsetMaximized,
1638
1639 /// set the window as fullscreen on an output
1640 ///
1641 /// Make the surface fullscreen.
1642 ///
1643 /// After requesting that the surface should be fullscreened, the
1644 /// compositor will respond by emitting a configure event. Whether the
1645 /// client is actually put into a fullscreen state is subject to compositor
1646 /// policies. The client must also acknowledge the configure when
1647 /// committing the new content (see ack_configure).
1648 ///
1649 /// The output passed by the request indicates the client's preference as
1650 /// to which display it should be set fullscreen on. If this value is NULL,
1651 /// it's up to the compositor to choose which display will be used to map
1652 /// this surface.
1653 ///
1654 /// If the surface doesn't cover the whole output, the compositor will
1655 /// position the surface in the center of the output and compensate with
1656 /// with border fill covering the rest of the output. The content of the
1657 /// border fill is undefined, but should be assumed to be in some way that
1658 /// attempts to blend into the surrounding area (e.g. solid black).
1659 ///
1660 /// If the fullscreened surface is not opaque, the compositor must make
1661 /// sure that other screen content not part of the same surface tree (made
1662 /// up of subsurfaces, popups or similarly coupled surfaces) are not
1663 /// visible below the fullscreened surface.
1664 SetFullscreen {
1665 output: ObjectId,
1666 },
1667
1668 /// unset the window as fullscreen
1669 ///
1670 /// Make the surface no longer fullscreen.
1671 ///
1672 /// After requesting that the surface should be unfullscreened, the
1673 /// compositor will respond by emitting a configure event.
1674 /// Whether this actually removes the fullscreen state of the client is
1675 /// subject to compositor policies.
1676 ///
1677 /// Making a surface unfullscreen sets states for the surface based on the following:
1678 /// * the state(s) it may have had before becoming fullscreen
1679 /// * any state(s) decided by the compositor
1680 /// * any state(s) requested by the client while the surface was fullscreen
1681 ///
1682 /// The compositor may include the previous window geometry dimensions in
1683 /// the configure event, if applicable.
1684 ///
1685 /// The client must also acknowledge the configure when committing the new
1686 /// content (see ack_configure).
1687 UnsetFullscreen,
1688
1689 /// set the window as minimized
1690 ///
1691 /// Request that the compositor minimize your surface. There is no
1692 /// way to know if the surface is currently minimized, nor is there
1693 /// any way to unset minimization on this surface.
1694 ///
1695 /// If you are looking to throttle redrawing when minimized, please
1696 /// instead use the wl_surface.frame event for this, as this will
1697 /// also work with live previews on windows in Alt-Tab, Expose or
1698 /// similar compositor features.
1699 SetMinimized,
1700}
1701
1702impl MessageType for Request {
1703 fn log(&self, this: ObjectId) -> String {
1704 match *self {
1705 Request::Destroy {
1706 } => {
1707 format!("xdg_toplevel@{:?}::destroy()", this)
1708 }
1709 Request::SetParent {
1710 ref parent,
1711 } => {
1712 format!("xdg_toplevel@{:?}::set_parent(parent: {:?})", this, parent)
1713 }
1714 Request::SetTitle {
1715 ref title,
1716 } => {
1717 format!("xdg_toplevel@{:?}::set_title(title: {:?})", this, title)
1718 }
1719 Request::SetAppId {
1720 ref app_id,
1721 } => {
1722 format!("xdg_toplevel@{:?}::set_app_id(app_id: {:?})", this, app_id)
1723 }
1724 Request::ShowWindowMenu {
1725 ref seat,
1726 ref serial,
1727 ref x,
1728 ref y,
1729 } => {
1730 format!("xdg_toplevel@{:?}::show_window_menu(seat: {:?}, serial: {:?}, x: {:?}, y: {:?})", this, seat, serial, x, y)
1731 }
1732 Request::Move {
1733 ref seat,
1734 ref serial,
1735 } => {
1736 format!("xdg_toplevel@{:?}::move(seat: {:?}, serial: {:?})", this, seat, serial)
1737 }
1738 Request::Resize {
1739 ref seat,
1740 ref serial,
1741 ref edges,
1742 } => {
1743 format!("xdg_toplevel@{:?}::resize(seat: {:?}, serial: {:?}, edges: {:?})", this, seat, serial, edges)
1744 }
1745 Request::SetMaxSize {
1746 ref width,
1747 ref height,
1748 } => {
1749 format!("xdg_toplevel@{:?}::set_max_size(width: {:?}, height: {:?})", this, width, height)
1750 }
1751 Request::SetMinSize {
1752 ref width,
1753 ref height,
1754 } => {
1755 format!("xdg_toplevel@{:?}::set_min_size(width: {:?}, height: {:?})", this, width, height)
1756 }
1757 Request::SetMaximized {
1758 } => {
1759 format!("xdg_toplevel@{:?}::set_maximized()", this)
1760 }
1761 Request::UnsetMaximized {
1762 } => {
1763 format!("xdg_toplevel@{:?}::unset_maximized()", this)
1764 }
1765 Request::SetFullscreen {
1766 ref output,
1767 } => {
1768 format!("xdg_toplevel@{:?}::set_fullscreen(output: {:?})", this, output)
1769 }
1770 Request::UnsetFullscreen {
1771 } => {
1772 format!("xdg_toplevel@{:?}::unset_fullscreen()", this)
1773 }
1774 Request::SetMinimized {
1775 } => {
1776 format!("xdg_toplevel@{:?}::set_minimized()", this)
1777 }
1778 }
1779 }
1780 fn message_name(&self) -> &'static std::ffi::CStr{
1781 match *self {
1782 Request::Destroy { .. } => c"xdg_toplevel::destroy",
1783 Request::SetParent { .. } => c"xdg_toplevel::set_parent",
1784 Request::SetTitle { .. } => c"xdg_toplevel::set_title",
1785 Request::SetAppId { .. } => c"xdg_toplevel::set_app_id",
1786 Request::ShowWindowMenu { .. } => c"xdg_toplevel::show_window_menu",
1787 Request::Move { .. } => c"xdg_toplevel::move",
1788 Request::Resize { .. } => c"xdg_toplevel::resize",
1789 Request::SetMaxSize { .. } => c"xdg_toplevel::set_max_size",
1790 Request::SetMinSize { .. } => c"xdg_toplevel::set_min_size",
1791 Request::SetMaximized { .. } => c"xdg_toplevel::set_maximized",
1792 Request::UnsetMaximized { .. } => c"xdg_toplevel::unset_maximized",
1793 Request::SetFullscreen { .. } => c"xdg_toplevel::set_fullscreen",
1794 Request::UnsetFullscreen { .. } => c"xdg_toplevel::unset_fullscreen",
1795 Request::SetMinimized { .. } => c"xdg_toplevel::set_minimized",
1796 }
1797 }
1798}
1799#[derive(Debug)]
1800pub enum Event {
1801
1802 /// suggest a surface change
1803 ///
1804 /// This configure event asks the client to resize its toplevel surface or
1805 /// to change its state. The configured state should not be applied
1806 /// immediately. See xdg_surface.configure for details.
1807 ///
1808 /// The width and height arguments specify a hint to the window
1809 /// about how its surface should be resized in window geometry
1810 /// coordinates. See set_window_geometry.
1811 ///
1812 /// If the width or height arguments are zero, it means the client
1813 /// should decide its own window dimension. This may happen when the
1814 /// compositor needs to configure the state of the surface but doesn't
1815 /// have any information about any previous or expected dimension.
1816 ///
1817 /// The states listed in the event specify how the width/height
1818 /// arguments should be interpreted, and possibly how it should be
1819 /// drawn.
1820 ///
1821 /// Clients must send an ack_configure in response to this event. See
1822 /// xdg_surface.configure and xdg_surface.ack_configure for details.
1823 Configure {
1824 width: i32,
1825 height: i32,
1826 states: Array,
1827 },
1828
1829 /// surface wants to be closed
1830 ///
1831 /// The close event is sent by the compositor when the user
1832 /// wants the surface to be closed. This should be equivalent to
1833 /// the user clicking the close button in client-side decorations,
1834 /// if your application has any.
1835 ///
1836 /// This is only a request that the user intends to close the
1837 /// window. The client may choose to ignore this request, or show
1838 /// a dialog to ask the user to save their data, etc.
1839 Close,
1840}
1841
1842impl MessageType for Event {
1843 fn log(&self, this: ObjectId) -> String {
1844 match *self {
1845 Event::Configure {
1846 ref width,
1847 ref height,
1848 ref states,
1849 } => {
1850 format!("xdg_toplevel@{:?}::configure(width: {:?}, height: {:?}, states: Array[{}])", this, width, height, states.len())
1851 }
1852 Event::Close {
1853 } => {
1854 format!("xdg_toplevel@{:?}::close()", this)
1855 }
1856 }
1857 }
1858 fn message_name(&self) -> &'static std::ffi::CStr{
1859 match *self {
1860 Event::Configure { .. } => c"xdg_toplevel::configure",
1861 Event::Close { .. } => c"xdg_toplevel::close",
1862 }
1863 }
1864}
1865impl IntoMessage for Request {
1866 type Error = EncodeError;
1867 fn into_message(self, id: u32) -> Result<Message, <Self as IntoMessage>::Error> {
1868 let mut header = MessageHeader {
1869 sender: id,
1870 opcode: 0,
1871 length: 0,
1872 };
1873 let mut msg = Message::new();
1874 msg.write_header(&header)?;
1875 match self {
1876 Request::Destroy {
1877 } => {
1878 header.opcode = 0;
1879 },
1880 Request::SetParent {
1881 parent,
1882 } => {
1883 msg.write_arg(Arg::Object(parent))?;
1884 header.opcode = 1;
1885 },
1886 Request::SetTitle {
1887 title,
1888 } => {
1889 msg.write_arg(Arg::String(title))?;
1890 header.opcode = 2;
1891 },
1892 Request::SetAppId {
1893 app_id,
1894 } => {
1895 msg.write_arg(Arg::String(app_id))?;
1896 header.opcode = 3;
1897 },
1898 Request::ShowWindowMenu {
1899 seat,
1900 serial,
1901 x,
1902 y,
1903 } => {
1904 msg.write_arg(Arg::Object(seat))?;
1905 msg.write_arg(Arg::Uint(serial))?;
1906 msg.write_arg(Arg::Int(x))?;
1907 msg.write_arg(Arg::Int(y))?;
1908 header.opcode = 4;
1909 },
1910 Request::Move {
1911 seat,
1912 serial,
1913 } => {
1914 msg.write_arg(Arg::Object(seat))?;
1915 msg.write_arg(Arg::Uint(serial))?;
1916 header.opcode = 5;
1917 },
1918 Request::Resize {
1919 seat,
1920 serial,
1921 edges,
1922 } => {
1923 msg.write_arg(Arg::Object(seat))?;
1924 msg.write_arg(Arg::Uint(serial))?;
1925 msg.write_arg(Arg::Uint(edges.bits()))?;
1926 header.opcode = 6;
1927 },
1928 Request::SetMaxSize {
1929 width,
1930 height,
1931 } => {
1932 msg.write_arg(Arg::Int(width))?;
1933 msg.write_arg(Arg::Int(height))?;
1934 header.opcode = 7;
1935 },
1936 Request::SetMinSize {
1937 width,
1938 height,
1939 } => {
1940 msg.write_arg(Arg::Int(width))?;
1941 msg.write_arg(Arg::Int(height))?;
1942 header.opcode = 8;
1943 },
1944 Request::SetMaximized {
1945 } => {
1946 header.opcode = 9;
1947 },
1948 Request::UnsetMaximized {
1949 } => {
1950 header.opcode = 10;
1951 },
1952 Request::SetFullscreen {
1953 output,
1954 } => {
1955 msg.write_arg(Arg::Object(output))?;
1956 header.opcode = 11;
1957 },
1958 Request::UnsetFullscreen {
1959 } => {
1960 header.opcode = 12;
1961 },
1962 Request::SetMinimized {
1963 } => {
1964 header.opcode = 13;
1965 },
1966 }
1967 header.length = msg.bytes().len() as u16;
1968 msg.rewind();
1969 msg.write_header(&header)?;
1970 Ok(msg)
1971 }
1972}
1973impl FromArgs for Event {
1974 fn from_args(op: u16, mut args: Vec<Arg>) -> Result<Self, anyhow::Error> {
1975 match op {
1976 0 /* configure */ => {
1977 let mut iter = args.into_iter();
1978 Ok(Event::Configure {
1979 width: iter.next()
1980 .ok_or(DecodeError::InsufficientArgs)?
1981 .as_int()?,
1982 height: iter.next()
1983 .ok_or(DecodeError::InsufficientArgs)?
1984 .as_int()?,
1985 states: iter.next()
1986 .ok_or(DecodeError::InsufficientArgs)?
1987 .as_array()?,
1988
1989 })
1990 },
1991 1 /* close */ => {
1992 let mut iter = args.into_iter();
1993 Ok(Event::Close {
1994
1995 })
1996 },
1997 _ => {
1998 Err(DecodeError::InvalidOpcode(op).into())
1999 },
2000 }
2001 }
2002}
2003
2004/// edge values for resizing
2005///
2006/// These values are used to indicate which edge of a surface
2007/// is being dragged in a resize operation.
2008#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2009#[repr(u32)]
2010pub enum ResizeEdge {
2011 None = 0,
2012 Top = 1,
2013 Bottom = 2,
2014 Left = 4,
2015 TopLeft = 5,
2016 BottomLeft = 6,
2017 Right = 8,
2018 TopRight = 9,
2019 BottomRight = 10,
2020}
2021
2022impl ResizeEdge {
2023 pub fn from_bits(v: u32) -> Option<Self> {
2024 match v {
2025 0 => Some(ResizeEdge::None),
2026 1 => Some(ResizeEdge::Top),
2027 2 => Some(ResizeEdge::Bottom),
2028 4 => Some(ResizeEdge::Left),
2029 5 => Some(ResizeEdge::TopLeft),
2030 6 => Some(ResizeEdge::BottomLeft),
2031 8 => Some(ResizeEdge::Right),
2032 9 => Some(ResizeEdge::TopRight),
2033 10 => Some(ResizeEdge::BottomRight),
2034 _ => None,
2035 }
2036 }
2037
2038 pub fn bits(&self) -> u32 {
2039 *self as u32
2040 }
2041}
2042impl Into<Arg> for ResizeEdge {
2043 fn into(self) -> Arg {
2044 Arg::Uint(self.bits())
2045 }
2046}
2047
2048/// types of state on the surface
2049///
2050/// The different state values used on the surface. This is designed for
2051/// state values like maximized, fullscreen. It is paired with the
2052/// configure event to ensure that both the client and the compositor
2053/// setting the state can be synchronized.
2054///
2055/// States set in this way are double-buffered. They will get applied on
2056/// the next commit.
2057#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2058#[repr(u32)]
2059pub enum State {
2060 /// the surface is maximized,
2061 Maximized = 1,
2062 /// the surface is fullscreen,
2063 Fullscreen = 2,
2064 /// the surface is being resized,
2065 Resizing = 3,
2066 /// the surface is now activated,
2067 Activated = 4,
2068 TiledLeft = 5,
2069 TiledRight = 6,
2070 TiledTop = 7,
2071 TiledBottom = 8,
2072}
2073
2074impl State {
2075 pub fn from_bits(v: u32) -> Option<Self> {
2076 match v {
2077 1 => Some(State::Maximized),
2078 2 => Some(State::Fullscreen),
2079 3 => Some(State::Resizing),
2080 4 => Some(State::Activated),
2081 5 => Some(State::TiledLeft),
2082 6 => Some(State::TiledRight),
2083 7 => Some(State::TiledTop),
2084 8 => Some(State::TiledBottom),
2085 _ => None,
2086 }
2087 }
2088
2089 pub fn bits(&self) -> u32 {
2090 *self as u32
2091 }
2092}
2093impl Into<Arg> for State {
2094 fn into(self) -> Arg {
2095 Arg::Uint(self.bits())
2096 }
2097}
2098} // mod xdg_toplevel
2099
2100pub use crate::xdg_toplevel::XdgToplevel;
2101pub use crate::xdg_toplevel::Request as XdgToplevelRequest;
2102pub use crate::xdg_toplevel::Event as XdgToplevelEvent;
2103pub mod xdg_popup {
2104use super::*;
2105
2106/// short-lived, popup surfaces for menus
2107///
2108/// A popup surface is a short-lived, temporary surface. It can be used to
2109/// implement for example menus, popovers, tooltips and other similar user
2110/// interface concepts.
2111///
2112/// A popup can be made to take an explicit grab. See xdg_popup.grab for
2113/// details.
2114///
2115/// When the popup is dismissed, a popup_done event will be sent out, and at
2116/// the same time the surface will be unmapped. See the xdg_popup.popup_done
2117/// event for details.
2118///
2119/// Explicitly destroying the xdg_popup object will also dismiss the popup and
2120/// unmap the surface. Clients that want to dismiss the popup when another
2121/// surface of their own is clicked should dismiss the popup using the destroy
2122/// request.
2123///
2124/// A newly created xdg_popup will be stacked on top of all previously created
2125/// xdg_popup surfaces associated with the same xdg_toplevel.
2126///
2127/// The parent of an xdg_popup must be mapped (see the xdg_surface
2128/// description) before the xdg_popup itself.
2129///
2130/// The client must call wl_surface.commit on the corresponding wl_surface
2131/// for the xdg_popup state to take effect.
2132#[derive(Debug)]
2133pub struct XdgPopup;
2134
2135impl Interface for XdgPopup {
2136 const NAME: &'static str = "xdg_popup";
2137 const VERSION: u32 = 3;
2138 const REQUESTS: MessageGroupSpec = MessageGroupSpec(&[
2139 // destroy
2140 MessageSpec(&[
2141 ]),
2142 // grab
2143 MessageSpec(&[
2144 ArgKind::Object,
2145 ArgKind::Uint,
2146 ]),
2147 // reposition
2148 MessageSpec(&[
2149 ArgKind::Object,
2150 ArgKind::Uint,
2151 ]),
2152 ]);
2153 const EVENTS: MessageGroupSpec = MessageGroupSpec(&[
2154 // configure
2155 MessageSpec(&[
2156 ArgKind::Int,
2157 ArgKind::Int,
2158 ArgKind::Int,
2159 ArgKind::Int,
2160 ]),
2161 // popup_done
2162 MessageSpec(&[
2163 ]),
2164 // repositioned
2165 MessageSpec(&[
2166 ArgKind::Uint,
2167 ]),
2168 ]);
2169 type Incoming = Event;
2170 type Outgoing = Request;
2171}
2172
2173#[derive(Debug)]
2174pub enum Request {
2175
2176 /// remove xdg_popup interface
2177 ///
2178 /// This destroys the popup. Explicitly destroying the xdg_popup
2179 /// object will also dismiss the popup, and unmap the surface.
2180 ///
2181 /// If this xdg_popup is not the "topmost" popup, a protocol error
2182 /// will be sent.
2183 Destroy,
2184
2185 /// make the popup take an explicit grab
2186 ///
2187 /// This request makes the created popup take an explicit grab. An explicit
2188 /// grab will be dismissed when the user dismisses the popup, or when the
2189 /// client destroys the xdg_popup. This can be done by the user clicking
2190 /// outside the surface, using the keyboard, or even locking the screen
2191 /// through closing the lid or a timeout.
2192 ///
2193 /// If the compositor denies the grab, the popup will be immediately
2194 /// dismissed.
2195 ///
2196 /// This request must be used in response to some sort of user action like a
2197 /// button press, key press, or touch down event. The serial number of the
2198 /// event should be passed as 'serial'.
2199 ///
2200 /// The parent of a grabbing popup must either be an xdg_toplevel surface or
2201 /// another xdg_popup with an explicit grab. If the parent is another
2202 /// xdg_popup it means that the popups are nested, with this popup now being
2203 /// the topmost popup.
2204 ///
2205 /// Nested popups must be destroyed in the reverse order they were created
2206 /// in, e.g. the only popup you are allowed to destroy at all times is the
2207 /// topmost one.
2208 ///
2209 /// When compositors choose to dismiss a popup, they may dismiss every
2210 /// nested grabbing popup as well. When a compositor dismisses popups, it
2211 /// will follow the same dismissing order as required from the client.
2212 ///
2213 /// The parent of a grabbing popup must either be another xdg_popup with an
2214 /// active explicit grab, or an xdg_popup or xdg_toplevel, if there are no
2215 /// explicit grabs already taken.
2216 ///
2217 /// If the topmost grabbing popup is destroyed, the grab will be returned to
2218 /// the parent of the popup, if that parent previously had an explicit grab.
2219 ///
2220 /// If the parent is a grabbing popup which has already been dismissed, this
2221 /// popup will be immediately dismissed. If the parent is a popup that did
2222 /// not take an explicit grab, an error will be raised.
2223 ///
2224 /// During a popup grab, the client owning the grab will receive pointer
2225 /// and touch events for all their surfaces as normal (similar to an
2226 /// "owner-events" grab in X11 parlance), while the top most grabbing popup
2227 /// will always have keyboard focus.
2228 Grab {
2229 /// the wl_seat of the user event
2230 seat: ObjectId,
2231 /// the serial of the user event
2232 serial: u32,
2233 },
2234
2235 /// recalculate the popup's location
2236 ///
2237 /// Reposition an already-mapped popup. The popup will be placed given the
2238 /// details in the passed xdg_positioner object, and a
2239 /// xdg_popup.repositioned followed by xdg_popup.configure and
2240 /// xdg_surface.configure will be emitted in response. Any parameters set
2241 /// by the previous positioner will be discarded.
2242 ///
2243 /// The passed token will be sent in the corresponding
2244 /// xdg_popup.repositioned event. The new popup position will not take
2245 /// effect until the corresponding configure event is acknowledged by the
2246 /// client. See xdg_popup.repositioned for details. The token itself is
2247 /// opaque, and has no other special meaning.
2248 ///
2249 /// If multiple reposition requests are sent, the compositor may skip all
2250 /// but the last one.
2251 ///
2252 /// If the popup is repositioned in response to a configure event for its
2253 /// parent, the client should send an xdg_positioner.set_parent_configure
2254 /// and possibly an xdg_positioner.set_parent_size request to allow the
2255 /// compositor to properly constrain the popup.
2256 ///
2257 /// If the popup is repositioned together with a parent that is being
2258 /// resized, but not in response to a configure event, the client should
2259 /// send an xdg_positioner.set_parent_size request.
2260 Reposition {
2261 positioner: ObjectId,
2262 /// reposition request token
2263 token: u32,
2264 },
2265}
2266
2267impl MessageType for Request {
2268 fn log(&self, this: ObjectId) -> String {
2269 match *self {
2270 Request::Destroy {
2271 } => {
2272 format!("xdg_popup@{:?}::destroy()", this)
2273 }
2274 Request::Grab {
2275 ref seat,
2276 ref serial,
2277 } => {
2278 format!("xdg_popup@{:?}::grab(seat: {:?}, serial: {:?})", this, seat, serial)
2279 }
2280 Request::Reposition {
2281 ref positioner,
2282 ref token,
2283 } => {
2284 format!("xdg_popup@{:?}::reposition(positioner: {:?}, token: {:?})", this, positioner, token)
2285 }
2286 }
2287 }
2288 fn message_name(&self) -> &'static std::ffi::CStr{
2289 match *self {
2290 Request::Destroy { .. } => c"xdg_popup::destroy",
2291 Request::Grab { .. } => c"xdg_popup::grab",
2292 Request::Reposition { .. } => c"xdg_popup::reposition",
2293 }
2294 }
2295}
2296#[derive(Debug)]
2297pub enum Event {
2298
2299 /// configure the popup surface
2300 ///
2301 /// This event asks the popup surface to configure itself given the
2302 /// configuration. The configured state should not be applied immediately.
2303 /// See xdg_surface.configure for details.
2304 ///
2305 /// The x and y arguments represent the position the popup was placed at
2306 /// given the xdg_positioner rule, relative to the upper left corner of the
2307 /// window geometry of the parent surface.
2308 ///
2309 /// For version 2 or older, the configure event for an xdg_popup is only
2310 /// ever sent once for the initial configuration. Starting with version 3,
2311 /// it may be sent again if the popup is setup with an xdg_positioner with
2312 /// set_reactive requested, or in response to xdg_popup.reposition requests.
2313 Configure {
2314 /// x position relative to parent surface window geometry
2315 x: i32,
2316 /// y position relative to parent surface window geometry
2317 y: i32,
2318 /// window geometry width
2319 width: i32,
2320 /// window geometry height
2321 height: i32,
2322 },
2323
2324 /// popup interaction is done
2325 ///
2326 /// The popup_done event is sent out when a popup is dismissed by the
2327 /// compositor. The client should destroy the xdg_popup object at this
2328 /// point.
2329 PopupDone,
2330
2331 /// signal the completion of a repositioned request
2332 ///
2333 /// The repositioned event is sent as part of a popup configuration
2334 /// sequence, together with xdg_popup.configure and lastly
2335 /// xdg_surface.configure to notify the completion of a reposition request.
2336 ///
2337 /// The repositioned event is to notify about the completion of a
2338 /// xdg_popup.reposition request. The token argument is the token passed
2339 /// in the xdg_popup.reposition request.
2340 ///
2341 /// Immediately after this event is emitted, xdg_popup.configure and
2342 /// xdg_surface.configure will be sent with the updated size and position,
2343 /// as well as a new configure serial.
2344 ///
2345 /// The client should optionally update the content of the popup, but must
2346 /// acknowledge the new popup configuration for the new position to take
2347 /// effect. See xdg_surface.ack_configure for details.
2348 Repositioned {
2349 /// reposition request token
2350 token: u32,
2351 },
2352}
2353
2354impl MessageType for Event {
2355 fn log(&self, this: ObjectId) -> String {
2356 match *self {
2357 Event::Configure {
2358 ref x,
2359 ref y,
2360 ref width,
2361 ref height,
2362 } => {
2363 format!("xdg_popup@{:?}::configure(x: {:?}, y: {:?}, width: {:?}, height: {:?})", this, x, y, width, height)
2364 }
2365 Event::PopupDone {
2366 } => {
2367 format!("xdg_popup@{:?}::popup_done()", this)
2368 }
2369 Event::Repositioned {
2370 ref token,
2371 } => {
2372 format!("xdg_popup@{:?}::repositioned(token: {:?})", this, token)
2373 }
2374 }
2375 }
2376 fn message_name(&self) -> &'static std::ffi::CStr{
2377 match *self {
2378 Event::Configure { .. } => c"xdg_popup::configure",
2379 Event::PopupDone { .. } => c"xdg_popup::popup_done",
2380 Event::Repositioned { .. } => c"xdg_popup::repositioned",
2381 }
2382 }
2383}
2384impl IntoMessage for Request {
2385 type Error = EncodeError;
2386 fn into_message(self, id: u32) -> Result<Message, <Self as IntoMessage>::Error> {
2387 let mut header = MessageHeader {
2388 sender: id,
2389 opcode: 0,
2390 length: 0,
2391 };
2392 let mut msg = Message::new();
2393 msg.write_header(&header)?;
2394 match self {
2395 Request::Destroy {
2396 } => {
2397 header.opcode = 0;
2398 },
2399 Request::Grab {
2400 seat,
2401 serial,
2402 } => {
2403 msg.write_arg(Arg::Object(seat))?;
2404 msg.write_arg(Arg::Uint(serial))?;
2405 header.opcode = 1;
2406 },
2407 Request::Reposition {
2408 positioner,
2409 token,
2410 } => {
2411 msg.write_arg(Arg::Object(positioner))?;
2412 msg.write_arg(Arg::Uint(token))?;
2413 header.opcode = 2;
2414 },
2415 }
2416 header.length = msg.bytes().len() as u16;
2417 msg.rewind();
2418 msg.write_header(&header)?;
2419 Ok(msg)
2420 }
2421}
2422impl FromArgs for Event {
2423 fn from_args(op: u16, mut args: Vec<Arg>) -> Result<Self, anyhow::Error> {
2424 match op {
2425 0 /* configure */ => {
2426 let mut iter = args.into_iter();
2427 Ok(Event::Configure {
2428 x: iter.next()
2429 .ok_or(DecodeError::InsufficientArgs)?
2430 .as_int()?,
2431 y: iter.next()
2432 .ok_or(DecodeError::InsufficientArgs)?
2433 .as_int()?,
2434 width: iter.next()
2435 .ok_or(DecodeError::InsufficientArgs)?
2436 .as_int()?,
2437 height: iter.next()
2438 .ok_or(DecodeError::InsufficientArgs)?
2439 .as_int()?,
2440
2441 })
2442 },
2443 1 /* popup_done */ => {
2444 let mut iter = args.into_iter();
2445 Ok(Event::PopupDone {
2446
2447 })
2448 },
2449 2 /* repositioned */ => {
2450 let mut iter = args.into_iter();
2451 Ok(Event::Repositioned {
2452 token: iter.next()
2453 .ok_or(DecodeError::InsufficientArgs)?
2454 .as_uint()?,
2455
2456 })
2457 },
2458 _ => {
2459 Err(DecodeError::InvalidOpcode(op).into())
2460 },
2461 }
2462 }
2463}
2464#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2465#[repr(u32)]
2466pub enum Error {
2467 /// tried to grab after being mapped,
2468 InvalidGrab = 0,
2469}
2470
2471impl Error {
2472 pub fn from_bits(v: u32) -> Option<Self> {
2473 match v {
2474 0 => Some(Error::InvalidGrab),
2475 _ => None,
2476 }
2477 }
2478
2479 pub fn bits(&self) -> u32 {
2480 *self as u32
2481 }
2482}
2483impl Into<Arg> for Error {
2484 fn into(self) -> Arg {
2485 Arg::Uint(self.bits())
2486 }
2487}
2488} // mod xdg_popup
2489
2490pub use crate::xdg_popup::XdgPopup;
2491pub use crate::xdg_popup::Request as XdgPopupRequest;
2492pub use crate::xdg_popup::Event as XdgPopupEvent;