simple_window/common/protocols_data/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 type Data: 'static;
847
848 /// suggest a surface change
849 ///
850 /// This configure event asks the client to resize its toplevel surface or
851 /// to change its state. The configured state should not be applied
852 /// immediately. See xdg_surface.configure for details.
853 ///
854 /// The width and height arguments specify a hint to the window
855 /// about how its surface should be resized in window geometry
856 /// coordinates. See set_window_geometry.
857 ///
858 /// If the width or height arguments are zero, it means the client
859 /// should decide its own window dimension. This may happen when the
860 /// compositor needs to configure the state of the surface but doesn't
861 /// have any information about any previous or expected dimension.
862 ///
863 /// The states listed in the event specify how the width/height
864 /// arguments should be interpreted, and possibly how it should be
865 /// drawn.
866 ///
867 /// Clients must send an ack_configure in response to this event. See
868 /// xdg_surface.configure and xdg_surface.ack_configure for details.
869 ///
870 /// # Arguments
871 ///
872 /// - `width`:
873 /// - `height`:
874 /// - `states`:
875 #[inline]
876 fn configure(
877 &self,
878 _data: &mut Self::Data,
879 _slf: &XdgToplevelRef,
880 width: i32,
881 height: i32,
882 states: &[u8],
883 ) {
884 let _ = width;
885 let _ = height;
886 let _ = states;
887 }
888
889 /// surface wants to be closed
890 ///
891 /// The close event is sent by the compositor when the user
892 /// wants the surface to be closed. This should be equivalent to
893 /// the user clicking the close button in client-side decorations,
894 /// if your application has any.
895 ///
896 /// This is only a request that the user intends to close the
897 /// window. The client may choose to ignore this request, or show
898 /// a dialog to ask the user to save their data, etc.
899 #[inline]
900 fn close(&self, _data: &mut Self::Data, _slf: &XdgToplevelRef) {}
901
902 /// recommended window geometry bounds
903 ///
904 /// The configure_bounds event may be sent prior to a xdg_toplevel.configure
905 /// event to communicate the bounds a window geometry size is recommended
906 /// to constrain to.
907 ///
908 /// The passed width and height are in surface coordinate space. If width
909 /// and height are 0, it means bounds is unknown and equivalent to as if no
910 /// configure_bounds event was ever sent for this surface.
911 ///
912 /// The bounds can for example correspond to the size of a monitor excluding
913 /// any panels or other shell components, so that a surface isn't created in
914 /// a way that it cannot fit.
915 ///
916 /// The bounds may change at any point, and in such a case, a new
917 /// xdg_toplevel.configure_bounds will be sent, followed by
918 /// xdg_toplevel.configure and xdg_surface.configure.
919 ///
920 /// # Arguments
921 ///
922 /// - `width`:
923 /// - `height`:
924 #[inline]
925 fn configure_bounds(
926 &self,
927 _data: &mut Self::Data,
928 _slf: &XdgToplevelRef,
929 width: i32,
930 height: i32,
931 ) {
932 let _ = width;
933 let _ = height;
934 }
935
936 /// compositor capabilities
937 ///
938 /// This event advertises the capabilities supported by the compositor. If
939 /// a capability isn't supported, clients should hide or disable the UI
940 /// elements that expose this functionality. For instance, if the
941 /// compositor doesn't advertise support for minimized toplevels, a button
942 /// triggering the set_minimized request should not be displayed.
943 ///
944 /// The compositor will ignore requests it doesn't support. For instance,
945 /// a compositor which doesn't advertise support for minimized will ignore
946 /// set_minimized requests.
947 ///
948 /// Compositors must send this event once before the first
949 /// xdg_surface.configure event. When the capabilities change, compositors
950 /// must send this event again and then send an xdg_surface.configure
951 /// event.
952 ///
953 /// The configured state should not be applied immediately. See
954 /// xdg_surface.configure for details.
955 ///
956 /// The capabilities are sent as an array of 32-bit unsigned integers in
957 /// native endianness.
958 ///
959 /// # Arguments
960 ///
961 /// - `capabilities`: array of 32-bit capabilities
962 #[inline]
963 fn wm_capabilities(&self, _data: &mut Self::Data, _slf: &XdgToplevelRef, capabilities: &[u8]) {
964 let _ = capabilities;
965 }
966}
967
968impl XdgToplevelEventHandler for private::NoOpEventHandler {
969 type Data = ();
970}
971
972// SAFETY: - INTERFACE is a valid wl_interface
973// - mutable_type always returns the same value
974unsafe impl<H> EventHandler for private::EventHandler<H>
975where
976 H: XdgToplevelEventHandler,
977{
978 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
979
980 #[inline]
981 fn mutable_type() -> Option<(TypeId, &'static str)> {
982 let id = TypeId::of::<H::Data>();
983 let name = std::any::type_name::<H::Data>();
984 Some((id, name))
985 }
986
987 #[allow(unused_variables)]
988 unsafe fn handle_event(
989 &self,
990 queue: &Queue,
991 data: *mut u8,
992 slf: &UntypedBorrowedProxy,
993 opcode: u32,
994 args: *mut wl_argument,
995 ) {
996 // SAFETY: This function requires that slf has the interface INTERFACE
997 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<XdgToplevelRef>(slf) };
998 // SAFETY: This function requires that data is `&mut T` where `T`
999 // has the type id returned by `Self::mutable_type`, i.e.,
1000 // `T = H::Data`.
1001 let data: &mut H::Data = unsafe { &mut *data.cast() };
1002 match opcode {
1003 0 => {
1004 // SAFETY: INTERFACE requires that there are 3 arguments
1005 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
1006 // SAFETY: - INTERFACE requires that args[0] contains an int
1007 let arg0 = unsafe { args[0].i };
1008 // SAFETY: - INTERFACE requires that args[1] contains an int
1009 let arg1 = unsafe { args[1].i };
1010 // SAFETY: - INTERFACE requires that args[2] contains an array
1011 let arg2 = unsafe {
1012 let a = &*args[2].a;
1013 std::slice::from_raw_parts(a.data.cast(), a.size)
1014 };
1015 self.0.configure(data, slf, arg0, arg1, arg2);
1016 }
1017 1 => {
1018 self.0.close(data, slf);
1019 }
1020 2 => {
1021 // SAFETY: INTERFACE requires that there are 2 arguments
1022 let args = unsafe { &*args.cast::<[wl_argument; 2]>() };
1023 // SAFETY: - INTERFACE requires that args[0] contains an int
1024 let arg0 = unsafe { args[0].i };
1025 // SAFETY: - INTERFACE requires that args[1] contains an int
1026 let arg1 = unsafe { args[1].i };
1027 self.0.configure_bounds(data, slf, arg0, arg1);
1028 }
1029 3 => {
1030 // SAFETY: INTERFACE requires that there are 1 arguments
1031 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1032 // SAFETY: - INTERFACE requires that args[0] contains an array
1033 let arg0 = unsafe {
1034 let a = &*args[0].a;
1035 std::slice::from_raw_parts(a.data.cast(), a.size)
1036 };
1037 self.0.wm_capabilities(data, slf, arg0);
1038 }
1039 _ => {
1040 invalid_opcode("xdg_toplevel", opcode);
1041 }
1042 }
1043 }
1044}
1045
1046impl<H> CreateEventHandler<H> for private::ProxyApi
1047where
1048 H: XdgToplevelEventHandler,
1049{
1050 type EventHandler = private::EventHandler<H>;
1051
1052 #[inline]
1053 fn create_event_handler(handler: H) -> Self::EventHandler {
1054 private::EventHandler(handler)
1055 }
1056}
1057
1058impl XdgToplevel {
1059 /// Since when the error.invalid_resize_edge enum variant is available.
1060 #[allow(dead_code)]
1061 pub const ENM__ERROR_INVALID_RESIZE_EDGE__SINCE: u32 = 1;
1062 /// Since when the error.invalid_parent enum variant is available.
1063 #[allow(dead_code)]
1064 pub const ENM__ERROR_INVALID_PARENT__SINCE: u32 = 1;
1065 /// Since when the error.invalid_size enum variant is available.
1066 #[allow(dead_code)]
1067 pub const ENM__ERROR_INVALID_SIZE__SINCE: u32 = 1;
1068
1069 /// Since when the resize_edge.none enum variant is available.
1070 #[allow(dead_code)]
1071 pub const ENM__RESIZE_EDGE_NONE__SINCE: u32 = 1;
1072 /// Since when the resize_edge.top enum variant is available.
1073 #[allow(dead_code)]
1074 pub const ENM__RESIZE_EDGE_TOP__SINCE: u32 = 1;
1075 /// Since when the resize_edge.bottom enum variant is available.
1076 #[allow(dead_code)]
1077 pub const ENM__RESIZE_EDGE_BOTTOM__SINCE: u32 = 1;
1078 /// Since when the resize_edge.left enum variant is available.
1079 #[allow(dead_code)]
1080 pub const ENM__RESIZE_EDGE_LEFT__SINCE: u32 = 1;
1081 /// Since when the resize_edge.top_left enum variant is available.
1082 #[allow(dead_code)]
1083 pub const ENM__RESIZE_EDGE_TOP_LEFT__SINCE: u32 = 1;
1084 /// Since when the resize_edge.bottom_left enum variant is available.
1085 #[allow(dead_code)]
1086 pub const ENM__RESIZE_EDGE_BOTTOM_LEFT__SINCE: u32 = 1;
1087 /// Since when the resize_edge.right enum variant is available.
1088 #[allow(dead_code)]
1089 pub const ENM__RESIZE_EDGE_RIGHT__SINCE: u32 = 1;
1090 /// Since when the resize_edge.top_right enum variant is available.
1091 #[allow(dead_code)]
1092 pub const ENM__RESIZE_EDGE_TOP_RIGHT__SINCE: u32 = 1;
1093 /// Since when the resize_edge.bottom_right enum variant is available.
1094 #[allow(dead_code)]
1095 pub const ENM__RESIZE_EDGE_BOTTOM_RIGHT__SINCE: u32 = 1;
1096
1097 /// Since when the state.maximized enum variant is available.
1098 #[allow(dead_code)]
1099 pub const ENM__STATE_MAXIMIZED__SINCE: u32 = 1;
1100 /// Since when the state.fullscreen enum variant is available.
1101 #[allow(dead_code)]
1102 pub const ENM__STATE_FULLSCREEN__SINCE: u32 = 1;
1103 /// Since when the state.resizing enum variant is available.
1104 #[allow(dead_code)]
1105 pub const ENM__STATE_RESIZING__SINCE: u32 = 1;
1106 /// Since when the state.activated enum variant is available.
1107 #[allow(dead_code)]
1108 pub const ENM__STATE_ACTIVATED__SINCE: u32 = 1;
1109 /// Since when the state.tiled_left enum variant is available.
1110 #[allow(dead_code)]
1111 pub const ENM__STATE_TILED_LEFT__SINCE: u32 = 2;
1112 /// Since when the state.tiled_right enum variant is available.
1113 #[allow(dead_code)]
1114 pub const ENM__STATE_TILED_RIGHT__SINCE: u32 = 2;
1115 /// Since when the state.tiled_top enum variant is available.
1116 #[allow(dead_code)]
1117 pub const ENM__STATE_TILED_TOP__SINCE: u32 = 2;
1118 /// Since when the state.tiled_bottom enum variant is available.
1119 #[allow(dead_code)]
1120 pub const ENM__STATE_TILED_BOTTOM__SINCE: u32 = 2;
1121 /// Since when the state.suspended enum variant is available.
1122 #[allow(dead_code)]
1123 pub const ENM__STATE_SUSPENDED__SINCE: u32 = 6;
1124
1125 /// Since when the wm_capabilities.window_menu enum variant is available.
1126 #[allow(dead_code)]
1127 pub const ENM__WM_CAPABILITIES_WINDOW_MENU__SINCE: u32 = 1;
1128 /// Since when the wm_capabilities.maximize enum variant is available.
1129 #[allow(dead_code)]
1130 pub const ENM__WM_CAPABILITIES_MAXIMIZE__SINCE: u32 = 1;
1131 /// Since when the wm_capabilities.fullscreen enum variant is available.
1132 #[allow(dead_code)]
1133 pub const ENM__WM_CAPABILITIES_FULLSCREEN__SINCE: u32 = 1;
1134 /// Since when the wm_capabilities.minimize enum variant is available.
1135 #[allow(dead_code)]
1136 pub const ENM__WM_CAPABILITIES_MINIMIZE__SINCE: u32 = 1;
1137}
1138
1139#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1140#[allow(dead_code)]
1141pub struct XdgToplevelError(pub u32);
1142
1143impl XdgToplevelError {
1144 /// provided value is
1145 /// not a valid variant of the resize_edge enum
1146 #[allow(dead_code)]
1147 pub const INVALID_RESIZE_EDGE: Self = Self(0);
1148
1149 /// invalid parent toplevel
1150 #[allow(dead_code)]
1151 pub const INVALID_PARENT: Self = Self(1);
1152
1153 /// client provided an invalid min or max size
1154 #[allow(dead_code)]
1155 pub const INVALID_SIZE: Self = Self(2);
1156}
1157
1158impl Debug for XdgToplevelError {
1159 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1160 let name = match *self {
1161 Self::INVALID_RESIZE_EDGE => "INVALID_RESIZE_EDGE",
1162 Self::INVALID_PARENT => "INVALID_PARENT",
1163 Self::INVALID_SIZE => "INVALID_SIZE",
1164 _ => return Debug::fmt(&self.0, f),
1165 };
1166 f.write_str(name)
1167 }
1168}
1169
1170/// edge values for resizing
1171///
1172/// These values are used to indicate which edge of a surface
1173/// is being dragged in a resize operation.
1174#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1175#[allow(dead_code)]
1176pub struct XdgToplevelResizeEdge(pub u32);
1177
1178impl XdgToplevelResizeEdge {
1179 #[allow(dead_code)]
1180 pub const NONE: Self = Self(0);
1181
1182 #[allow(dead_code)]
1183 pub const TOP: Self = Self(1);
1184
1185 #[allow(dead_code)]
1186 pub const BOTTOM: Self = Self(2);
1187
1188 #[allow(dead_code)]
1189 pub const LEFT: Self = Self(4);
1190
1191 #[allow(dead_code)]
1192 pub const TOP_LEFT: Self = Self(5);
1193
1194 #[allow(dead_code)]
1195 pub const BOTTOM_LEFT: Self = Self(6);
1196
1197 #[allow(dead_code)]
1198 pub const RIGHT: Self = Self(8);
1199
1200 #[allow(dead_code)]
1201 pub const TOP_RIGHT: Self = Self(9);
1202
1203 #[allow(dead_code)]
1204 pub const BOTTOM_RIGHT: Self = Self(10);
1205}
1206
1207impl Debug for XdgToplevelResizeEdge {
1208 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1209 let name = match *self {
1210 Self::NONE => "NONE",
1211 Self::TOP => "TOP",
1212 Self::BOTTOM => "BOTTOM",
1213 Self::LEFT => "LEFT",
1214 Self::TOP_LEFT => "TOP_LEFT",
1215 Self::BOTTOM_LEFT => "BOTTOM_LEFT",
1216 Self::RIGHT => "RIGHT",
1217 Self::TOP_RIGHT => "TOP_RIGHT",
1218 Self::BOTTOM_RIGHT => "BOTTOM_RIGHT",
1219 _ => return Debug::fmt(&self.0, f),
1220 };
1221 f.write_str(name)
1222 }
1223}
1224
1225/// types of state on the surface
1226///
1227/// The different state values used on the surface. This is designed for
1228/// state values like maximized, fullscreen. It is paired with the
1229/// configure event to ensure that both the client and the compositor
1230/// setting the state can be synchronized.
1231///
1232/// States set in this way are double-buffered, see wl_surface.commit.
1233#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1234#[allow(dead_code)]
1235pub struct XdgToplevelState(pub u32);
1236
1237impl XdgToplevelState {
1238 /// the surface is maximized
1239 ///
1240 /// the surface is maximized
1241 ///
1242 /// The surface is maximized. The window geometry specified in the configure
1243 /// event must be obeyed by the client, or the xdg_wm_base.invalid_surface_state
1244 /// error is raised.
1245 ///
1246 /// The client should draw without shadow or other
1247 /// decoration outside of the window geometry.
1248 #[allow(dead_code)]
1249 pub const MAXIMIZED: Self = Self(1);
1250
1251 /// the surface is fullscreen
1252 ///
1253 /// the surface is fullscreen
1254 ///
1255 /// The surface is fullscreen. The window geometry specified in the
1256 /// configure event is a maximum; the client cannot resize beyond it. For
1257 /// a surface to cover the whole fullscreened area, the geometry
1258 /// dimensions must be obeyed by the client. For more details, see
1259 /// xdg_toplevel.set_fullscreen.
1260 #[allow(dead_code)]
1261 pub const FULLSCREEN: Self = Self(2);
1262
1263 /// the surface is being resized
1264 ///
1265 /// the surface is being resized
1266 ///
1267 /// The surface is being resized. The window geometry specified in the
1268 /// configure event is a maximum; the client cannot resize beyond it.
1269 /// Clients that have aspect ratio or cell sizing configuration can use
1270 /// a smaller size, however.
1271 #[allow(dead_code)]
1272 pub const RESIZING: Self = Self(3);
1273
1274 /// the surface is now activated
1275 ///
1276 /// the surface is now activated
1277 ///
1278 /// Client window decorations should be painted as if the window is
1279 /// active. Do not assume this means that the window actually has
1280 /// keyboard or pointer focus.
1281 #[allow(dead_code)]
1282 pub const ACTIVATED: Self = Self(4);
1283
1284 /// the surface’s left edge is tiled
1285 ///
1286 /// The window is currently in a tiled layout and the left edge is
1287 /// considered to be adjacent to another part of the tiling grid.
1288 ///
1289 /// The client should draw without shadow or other decoration outside of
1290 /// the window geometry on the left edge.
1291 #[allow(dead_code)]
1292 pub const TILED_LEFT: Self = Self(5);
1293
1294 /// the surface’s right edge is tiled
1295 ///
1296 /// The window is currently in a tiled layout and the right edge is
1297 /// considered to be adjacent to another part of the tiling grid.
1298 ///
1299 /// The client should draw without shadow or other decoration outside of
1300 /// the window geometry on the right edge.
1301 #[allow(dead_code)]
1302 pub const TILED_RIGHT: Self = Self(6);
1303
1304 /// the surface’s top edge is tiled
1305 ///
1306 /// The window is currently in a tiled layout and the top edge is
1307 /// considered to be adjacent to another part of the tiling grid.
1308 ///
1309 /// The client should draw without shadow or other decoration outside of
1310 /// the window geometry on the top edge.
1311 #[allow(dead_code)]
1312 pub const TILED_TOP: Self = Self(7);
1313
1314 /// the surface’s bottom edge is tiled
1315 ///
1316 /// The window is currently in a tiled layout and the bottom edge is
1317 /// considered to be adjacent to another part of the tiling grid.
1318 ///
1319 /// The client should draw without shadow or other decoration outside of
1320 /// the window geometry on the bottom edge.
1321 #[allow(dead_code)]
1322 pub const TILED_BOTTOM: Self = Self(8);
1323
1324 /// surface repaint is suspended
1325 ///
1326 /// The surface is currently not ordinarily being repainted; for
1327 /// example because its content is occluded by another window, or its
1328 /// outputs are switched off due to screen locking.
1329 #[allow(dead_code)]
1330 pub const SUSPENDED: Self = Self(9);
1331}
1332
1333impl Debug for XdgToplevelState {
1334 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1335 let name = match *self {
1336 Self::MAXIMIZED => "MAXIMIZED",
1337 Self::FULLSCREEN => "FULLSCREEN",
1338 Self::RESIZING => "RESIZING",
1339 Self::ACTIVATED => "ACTIVATED",
1340 Self::TILED_LEFT => "TILED_LEFT",
1341 Self::TILED_RIGHT => "TILED_RIGHT",
1342 Self::TILED_TOP => "TILED_TOP",
1343 Self::TILED_BOTTOM => "TILED_BOTTOM",
1344 Self::SUSPENDED => "SUSPENDED",
1345 _ => return Debug::fmt(&self.0, f),
1346 };
1347 f.write_str(name)
1348 }
1349}
1350
1351#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1352#[allow(dead_code)]
1353pub struct XdgToplevelWmCapabilities(pub u32);
1354
1355impl XdgToplevelWmCapabilities {
1356 /// show_window_menu is available
1357 #[allow(dead_code)]
1358 pub const WINDOW_MENU: Self = Self(1);
1359
1360 /// set_maximized and unset_maximized are available
1361 #[allow(dead_code)]
1362 pub const MAXIMIZE: Self = Self(2);
1363
1364 /// set_fullscreen and unset_fullscreen are available
1365 #[allow(dead_code)]
1366 pub const FULLSCREEN: Self = Self(3);
1367
1368 /// set_minimized is available
1369 #[allow(dead_code)]
1370 pub const MINIMIZE: Self = Self(4);
1371}
1372
1373impl Debug for XdgToplevelWmCapabilities {
1374 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1375 let name = match *self {
1376 Self::WINDOW_MENU => "WINDOW_MENU",
1377 Self::MAXIMIZE => "MAXIMIZE",
1378 Self::FULLSCREEN => "FULLSCREEN",
1379 Self::MINIMIZE => "MINIMIZE",
1380 _ => return Debug::fmt(&self.0, f),
1381 };
1382 f.write_str(name)
1383 }
1384}
1385
1386/// Functional event handlers.
1387pub mod event_handlers {
1388 use super::*;
1389
1390 /// Event handler for configure events.
1391 pub struct Configure<T, F>(F, PhantomData<fn(&mut T)>);
1392 impl<T, F> XdgToplevelEventHandler for Configure<T, F>
1393 where
1394 T: 'static,
1395 F: Fn(&mut T, &XdgToplevelRef, i32, i32, &[u8]),
1396 {
1397 type Data = T;
1398
1399 #[inline]
1400 fn configure(
1401 &self,
1402 _data: &mut T,
1403 _slf: &XdgToplevelRef,
1404 width: i32,
1405 height: i32,
1406 states: &[u8],
1407 ) {
1408 self.0(_data, _slf, width, height, states)
1409 }
1410 }
1411
1412 /// Event handler for close events.
1413 pub struct Close<T, F>(F, PhantomData<fn(&mut T)>);
1414 impl<T, F> XdgToplevelEventHandler for Close<T, F>
1415 where
1416 T: 'static,
1417 F: Fn(&mut T, &XdgToplevelRef),
1418 {
1419 type Data = T;
1420
1421 #[inline]
1422 fn close(&self, _data: &mut T, _slf: &XdgToplevelRef) {
1423 self.0(_data, _slf)
1424 }
1425 }
1426
1427 /// Event handler for configure_bounds events.
1428 pub struct ConfigureBounds<T, F>(F, PhantomData<fn(&mut T)>);
1429 impl<T, F> XdgToplevelEventHandler for ConfigureBounds<T, F>
1430 where
1431 T: 'static,
1432 F: Fn(&mut T, &XdgToplevelRef, i32, i32),
1433 {
1434 type Data = T;
1435
1436 #[inline]
1437 fn configure_bounds(&self, _data: &mut T, _slf: &XdgToplevelRef, width: i32, height: i32) {
1438 self.0(_data, _slf, width, height)
1439 }
1440 }
1441
1442 /// Event handler for wm_capabilities events.
1443 pub struct WmCapabilities<T, F>(F, PhantomData<fn(&mut T)>);
1444 impl<T, F> XdgToplevelEventHandler for WmCapabilities<T, F>
1445 where
1446 T: 'static,
1447 F: Fn(&mut T, &XdgToplevelRef, &[u8]),
1448 {
1449 type Data = T;
1450
1451 #[inline]
1452 fn wm_capabilities(&self, _data: &mut T, _slf: &XdgToplevelRef, capabilities: &[u8]) {
1453 self.0(_data, _slf, capabilities)
1454 }
1455 }
1456
1457 impl XdgToplevel {
1458 /// Creates an event handler for configure events.
1459 ///
1460 /// The event handler ignores all other events.
1461 #[allow(dead_code)]
1462 pub fn on_configure<T, F>(f: F) -> Configure<T, F>
1463 where
1464 T: 'static,
1465 F: Fn(&mut T, &XdgToplevelRef, i32, i32, &[u8]),
1466 {
1467 Configure(f, PhantomData)
1468 }
1469
1470 /// Creates an event handler for close events.
1471 ///
1472 /// The event handler ignores all other events.
1473 #[allow(dead_code)]
1474 pub fn on_close<T, F>(f: F) -> Close<T, F>
1475 where
1476 T: 'static,
1477 F: Fn(&mut T, &XdgToplevelRef),
1478 {
1479 Close(f, PhantomData)
1480 }
1481
1482 /// Creates an event handler for configure_bounds events.
1483 ///
1484 /// The event handler ignores all other events.
1485 #[allow(dead_code)]
1486 pub fn on_configure_bounds<T, F>(f: F) -> ConfigureBounds<T, F>
1487 where
1488 T: 'static,
1489 F: Fn(&mut T, &XdgToplevelRef, i32, i32),
1490 {
1491 ConfigureBounds(f, PhantomData)
1492 }
1493
1494 /// Creates an event handler for wm_capabilities events.
1495 ///
1496 /// The event handler ignores all other events.
1497 #[allow(dead_code)]
1498 pub fn on_wm_capabilities<T, F>(f: F) -> WmCapabilities<T, F>
1499 where
1500 T: 'static,
1501 F: Fn(&mut T, &XdgToplevelRef, &[u8]),
1502 {
1503 WmCapabilities(f, PhantomData)
1504 }
1505 }
1506}