simple_window/common/protocols/xdg_shell/xdg_toplevel.rs
1//! toplevel surface
2//!
3//! This interface defines an xdg_surface role which allows a surface to,
4//! among other things, set window-like properties such as maximize,
5//! fullscreen, and minimize, set application-specific metadata like title and
6//! id, and well as trigger user interactive operations such as interactive
7//! resize and move.
8//!
9//! A xdg_toplevel by default is responsible for providing the full intended
10//! visual representation of the toplevel, which depending on the window
11//! state, may mean things like a title bar, window controls and drop shadow.
12//!
13//! Unmapping an xdg_toplevel means that the surface cannot be shown
14//! by the compositor until it is explicitly mapped again.
15//! All active operations (e.g., move, resize) are canceled and all
16//! attributes (e.g. title, state, stacking, ...) are discarded for
17//! an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
18//! the state it had right after xdg_surface.get_toplevel. The client
19//! can re-map the toplevel by performing a commit without any buffer
20//! attached, waiting for a configure event and handling it as usual (see
21//! xdg_surface description).
22//!
23//! Attaching a null buffer to a toplevel unmaps the surface.
24
25use {super::super::all_types::*, ::wl_client::builder::prelude::*};
26
27static INTERFACE: wl_interface = wl_interface {
28 name: c"xdg_toplevel".as_ptr(),
29 version: 6,
30 method_count: 14,
31 methods: {
32 static MESSAGES: [wl_message; 14] = [
33 wl_message {
34 name: c"destroy".as_ptr(),
35 signature: c"".as_ptr(),
36 types: {
37 static TYPES: [Option<&'static wl_interface>; 0] = [];
38 TYPES.as_ptr().cast()
39 },
40 },
41 wl_message {
42 name: c"set_parent".as_ptr(),
43 signature: c"?o".as_ptr(),
44 types: {
45 static TYPES: [Option<&'static wl_interface>; 1] =
46 [Some(XdgToplevel::WL_INTERFACE)];
47 TYPES.as_ptr().cast()
48 },
49 },
50 wl_message {
51 name: c"set_title".as_ptr(),
52 signature: c"s".as_ptr(),
53 types: {
54 static TYPES: [Option<&'static wl_interface>; 1] = [None];
55 TYPES.as_ptr().cast()
56 },
57 },
58 wl_message {
59 name: c"set_app_id".as_ptr(),
60 signature: c"s".as_ptr(),
61 types: {
62 static TYPES: [Option<&'static wl_interface>; 1] = [None];
63 TYPES.as_ptr().cast()
64 },
65 },
66 wl_message {
67 name: c"show_window_menu".as_ptr(),
68 signature: c"ouii".as_ptr(),
69 types: {
70 static TYPES: [Option<&'static wl_interface>; 4] =
71 [Some(WlSeat::WL_INTERFACE), None, None, None];
72 TYPES.as_ptr().cast()
73 },
74 },
75 wl_message {
76 name: c"move".as_ptr(),
77 signature: c"ou".as_ptr(),
78 types: {
79 static TYPES: [Option<&'static wl_interface>; 2] =
80 [Some(WlSeat::WL_INTERFACE), None];
81 TYPES.as_ptr().cast()
82 },
83 },
84 wl_message {
85 name: c"resize".as_ptr(),
86 signature: c"ouu".as_ptr(),
87 types: {
88 static TYPES: [Option<&'static wl_interface>; 3] =
89 [Some(WlSeat::WL_INTERFACE), None, None];
90 TYPES.as_ptr().cast()
91 },
92 },
93 wl_message {
94 name: c"set_max_size".as_ptr(),
95 signature: c"ii".as_ptr(),
96 types: {
97 static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
98 TYPES.as_ptr().cast()
99 },
100 },
101 wl_message {
102 name: c"set_min_size".as_ptr(),
103 signature: c"ii".as_ptr(),
104 types: {
105 static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
106 TYPES.as_ptr().cast()
107 },
108 },
109 wl_message {
110 name: c"set_maximized".as_ptr(),
111 signature: c"".as_ptr(),
112 types: {
113 static TYPES: [Option<&'static wl_interface>; 0] = [];
114 TYPES.as_ptr().cast()
115 },
116 },
117 wl_message {
118 name: c"unset_maximized".as_ptr(),
119 signature: c"".as_ptr(),
120 types: {
121 static TYPES: [Option<&'static wl_interface>; 0] = [];
122 TYPES.as_ptr().cast()
123 },
124 },
125 wl_message {
126 name: c"set_fullscreen".as_ptr(),
127 signature: c"?o".as_ptr(),
128 types: {
129 static TYPES: [Option<&'static wl_interface>; 1] =
130 [Some(WlOutput::WL_INTERFACE)];
131 TYPES.as_ptr().cast()
132 },
133 },
134 wl_message {
135 name: c"unset_fullscreen".as_ptr(),
136 signature: c"".as_ptr(),
137 types: {
138 static TYPES: [Option<&'static wl_interface>; 0] = [];
139 TYPES.as_ptr().cast()
140 },
141 },
142 wl_message {
143 name: c"set_minimized".as_ptr(),
144 signature: c"".as_ptr(),
145 types: {
146 static TYPES: [Option<&'static wl_interface>; 0] = [];
147 TYPES.as_ptr().cast()
148 },
149 },
150 ];
151 MESSAGES.as_ptr()
152 },
153 event_count: 4,
154 events: {
155 static MESSAGES: [wl_message; 4] = [
156 wl_message {
157 name: c"configure".as_ptr(),
158 signature: c"iia".as_ptr(),
159 types: {
160 static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
161 TYPES.as_ptr().cast()
162 },
163 },
164 wl_message {
165 name: c"close".as_ptr(),
166 signature: c"".as_ptr(),
167 types: {
168 static TYPES: [Option<&'static wl_interface>; 0] = [];
169 TYPES.as_ptr().cast()
170 },
171 },
172 wl_message {
173 name: c"configure_bounds".as_ptr(),
174 signature: c"ii".as_ptr(),
175 types: {
176 static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
177 TYPES.as_ptr().cast()
178 },
179 },
180 wl_message {
181 name: c"wm_capabilities".as_ptr(),
182 signature: c"a".as_ptr(),
183 types: {
184 static TYPES: [Option<&'static wl_interface>; 1] = [None];
185 TYPES.as_ptr().cast()
186 },
187 },
188 ];
189 MESSAGES.as_ptr()
190 },
191};
192
193/// An owned xdg_toplevel proxy.
194///
195/// See the documentation of [the module][self] for the interface description.
196#[derive(Clone, Eq, PartialEq)]
197#[repr(transparent)]
198pub struct XdgToplevel {
199 /// This proxy has the interface INTERFACE.
200 proxy: UntypedOwnedProxy,
201}
202
203/// A borrowed xdg_toplevel proxy.
204///
205/// See the documentation of [the module][self] for the interface description.
206#[derive(Eq, PartialEq)]
207#[repr(transparent)]
208pub struct XdgToplevelRef {
209 /// This proxy has the interface INTERFACE.
210 proxy: UntypedBorrowedProxy,
211}
212
213// SAFETY: XdgToplevel is a transparent wrapper around UntypedOwnedProxy
214unsafe impl UntypedOwnedProxyWrapper for XdgToplevel {}
215
216// SAFETY: - INTERFACE is a valid wl_interface
217// - The only invariant is that self.proxy has a compatible interface
218unsafe impl OwnedProxy for XdgToplevel {
219 const INTERFACE: &'static str = "xdg_toplevel";
220 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
221 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
222 private::EventHandler(private::NoOpEventHandler);
223 const MAX_VERSION: u32 = 6;
224
225 type Borrowed = XdgToplevelRef;
226 type Api = private::ProxyApi;
227 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
228}
229
230// SAFETY: XdgToplevelRef is a transparent wrapper around UntypedBorrowedProxy
231unsafe impl UntypedBorrowedProxyWrapper for XdgToplevelRef {}
232
233// SAFETY: - The only invariant is that self.proxy has a compatible interface
234unsafe impl BorrowedProxy for XdgToplevelRef {
235 type Owned = XdgToplevel;
236}
237
238impl Deref for XdgToplevel {
239 type Target = XdgToplevelRef;
240
241 fn deref(&self) -> &Self::Target {
242 proxy::low_level::deref(self)
243 }
244}
245
246mod private {
247 pub struct ProxyApi;
248
249 #[allow(dead_code)]
250 pub struct EventHandler<H>(pub(super) H);
251
252 #[allow(dead_code)]
253 pub struct NoOpEventHandler;
254}
255
256impl Debug for XdgToplevel {
257 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
258 write!(f, "xdg_toplevel#{}", self.proxy.id())
259 }
260}
261
262impl Debug for XdgToplevelRef {
263 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
264 write!(f, "xdg_toplevel#{}", self.proxy.id())
265 }
266}
267
268impl PartialEq<XdgToplevelRef> for XdgToplevel {
269 fn eq(&self, other: &XdgToplevelRef) -> bool {
270 self.proxy == other.proxy
271 }
272}
273
274impl PartialEq<XdgToplevel> for XdgToplevelRef {
275 fn eq(&self, other: &XdgToplevel) -> bool {
276 self.proxy == other.proxy
277 }
278}
279
280#[allow(dead_code)]
281impl XdgToplevel {
282 /// Since when the destroy request is available.
283 #[allow(dead_code)]
284 pub const REQ__DESTROY__SINCE: u32 = 1;
285
286 /// destroy the xdg_toplevel
287 ///
288 /// This request destroys the role surface and unmaps the surface;
289 /// see "Unmapping" behavior in interface section for details.
290 #[inline]
291 pub fn destroy(&self) {
292 let mut args = [];
293 // SAFETY: - self.proxy has the interface INTERFACE
294 // - 0 < INTERFACE.method_count = 14
295 // - the request signature is ``
296 unsafe {
297 self.proxy.send_destructor(0, &mut args);
298 }
299 }
300}
301
302#[allow(dead_code)]
303impl XdgToplevelRef {
304 /// set the parent of this surface
305 ///
306 /// Set the "parent" of this surface. This surface should be stacked
307 /// above the parent surface and all other ancestor surfaces.
308 ///
309 /// Parent surfaces should be set on dialogs, toolboxes, or other
310 /// "auxiliary" surfaces, so that the parent is raised when the dialog
311 /// is raised.
312 ///
313 /// Setting a null parent for a child surface unsets its parent. Setting
314 /// a null parent for a surface which currently has no parent is a no-op.
315 ///
316 /// Only mapped surfaces can have child surfaces. Setting a parent which
317 /// is not mapped is equivalent to setting a null parent. If a surface
318 /// becomes unmapped, its children's parent is set to the parent of
319 /// the now-unmapped surface. If the now-unmapped surface has no parent,
320 /// its children's parent is unset. If the now-unmapped surface becomes
321 /// mapped again, its parent-child relationship is not restored.
322 ///
323 /// The parent toplevel must not be one of the child toplevel's
324 /// descendants, and the parent must be different from the child toplevel,
325 /// otherwise the invalid_parent protocol error is raised.
326 ///
327 /// # Arguments
328 ///
329 /// - `parent`:
330 #[inline]
331 pub fn set_parent(&self, parent: Option<&XdgToplevelRef>) {
332 let (arg0,) = (parent,);
333 let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
334 let obj0 = obj0_lock
335 .map(|obj0_lock| check_argument_proxy("parent", obj0_lock.wl_proxy()))
336 .unwrap_or(ptr::null_mut());
337 let mut args = [wl_argument { o: obj0 }];
338 // SAFETY: - self.proxy has the interface INTERFACE
339 // - 1 < INTERFACE.method_count = 14
340 // - the request signature is `?o`
341 unsafe {
342 self.proxy.send_request(1, &mut args);
343 }
344 }
345
346 /// set surface title
347 ///
348 /// Set a short title for the surface.
349 ///
350 /// This string may be used to identify the surface in a task bar,
351 /// window list, or other user interface elements provided by the
352 /// compositor.
353 ///
354 /// The string must be encoded in UTF-8.
355 ///
356 /// # Arguments
357 ///
358 /// - `title`:
359 #[inline]
360 pub fn set_title(&self, title: &str) {
361 let (arg0,) = (title,);
362 with_cstr_cache(|cache| {
363 let str0_offset = cache.len();
364 cache.extend_from_slice(arg0.as_bytes());
365 cache.push(0);
366 let str0 = cache[str0_offset..].as_ptr().cast();
367 let mut args = [wl_argument { s: str0 }];
368 // SAFETY: - self.proxy has the interface INTERFACE
369 // - 2 < INTERFACE.method_count = 14
370 // - the request signature is `s`
371 unsafe {
372 self.proxy.send_request(2, &mut args);
373 }
374 })
375 }
376
377 /// set application ID
378 ///
379 /// Set an application identifier for the surface.
380 ///
381 /// The app ID identifies the general class of applications to which
382 /// the surface belongs. The compositor can use this to group multiple
383 /// surfaces together, or to determine how to launch a new application.
384 ///
385 /// For D-Bus activatable applications, the app ID is used as the D-Bus
386 /// service name.
387 ///
388 /// The compositor shell will try to group application surfaces together
389 /// by their app ID. As a best practice, it is suggested to select app
390 /// ID's that match the basename of the application's .desktop file.
391 /// For example, "org.freedesktop.FooViewer" where the .desktop file is
392 /// "org.freedesktop.FooViewer.desktop".
393 ///
394 /// Like other properties, a set_app_id request can be sent after the
395 /// xdg_toplevel has been mapped to update the property.
396 ///
397 /// See the desktop-entry specification [0] for more details on
398 /// application identifiers and how they relate to well-known D-Bus
399 /// names and .desktop files.
400 ///
401 /// [0] https://standards.freedesktop.org/desktop-entry-spec/
402 ///
403 /// # Arguments
404 ///
405 /// - `app_id`:
406 #[inline]
407 pub fn set_app_id(&self, app_id: &str) {
408 let (arg0,) = (app_id,);
409 with_cstr_cache(|cache| {
410 let str0_offset = cache.len();
411 cache.extend_from_slice(arg0.as_bytes());
412 cache.push(0);
413 let str0 = cache[str0_offset..].as_ptr().cast();
414 let mut args = [wl_argument { s: str0 }];
415 // SAFETY: - self.proxy has the interface INTERFACE
416 // - 3 < INTERFACE.method_count = 14
417 // - the request signature is `s`
418 unsafe {
419 self.proxy.send_request(3, &mut args);
420 }
421 })
422 }
423
424 /// show the window menu
425 ///
426 /// Clients implementing client-side decorations might want to show
427 /// a context menu when right-clicking on the decorations, giving the
428 /// user a menu that they can use to maximize or minimize the window.
429 ///
430 /// This request asks the compositor to pop up such a window menu at
431 /// the given position, relative to the local surface coordinates of
432 /// the parent surface. There are no guarantees as to what menu items
433 /// the window menu contains, or even if a window menu will be drawn
434 /// at all.
435 ///
436 /// This request must be used in response to some sort of user action
437 /// like a button press, key press, or touch down event.
438 ///
439 /// # Arguments
440 ///
441 /// - `seat`: the wl_seat of the user event
442 /// - `serial`: the serial of the user event
443 /// - `x`: the x position to pop up the window menu at
444 /// - `y`: the y position to pop up the window menu at
445 #[inline]
446 pub fn show_window_menu(&self, seat: &WlSeatRef, serial: u32, x: i32, y: i32) {
447 let (arg0, arg1, arg2, arg3) = (seat, serial, x, y);
448 let obj0_lock = proxy::lock(arg0);
449 let obj0 = check_argument_proxy("seat", obj0_lock.wl_proxy());
450 let mut args = [
451 wl_argument { o: obj0 },
452 wl_argument { u: arg1 },
453 wl_argument { i: arg2 },
454 wl_argument { i: arg3 },
455 ];
456 // SAFETY: - self.proxy has the interface INTERFACE
457 // - 4 < INTERFACE.method_count = 14
458 // - the request signature is `ouii`
459 unsafe {
460 self.proxy.send_request(4, &mut args);
461 }
462 }
463
464 /// start an interactive move
465 ///
466 /// Start an interactive, user-driven move of the surface.
467 ///
468 /// This request must be used in response to some sort of user action
469 /// like a button press, key press, or touch down event. The passed
470 /// serial is used to determine the type of interactive move (touch,
471 /// pointer, etc).
472 ///
473 /// The server may ignore move requests depending on the state of
474 /// the surface (e.g. fullscreen or maximized), or if the passed serial
475 /// is no longer valid.
476 ///
477 /// If triggered, the surface will lose the focus of the device
478 /// (wl_pointer, wl_touch, etc) used for the move. It is up to the
479 /// compositor to visually indicate that the move is taking place, such as
480 /// updating a pointer cursor, during the move. There is no guarantee
481 /// that the device focus will return when the move is completed.
482 ///
483 /// # Arguments
484 ///
485 /// - `seat`: the wl_seat of the user event
486 /// - `serial`: the serial of the user event
487 #[inline]
488 pub fn r#move(&self, seat: &WlSeatRef, serial: u32) {
489 let (arg0, arg1) = (seat, serial);
490 let obj0_lock = proxy::lock(arg0);
491 let obj0 = check_argument_proxy("seat", obj0_lock.wl_proxy());
492 let mut args = [wl_argument { o: obj0 }, wl_argument { u: arg1 }];
493 // SAFETY: - self.proxy has the interface INTERFACE
494 // - 5 < INTERFACE.method_count = 14
495 // - the request signature is `ou`
496 unsafe {
497 self.proxy.send_request(5, &mut args);
498 }
499 }
500
501 /// start an interactive resize
502 ///
503 /// Start a user-driven, interactive resize of the surface.
504 ///
505 /// This request must be used in response to some sort of user action
506 /// like a button press, key press, or touch down event. The passed
507 /// serial is used to determine the type of interactive resize (touch,
508 /// pointer, etc).
509 ///
510 /// The server may ignore resize requests depending on the state of
511 /// the surface (e.g. fullscreen or maximized).
512 ///
513 /// If triggered, the client will receive configure events with the
514 /// "resize" state enum value and the expected sizes. See the "resize"
515 /// enum value for more details about what is required. The client
516 /// must also acknowledge configure events using "ack_configure". After
517 /// the resize is completed, the client will receive another "configure"
518 /// event without the resize state.
519 ///
520 /// If triggered, the surface also will lose the focus of the device
521 /// (wl_pointer, wl_touch, etc) used for the resize. It is up to the
522 /// compositor to visually indicate that the resize is taking place,
523 /// such as updating a pointer cursor, during the resize. There is no
524 /// guarantee that the device focus will return when the resize is
525 /// completed.
526 ///
527 /// The edges parameter specifies how the surface should be resized, and
528 /// is one of the values of the resize_edge enum. Values not matching
529 /// a variant of the enum will cause the invalid_resize_edge protocol error.
530 /// The compositor may use this information to update the surface position
531 /// for example when dragging the top left corner. The compositor may also
532 /// use this information to adapt its behavior, e.g. choose an appropriate
533 /// cursor image.
534 ///
535 /// # Arguments
536 ///
537 /// - `seat`: the wl_seat of the user event
538 /// - `serial`: the serial of the user event
539 /// - `edges`: which edge or corner is being dragged
540 #[inline]
541 pub fn resize(&self, seat: &WlSeatRef, serial: u32, edges: XdgToplevelResizeEdge) {
542 let (arg0, arg1, arg2) = (seat, serial, edges);
543 let obj0_lock = proxy::lock(arg0);
544 let obj0 = check_argument_proxy("seat", obj0_lock.wl_proxy());
545 let mut args = [
546 wl_argument { o: obj0 },
547 wl_argument { u: arg1 },
548 wl_argument { u: arg2.0 },
549 ];
550 // SAFETY: - self.proxy has the interface INTERFACE
551 // - 6 < INTERFACE.method_count = 14
552 // - the request signature is `ouu`
553 unsafe {
554 self.proxy.send_request(6, &mut args);
555 }
556 }
557
558 /// set the maximum size
559 ///
560 /// Set a maximum size for the window.
561 ///
562 /// The client can specify a maximum size so that the compositor does
563 /// not try to configure the window beyond this size.
564 ///
565 /// The width and height arguments are in window geometry coordinates.
566 /// See xdg_surface.set_window_geometry.
567 ///
568 /// Values set in this way are double-buffered, see wl_surface.commit.
569 ///
570 /// The compositor can use this information to allow or disallow
571 /// different states like maximize or fullscreen and draw accurate
572 /// animations.
573 ///
574 /// Similarly, a tiling window manager may use this information to
575 /// place and resize client windows in a more effective way.
576 ///
577 /// The client should not rely on the compositor to obey the maximum
578 /// size. The compositor may decide to ignore the values set by the
579 /// client and request a larger size.
580 ///
581 /// If never set, or a value of zero in the request, means that the
582 /// client has no expected maximum size in the given dimension.
583 /// As a result, a client wishing to reset the maximum size
584 /// to an unspecified state can use zero for width and height in the
585 /// request.
586 ///
587 /// Requesting a maximum size to be smaller than the minimum size of
588 /// a surface is illegal and will result in an invalid_size error.
589 ///
590 /// The width and height must be greater than or equal to zero. Using
591 /// strictly negative values for width or height will result in a
592 /// invalid_size error.
593 ///
594 /// # Arguments
595 ///
596 /// - `width`:
597 /// - `height`:
598 #[inline]
599 pub fn set_max_size(&self, width: i32, height: i32) {
600 let (arg0, arg1) = (width, height);
601 let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
602 // SAFETY: - self.proxy has the interface INTERFACE
603 // - 7 < INTERFACE.method_count = 14
604 // - the request signature is `ii`
605 unsafe {
606 self.proxy.send_request(7, &mut args);
607 }
608 }
609
610 /// set the minimum size
611 ///
612 /// Set a minimum size for the window.
613 ///
614 /// The client can specify a minimum size so that the compositor does
615 /// not try to configure the window below this size.
616 ///
617 /// The width and height arguments are in window geometry coordinates.
618 /// See xdg_surface.set_window_geometry.
619 ///
620 /// Values set in this way are double-buffered, see wl_surface.commit.
621 ///
622 /// The compositor can use this information to allow or disallow
623 /// different states like maximize or fullscreen and draw accurate
624 /// animations.
625 ///
626 /// Similarly, a tiling window manager may use this information to
627 /// place and resize client windows in a more effective way.
628 ///
629 /// The client should not rely on the compositor to obey the minimum
630 /// size. The compositor may decide to ignore the values set by the
631 /// client and request a smaller size.
632 ///
633 /// If never set, or a value of zero in the request, means that the
634 /// client has no expected minimum size in the given dimension.
635 /// As a result, a client wishing to reset the minimum size
636 /// to an unspecified state can use zero for width and height in the
637 /// request.
638 ///
639 /// Requesting a minimum size to be larger than the maximum size of
640 /// a surface is illegal and will result in an invalid_size error.
641 ///
642 /// The width and height must be greater than or equal to zero. Using
643 /// strictly negative values for width and height will result in a
644 /// invalid_size error.
645 ///
646 /// # Arguments
647 ///
648 /// - `width`:
649 /// - `height`:
650 #[inline]
651 pub fn set_min_size(&self, width: i32, height: i32) {
652 let (arg0, arg1) = (width, height);
653 let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
654 // SAFETY: - self.proxy has the interface INTERFACE
655 // - 8 < INTERFACE.method_count = 14
656 // - the request signature is `ii`
657 unsafe {
658 self.proxy.send_request(8, &mut args);
659 }
660 }
661
662 /// maximize the window
663 ///
664 /// Maximize the surface.
665 ///
666 /// After requesting that the surface should be maximized, the compositor
667 /// will respond by emitting a configure event. Whether this configure
668 /// actually sets the window maximized is subject to compositor policies.
669 /// The client must then update its content, drawing in the configured
670 /// state. The client must also acknowledge the configure when committing
671 /// the new content (see ack_configure).
672 ///
673 /// It is up to the compositor to decide how and where to maximize the
674 /// surface, for example which output and what region of the screen should
675 /// be used.
676 ///
677 /// If the surface was already maximized, the compositor will still emit
678 /// a configure event with the "maximized" state.
679 ///
680 /// If the surface is in a fullscreen state, this request has no direct
681 /// effect. It may alter the state the surface is returned to when
682 /// unmaximized unless overridden by the compositor.
683 #[inline]
684 pub fn set_maximized(&self) {
685 let mut args = [];
686 // SAFETY: - self.proxy has the interface INTERFACE
687 // - 9 < INTERFACE.method_count = 14
688 // - the request signature is ``
689 unsafe {
690 self.proxy.send_request(9, &mut args);
691 }
692 }
693
694 /// unmaximize the window
695 ///
696 /// Unmaximize the surface.
697 ///
698 /// After requesting that the surface should be unmaximized, the compositor
699 /// will respond by emitting a configure event. Whether this actually
700 /// un-maximizes the window is subject to compositor policies.
701 /// If available and applicable, the compositor will include the window
702 /// geometry dimensions the window had prior to being maximized in the
703 /// configure event. The client must then update its content, drawing it in
704 /// the configured state. The client must also acknowledge the configure
705 /// when committing the new content (see ack_configure).
706 ///
707 /// It is up to the compositor to position the surface after it was
708 /// unmaximized; usually the position the surface had before maximizing, if
709 /// applicable.
710 ///
711 /// If the surface was already not maximized, the compositor will still
712 /// emit a configure event without the "maximized" state.
713 ///
714 /// If the surface is in a fullscreen state, this request has no direct
715 /// effect. It may alter the state the surface is returned to when
716 /// unmaximized unless overridden by the compositor.
717 #[inline]
718 pub fn unset_maximized(&self) {
719 let mut args = [];
720 // SAFETY: - self.proxy has the interface INTERFACE
721 // - 10 < INTERFACE.method_count = 14
722 // - the request signature is ``
723 unsafe {
724 self.proxy.send_request(10, &mut args);
725 }
726 }
727
728 /// set the window as fullscreen on an output
729 ///
730 /// Make the surface fullscreen.
731 ///
732 /// After requesting that the surface should be fullscreened, the
733 /// compositor will respond by emitting a configure event. Whether the
734 /// client is actually put into a fullscreen state is subject to compositor
735 /// policies. The client must also acknowledge the configure when
736 /// committing the new content (see ack_configure).
737 ///
738 /// The output passed by the request indicates the client's preference as
739 /// to which display it should be set fullscreen on. If this value is NULL,
740 /// it's up to the compositor to choose which display will be used to map
741 /// this surface.
742 ///
743 /// If the surface doesn't cover the whole output, the compositor will
744 /// position the surface in the center of the output and compensate with
745 /// with border fill covering the rest of the output. The content of the
746 /// border fill is undefined, but should be assumed to be in some way that
747 /// attempts to blend into the surrounding area (e.g. solid black).
748 ///
749 /// If the fullscreened surface is not opaque, the compositor must make
750 /// sure that other screen content not part of the same surface tree (made
751 /// up of subsurfaces, popups or similarly coupled surfaces) are not
752 /// visible below the fullscreened surface.
753 ///
754 /// # Arguments
755 ///
756 /// - `output`:
757 #[inline]
758 pub fn set_fullscreen(&self, output: Option<&WlOutputRef>) {
759 let (arg0,) = (output,);
760 let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
761 let obj0 = obj0_lock
762 .map(|obj0_lock| check_argument_proxy("output", obj0_lock.wl_proxy()))
763 .unwrap_or(ptr::null_mut());
764 let mut args = [wl_argument { o: obj0 }];
765 // SAFETY: - self.proxy has the interface INTERFACE
766 // - 11 < INTERFACE.method_count = 14
767 // - the request signature is `?o`
768 unsafe {
769 self.proxy.send_request(11, &mut args);
770 }
771 }
772
773 /// unset the window as fullscreen
774 ///
775 /// Make the surface no longer fullscreen.
776 ///
777 /// After requesting that the surface should be unfullscreened, the
778 /// compositor will respond by emitting a configure event.
779 /// Whether this actually removes the fullscreen state of the client is
780 /// subject to compositor policies.
781 ///
782 /// Making a surface unfullscreen sets states for the surface based on the following:
783 /// * the state(s) it may have had before becoming fullscreen
784 /// * any state(s) decided by the compositor
785 /// * any state(s) requested by the client while the surface was fullscreen
786 ///
787 /// The compositor may include the previous window geometry dimensions in
788 /// the configure event, if applicable.
789 ///
790 /// The client must also acknowledge the configure when committing the new
791 /// content (see ack_configure).
792 #[inline]
793 pub fn unset_fullscreen(&self) {
794 let mut args = [];
795 // SAFETY: - self.proxy has the interface INTERFACE
796 // - 12 < INTERFACE.method_count = 14
797 // - the request signature is ``
798 unsafe {
799 self.proxy.send_request(12, &mut args);
800 }
801 }
802
803 /// set the window as minimized
804 ///
805 /// Request that the compositor minimize your surface. There is no
806 /// way to know if the surface is currently minimized, nor is there
807 /// any way to unset minimization on this surface.
808 ///
809 /// If you are looking to throttle redrawing when minimized, please
810 /// instead use the wl_surface.frame event for this, as this will
811 /// also work with live previews on windows in Alt-Tab, Expose or
812 /// similar compositor features.
813 #[inline]
814 pub fn set_minimized(&self) {
815 let mut args = [];
816 // SAFETY: - self.proxy has the interface INTERFACE
817 // - 13 < INTERFACE.method_count = 14
818 // - the request signature is ``
819 unsafe {
820 self.proxy.send_request(13, &mut args);
821 }
822 }
823}
824
825impl XdgToplevel {
826 /// Since when the configure event is available.
827 #[allow(dead_code)]
828 pub const EVT__CONFIGURE__SINCE: u32 = 1;
829
830 /// Since when the close event is available.
831 #[allow(dead_code)]
832 pub const EVT__CLOSE__SINCE: u32 = 1;
833
834 /// Since when the configure_bounds event is available.
835 #[allow(dead_code)]
836 pub const EVT__CONFIGURE_BOUNDS__SINCE: u32 = 4;
837
838 /// Since when the wm_capabilities event is available.
839 #[allow(dead_code)]
840 pub const EVT__WM_CAPABILITIES__SINCE: u32 = 5;
841}
842
843/// An event handler for [XdgToplevel] proxies.
844#[allow(dead_code)]
845pub trait XdgToplevelEventHandler {
846 /// suggest a surface change
847 ///
848 /// This configure event asks the client to resize its toplevel surface or
849 /// to change its state. The configured state should not be applied
850 /// immediately. See xdg_surface.configure for details.
851 ///
852 /// The width and height arguments specify a hint to the window
853 /// about how its surface should be resized in window geometry
854 /// coordinates. See set_window_geometry.
855 ///
856 /// If the width or height arguments are zero, it means the client
857 /// should decide its own window dimension. This may happen when the
858 /// compositor needs to configure the state of the surface but doesn't
859 /// have any information about any previous or expected dimension.
860 ///
861 /// The states listed in the event specify how the width/height
862 /// arguments should be interpreted, and possibly how it should be
863 /// drawn.
864 ///
865 /// Clients must send an ack_configure in response to this event. See
866 /// xdg_surface.configure and xdg_surface.ack_configure for details.
867 ///
868 /// # Arguments
869 ///
870 /// - `width`:
871 /// - `height`:
872 /// - `states`:
873 #[inline]
874 fn configure(&self, _slf: &XdgToplevelRef, width: i32, height: i32, states: &[u8]) {
875 let _ = width;
876 let _ = height;
877 let _ = states;
878 }
879
880 /// surface wants to be closed
881 ///
882 /// The close event is sent by the compositor when the user
883 /// wants the surface to be closed. This should be equivalent to
884 /// the user clicking the close button in client-side decorations,
885 /// if your application has any.
886 ///
887 /// This is only a request that the user intends to close the
888 /// window. The client may choose to ignore this request, or show
889 /// a dialog to ask the user to save their data, etc.
890 #[inline]
891 fn close(&self, _slf: &XdgToplevelRef) {}
892
893 /// recommended window geometry bounds
894 ///
895 /// The configure_bounds event may be sent prior to a xdg_toplevel.configure
896 /// event to communicate the bounds a window geometry size is recommended
897 /// to constrain to.
898 ///
899 /// The passed width and height are in surface coordinate space. If width
900 /// and height are 0, it means bounds is unknown and equivalent to as if no
901 /// configure_bounds event was ever sent for this surface.
902 ///
903 /// The bounds can for example correspond to the size of a monitor excluding
904 /// any panels or other shell components, so that a surface isn't created in
905 /// a way that it cannot fit.
906 ///
907 /// The bounds may change at any point, and in such a case, a new
908 /// xdg_toplevel.configure_bounds will be sent, followed by
909 /// xdg_toplevel.configure and xdg_surface.configure.
910 ///
911 /// # Arguments
912 ///
913 /// - `width`:
914 /// - `height`:
915 #[inline]
916 fn configure_bounds(&self, _slf: &XdgToplevelRef, width: i32, height: i32) {
917 let _ = width;
918 let _ = height;
919 }
920
921 /// compositor capabilities
922 ///
923 /// This event advertises the capabilities supported by the compositor. If
924 /// a capability isn't supported, clients should hide or disable the UI
925 /// elements that expose this functionality. For instance, if the
926 /// compositor doesn't advertise support for minimized toplevels, a button
927 /// triggering the set_minimized request should not be displayed.
928 ///
929 /// The compositor will ignore requests it doesn't support. For instance,
930 /// a compositor which doesn't advertise support for minimized will ignore
931 /// set_minimized requests.
932 ///
933 /// Compositors must send this event once before the first
934 /// xdg_surface.configure event. When the capabilities change, compositors
935 /// must send this event again and then send an xdg_surface.configure
936 /// event.
937 ///
938 /// The configured state should not be applied immediately. See
939 /// xdg_surface.configure for details.
940 ///
941 /// The capabilities are sent as an array of 32-bit unsigned integers in
942 /// native endianness.
943 ///
944 /// # Arguments
945 ///
946 /// - `capabilities`: array of 32-bit capabilities
947 #[inline]
948 fn wm_capabilities(&self, _slf: &XdgToplevelRef, capabilities: &[u8]) {
949 let _ = capabilities;
950 }
951}
952
953impl XdgToplevelEventHandler for private::NoOpEventHandler {}
954
955// SAFETY: - INTERFACE is a valid wl_interface
956unsafe impl<H> EventHandler for private::EventHandler<H>
957where
958 H: XdgToplevelEventHandler,
959{
960 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
961
962 #[allow(unused_variables)]
963 unsafe fn handle_event(
964 &self,
965 queue: &Queue,
966 data: *mut u8,
967 slf: &UntypedBorrowedProxy,
968 opcode: u32,
969 args: *mut wl_argument,
970 ) {
971 // SAFETY: This function requires that slf has the interface INTERFACE
972 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<XdgToplevelRef>(slf) };
973 match opcode {
974 0 => {
975 // SAFETY: INTERFACE requires that there are 3 arguments
976 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
977 // SAFETY: - INTERFACE requires that args[0] contains an int
978 let arg0 = unsafe { args[0].i };
979 // SAFETY: - INTERFACE requires that args[1] contains an int
980 let arg1 = unsafe { args[1].i };
981 // SAFETY: - INTERFACE requires that args[2] contains an array
982 let arg2 = unsafe {
983 let a = &*args[2].a;
984 std::slice::from_raw_parts(a.data.cast(), a.size)
985 };
986 self.0.configure(slf, arg0, arg1, arg2);
987 }
988 1 => {
989 self.0.close(slf);
990 }
991 2 => {
992 // SAFETY: INTERFACE requires that there are 2 arguments
993 let args = unsafe { &*args.cast::<[wl_argument; 2]>() };
994 // SAFETY: - INTERFACE requires that args[0] contains an int
995 let arg0 = unsafe { args[0].i };
996 // SAFETY: - INTERFACE requires that args[1] contains an int
997 let arg1 = unsafe { args[1].i };
998 self.0.configure_bounds(slf, arg0, arg1);
999 }
1000 3 => {
1001 // SAFETY: INTERFACE requires that there are 1 arguments
1002 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1003 // SAFETY: - INTERFACE requires that args[0] contains an array
1004 let arg0 = unsafe {
1005 let a = &*args[0].a;
1006 std::slice::from_raw_parts(a.data.cast(), a.size)
1007 };
1008 self.0.wm_capabilities(slf, arg0);
1009 }
1010 _ => {
1011 invalid_opcode("xdg_toplevel", opcode);
1012 }
1013 }
1014 }
1015}
1016
1017impl<H> CreateEventHandler<H> for private::ProxyApi
1018where
1019 H: XdgToplevelEventHandler,
1020{
1021 type EventHandler = private::EventHandler<H>;
1022
1023 #[inline]
1024 fn create_event_handler(handler: H) -> Self::EventHandler {
1025 private::EventHandler(handler)
1026 }
1027}
1028
1029impl XdgToplevel {
1030 /// Since when the error.invalid_resize_edge enum variant is available.
1031 #[allow(dead_code)]
1032 pub const ENM__ERROR_INVALID_RESIZE_EDGE__SINCE: u32 = 1;
1033 /// Since when the error.invalid_parent enum variant is available.
1034 #[allow(dead_code)]
1035 pub const ENM__ERROR_INVALID_PARENT__SINCE: u32 = 1;
1036 /// Since when the error.invalid_size enum variant is available.
1037 #[allow(dead_code)]
1038 pub const ENM__ERROR_INVALID_SIZE__SINCE: u32 = 1;
1039
1040 /// Since when the resize_edge.none enum variant is available.
1041 #[allow(dead_code)]
1042 pub const ENM__RESIZE_EDGE_NONE__SINCE: u32 = 1;
1043 /// Since when the resize_edge.top enum variant is available.
1044 #[allow(dead_code)]
1045 pub const ENM__RESIZE_EDGE_TOP__SINCE: u32 = 1;
1046 /// Since when the resize_edge.bottom enum variant is available.
1047 #[allow(dead_code)]
1048 pub const ENM__RESIZE_EDGE_BOTTOM__SINCE: u32 = 1;
1049 /// Since when the resize_edge.left enum variant is available.
1050 #[allow(dead_code)]
1051 pub const ENM__RESIZE_EDGE_LEFT__SINCE: u32 = 1;
1052 /// Since when the resize_edge.top_left enum variant is available.
1053 #[allow(dead_code)]
1054 pub const ENM__RESIZE_EDGE_TOP_LEFT__SINCE: u32 = 1;
1055 /// Since when the resize_edge.bottom_left enum variant is available.
1056 #[allow(dead_code)]
1057 pub const ENM__RESIZE_EDGE_BOTTOM_LEFT__SINCE: u32 = 1;
1058 /// Since when the resize_edge.right enum variant is available.
1059 #[allow(dead_code)]
1060 pub const ENM__RESIZE_EDGE_RIGHT__SINCE: u32 = 1;
1061 /// Since when the resize_edge.top_right enum variant is available.
1062 #[allow(dead_code)]
1063 pub const ENM__RESIZE_EDGE_TOP_RIGHT__SINCE: u32 = 1;
1064 /// Since when the resize_edge.bottom_right enum variant is available.
1065 #[allow(dead_code)]
1066 pub const ENM__RESIZE_EDGE_BOTTOM_RIGHT__SINCE: u32 = 1;
1067
1068 /// Since when the state.maximized enum variant is available.
1069 #[allow(dead_code)]
1070 pub const ENM__STATE_MAXIMIZED__SINCE: u32 = 1;
1071 /// Since when the state.fullscreen enum variant is available.
1072 #[allow(dead_code)]
1073 pub const ENM__STATE_FULLSCREEN__SINCE: u32 = 1;
1074 /// Since when the state.resizing enum variant is available.
1075 #[allow(dead_code)]
1076 pub const ENM__STATE_RESIZING__SINCE: u32 = 1;
1077 /// Since when the state.activated enum variant is available.
1078 #[allow(dead_code)]
1079 pub const ENM__STATE_ACTIVATED__SINCE: u32 = 1;
1080 /// Since when the state.tiled_left enum variant is available.
1081 #[allow(dead_code)]
1082 pub const ENM__STATE_TILED_LEFT__SINCE: u32 = 2;
1083 /// Since when the state.tiled_right enum variant is available.
1084 #[allow(dead_code)]
1085 pub const ENM__STATE_TILED_RIGHT__SINCE: u32 = 2;
1086 /// Since when the state.tiled_top enum variant is available.
1087 #[allow(dead_code)]
1088 pub const ENM__STATE_TILED_TOP__SINCE: u32 = 2;
1089 /// Since when the state.tiled_bottom enum variant is available.
1090 #[allow(dead_code)]
1091 pub const ENM__STATE_TILED_BOTTOM__SINCE: u32 = 2;
1092 /// Since when the state.suspended enum variant is available.
1093 #[allow(dead_code)]
1094 pub const ENM__STATE_SUSPENDED__SINCE: u32 = 6;
1095
1096 /// Since when the wm_capabilities.window_menu enum variant is available.
1097 #[allow(dead_code)]
1098 pub const ENM__WM_CAPABILITIES_WINDOW_MENU__SINCE: u32 = 1;
1099 /// Since when the wm_capabilities.maximize enum variant is available.
1100 #[allow(dead_code)]
1101 pub const ENM__WM_CAPABILITIES_MAXIMIZE__SINCE: u32 = 1;
1102 /// Since when the wm_capabilities.fullscreen enum variant is available.
1103 #[allow(dead_code)]
1104 pub const ENM__WM_CAPABILITIES_FULLSCREEN__SINCE: u32 = 1;
1105 /// Since when the wm_capabilities.minimize enum variant is available.
1106 #[allow(dead_code)]
1107 pub const ENM__WM_CAPABILITIES_MINIMIZE__SINCE: u32 = 1;
1108}
1109
1110#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1111#[allow(dead_code)]
1112pub struct XdgToplevelError(pub u32);
1113
1114impl XdgToplevelError {
1115 /// provided value is
1116 /// not a valid variant of the resize_edge enum
1117 #[allow(dead_code)]
1118 pub const INVALID_RESIZE_EDGE: Self = Self(0);
1119
1120 /// invalid parent toplevel
1121 #[allow(dead_code)]
1122 pub const INVALID_PARENT: Self = Self(1);
1123
1124 /// client provided an invalid min or max size
1125 #[allow(dead_code)]
1126 pub const INVALID_SIZE: Self = Self(2);
1127}
1128
1129impl Debug for XdgToplevelError {
1130 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1131 let name = match *self {
1132 Self::INVALID_RESIZE_EDGE => "INVALID_RESIZE_EDGE",
1133 Self::INVALID_PARENT => "INVALID_PARENT",
1134 Self::INVALID_SIZE => "INVALID_SIZE",
1135 _ => return Debug::fmt(&self.0, f),
1136 };
1137 f.write_str(name)
1138 }
1139}
1140
1141/// edge values for resizing
1142///
1143/// These values are used to indicate which edge of a surface
1144/// is being dragged in a resize operation.
1145#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1146#[allow(dead_code)]
1147pub struct XdgToplevelResizeEdge(pub u32);
1148
1149impl XdgToplevelResizeEdge {
1150 #[allow(dead_code)]
1151 pub const NONE: Self = Self(0);
1152
1153 #[allow(dead_code)]
1154 pub const TOP: Self = Self(1);
1155
1156 #[allow(dead_code)]
1157 pub const BOTTOM: Self = Self(2);
1158
1159 #[allow(dead_code)]
1160 pub const LEFT: Self = Self(4);
1161
1162 #[allow(dead_code)]
1163 pub const TOP_LEFT: Self = Self(5);
1164
1165 #[allow(dead_code)]
1166 pub const BOTTOM_LEFT: Self = Self(6);
1167
1168 #[allow(dead_code)]
1169 pub const RIGHT: Self = Self(8);
1170
1171 #[allow(dead_code)]
1172 pub const TOP_RIGHT: Self = Self(9);
1173
1174 #[allow(dead_code)]
1175 pub const BOTTOM_RIGHT: Self = Self(10);
1176}
1177
1178impl Debug for XdgToplevelResizeEdge {
1179 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1180 let name = match *self {
1181 Self::NONE => "NONE",
1182 Self::TOP => "TOP",
1183 Self::BOTTOM => "BOTTOM",
1184 Self::LEFT => "LEFT",
1185 Self::TOP_LEFT => "TOP_LEFT",
1186 Self::BOTTOM_LEFT => "BOTTOM_LEFT",
1187 Self::RIGHT => "RIGHT",
1188 Self::TOP_RIGHT => "TOP_RIGHT",
1189 Self::BOTTOM_RIGHT => "BOTTOM_RIGHT",
1190 _ => return Debug::fmt(&self.0, f),
1191 };
1192 f.write_str(name)
1193 }
1194}
1195
1196/// types of state on the surface
1197///
1198/// The different state values used on the surface. This is designed for
1199/// state values like maximized, fullscreen. It is paired with the
1200/// configure event to ensure that both the client and the compositor
1201/// setting the state can be synchronized.
1202///
1203/// States set in this way are double-buffered, see wl_surface.commit.
1204#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1205#[allow(dead_code)]
1206pub struct XdgToplevelState(pub u32);
1207
1208impl XdgToplevelState {
1209 /// the surface is maximized
1210 ///
1211 /// the surface is maximized
1212 ///
1213 /// The surface is maximized. The window geometry specified in the configure
1214 /// event must be obeyed by the client, or the xdg_wm_base.invalid_surface_state
1215 /// error is raised.
1216 ///
1217 /// The client should draw without shadow or other
1218 /// decoration outside of the window geometry.
1219 #[allow(dead_code)]
1220 pub const MAXIMIZED: Self = Self(1);
1221
1222 /// the surface is fullscreen
1223 ///
1224 /// the surface is fullscreen
1225 ///
1226 /// The surface is fullscreen. The window geometry specified in the
1227 /// configure event is a maximum; the client cannot resize beyond it. For
1228 /// a surface to cover the whole fullscreened area, the geometry
1229 /// dimensions must be obeyed by the client. For more details, see
1230 /// xdg_toplevel.set_fullscreen.
1231 #[allow(dead_code)]
1232 pub const FULLSCREEN: Self = Self(2);
1233
1234 /// the surface is being resized
1235 ///
1236 /// the surface is being resized
1237 ///
1238 /// The surface is being resized. The window geometry specified in the
1239 /// configure event is a maximum; the client cannot resize beyond it.
1240 /// Clients that have aspect ratio or cell sizing configuration can use
1241 /// a smaller size, however.
1242 #[allow(dead_code)]
1243 pub const RESIZING: Self = Self(3);
1244
1245 /// the surface is now activated
1246 ///
1247 /// the surface is now activated
1248 ///
1249 /// Client window decorations should be painted as if the window is
1250 /// active. Do not assume this means that the window actually has
1251 /// keyboard or pointer focus.
1252 #[allow(dead_code)]
1253 pub const ACTIVATED: Self = Self(4);
1254
1255 /// the surface’s left edge is tiled
1256 ///
1257 /// The window is currently in a tiled layout and the left edge is
1258 /// considered to be adjacent to another part of the tiling grid.
1259 ///
1260 /// The client should draw without shadow or other decoration outside of
1261 /// the window geometry on the left edge.
1262 #[allow(dead_code)]
1263 pub const TILED_LEFT: Self = Self(5);
1264
1265 /// the surface’s right edge is tiled
1266 ///
1267 /// The window is currently in a tiled layout and the right edge is
1268 /// considered to be adjacent to another part of the tiling grid.
1269 ///
1270 /// The client should draw without shadow or other decoration outside of
1271 /// the window geometry on the right edge.
1272 #[allow(dead_code)]
1273 pub const TILED_RIGHT: Self = Self(6);
1274
1275 /// the surface’s top edge is tiled
1276 ///
1277 /// The window is currently in a tiled layout and the top edge is
1278 /// considered to be adjacent to another part of the tiling grid.
1279 ///
1280 /// The client should draw without shadow or other decoration outside of
1281 /// the window geometry on the top edge.
1282 #[allow(dead_code)]
1283 pub const TILED_TOP: Self = Self(7);
1284
1285 /// the surface’s bottom edge is tiled
1286 ///
1287 /// The window is currently in a tiled layout and the bottom edge is
1288 /// considered to be adjacent to another part of the tiling grid.
1289 ///
1290 /// The client should draw without shadow or other decoration outside of
1291 /// the window geometry on the bottom edge.
1292 #[allow(dead_code)]
1293 pub const TILED_BOTTOM: Self = Self(8);
1294
1295 /// surface repaint is suspended
1296 ///
1297 /// The surface is currently not ordinarily being repainted; for
1298 /// example because its content is occluded by another window, or its
1299 /// outputs are switched off due to screen locking.
1300 #[allow(dead_code)]
1301 pub const SUSPENDED: Self = Self(9);
1302}
1303
1304impl Debug for XdgToplevelState {
1305 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1306 let name = match *self {
1307 Self::MAXIMIZED => "MAXIMIZED",
1308 Self::FULLSCREEN => "FULLSCREEN",
1309 Self::RESIZING => "RESIZING",
1310 Self::ACTIVATED => "ACTIVATED",
1311 Self::TILED_LEFT => "TILED_LEFT",
1312 Self::TILED_RIGHT => "TILED_RIGHT",
1313 Self::TILED_TOP => "TILED_TOP",
1314 Self::TILED_BOTTOM => "TILED_BOTTOM",
1315 Self::SUSPENDED => "SUSPENDED",
1316 _ => return Debug::fmt(&self.0, f),
1317 };
1318 f.write_str(name)
1319 }
1320}
1321
1322#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1323#[allow(dead_code)]
1324pub struct XdgToplevelWmCapabilities(pub u32);
1325
1326impl XdgToplevelWmCapabilities {
1327 /// show_window_menu is available
1328 #[allow(dead_code)]
1329 pub const WINDOW_MENU: Self = Self(1);
1330
1331 /// set_maximized and unset_maximized are available
1332 #[allow(dead_code)]
1333 pub const MAXIMIZE: Self = Self(2);
1334
1335 /// set_fullscreen and unset_fullscreen are available
1336 #[allow(dead_code)]
1337 pub const FULLSCREEN: Self = Self(3);
1338
1339 /// set_minimized is available
1340 #[allow(dead_code)]
1341 pub const MINIMIZE: Self = Self(4);
1342}
1343
1344impl Debug for XdgToplevelWmCapabilities {
1345 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1346 let name = match *self {
1347 Self::WINDOW_MENU => "WINDOW_MENU",
1348 Self::MAXIMIZE => "MAXIMIZE",
1349 Self::FULLSCREEN => "FULLSCREEN",
1350 Self::MINIMIZE => "MINIMIZE",
1351 _ => return Debug::fmt(&self.0, f),
1352 };
1353 f.write_str(name)
1354 }
1355}
1356
1357/// Functional event handlers.
1358pub mod event_handlers {
1359 use super::*;
1360
1361 /// Event handler for configure events.
1362 pub struct Configure<F>(F);
1363 impl<F> XdgToplevelEventHandler for Configure<F>
1364 where
1365 F: Fn(&XdgToplevelRef, i32, i32, &[u8]),
1366 {
1367 #[inline]
1368 fn configure(&self, _slf: &XdgToplevelRef, width: i32, height: i32, states: &[u8]) {
1369 self.0(_slf, width, height, states)
1370 }
1371 }
1372
1373 /// Event handler for close events.
1374 pub struct Close<F>(F);
1375 impl<F> XdgToplevelEventHandler for Close<F>
1376 where
1377 F: Fn(&XdgToplevelRef),
1378 {
1379 #[inline]
1380 fn close(&self, _slf: &XdgToplevelRef) {
1381 self.0(_slf)
1382 }
1383 }
1384
1385 /// Event handler for configure_bounds events.
1386 pub struct ConfigureBounds<F>(F);
1387 impl<F> XdgToplevelEventHandler for ConfigureBounds<F>
1388 where
1389 F: Fn(&XdgToplevelRef, i32, i32),
1390 {
1391 #[inline]
1392 fn configure_bounds(&self, _slf: &XdgToplevelRef, width: i32, height: i32) {
1393 self.0(_slf, width, height)
1394 }
1395 }
1396
1397 /// Event handler for wm_capabilities events.
1398 pub struct WmCapabilities<F>(F);
1399 impl<F> XdgToplevelEventHandler for WmCapabilities<F>
1400 where
1401 F: Fn(&XdgToplevelRef, &[u8]),
1402 {
1403 #[inline]
1404 fn wm_capabilities(&self, _slf: &XdgToplevelRef, capabilities: &[u8]) {
1405 self.0(_slf, capabilities)
1406 }
1407 }
1408
1409 impl XdgToplevel {
1410 /// Creates an event handler for configure events.
1411 ///
1412 /// The event handler ignores all other events.
1413 #[allow(dead_code)]
1414 pub fn on_configure<F>(f: F) -> Configure<F>
1415 where
1416 F: Fn(&XdgToplevelRef, i32, i32, &[u8]),
1417 {
1418 Configure(f)
1419 }
1420
1421 /// Creates an event handler for close events.
1422 ///
1423 /// The event handler ignores all other events.
1424 #[allow(dead_code)]
1425 pub fn on_close<F>(f: F) -> Close<F>
1426 where
1427 F: Fn(&XdgToplevelRef),
1428 {
1429 Close(f)
1430 }
1431
1432 /// Creates an event handler for configure_bounds events.
1433 ///
1434 /// The event handler ignores all other events.
1435 #[allow(dead_code)]
1436 pub fn on_configure_bounds<F>(f: F) -> ConfigureBounds<F>
1437 where
1438 F: Fn(&XdgToplevelRef, i32, i32),
1439 {
1440 ConfigureBounds(f)
1441 }
1442
1443 /// Creates an event handler for wm_capabilities events.
1444 ///
1445 /// The event handler ignores all other events.
1446 #[allow(dead_code)]
1447 pub fn on_wm_capabilities<F>(f: F) -> WmCapabilities<F>
1448 where
1449 F: Fn(&XdgToplevelRef, &[u8]),
1450 {
1451 WmCapabilities(f)
1452 }
1453 }
1454}