simple_window/common/protocols_data/xdg_shell/xdg_surface.rs
1//! desktop user interface surface base interface
2//!
3//! An interface that may be implemented by a wl_surface, for
4//! implementations that provide a desktop-style user interface.
5//!
6//! It provides a base set of functionality required to construct user
7//! interface elements requiring management by the compositor, such as
8//! toplevel windows, menus, etc. The types of functionality are split into
9//! xdg_surface roles.
10//!
11//! Creating an xdg_surface does not set the role for a wl_surface. In order
12//! to map an xdg_surface, the client must create a role-specific object
13//! using, e.g., get_toplevel, get_popup. The wl_surface for any given
14//! xdg_surface can have at most one role, and may not be assigned any role
15//! not based on xdg_surface.
16//!
17//! A role must be assigned before any other requests are made to the
18//! xdg_surface object.
19//!
20//! The client must call wl_surface.commit on the corresponding wl_surface
21//! for the xdg_surface state to take effect.
22//!
23//! Creating an xdg_surface from a wl_surface which has a buffer attached or
24//! committed is a client error, and any attempts by a client to attach or
25//! manipulate a buffer prior to the first xdg_surface.configure call must
26//! also be treated as errors.
27//!
28//! After creating a role-specific object and setting it up (e.g. by sending
29//! the title, app ID, size constraints, parent, etc), the client must
30//! perform an initial commit without any buffer attached. The compositor
31//! will reply with initial wl_surface state such as
32//! wl_surface.preferred_buffer_scale followed by an xdg_surface.configure
33//! event. The client must acknowledge it and is then allowed to attach a
34//! buffer to map the surface.
35//!
36//! Mapping an xdg_surface-based role surface is defined as making it
37//! possible for the surface to be shown by the compositor. Note that
38//! a mapped surface is not guaranteed to be visible once it is mapped.
39//!
40//! For an xdg_surface to be mapped by the compositor, the following
41//! conditions must be met:
42//! (1) the client has assigned an xdg_surface-based role to the surface
43//! (2) the client has set and committed the xdg_surface state and the
44//! role-dependent state to the surface
45//! (3) the client has committed a buffer to the surface
46//!
47//! A newly-unmapped surface is considered to have met condition (1) out
48//! of the 3 required conditions for mapping a surface if its role surface
49//! has not been destroyed, i.e. the client must perform the initial commit
50//! again before attaching a buffer.
51
52use {super::super::all_types::*, ::wl_client::builder::prelude::*};
53
54static INTERFACE: wl_interface = wl_interface {
55 name: c"xdg_surface".as_ptr(),
56 version: 6,
57 method_count: 5,
58 methods: {
59 static MESSAGES: [wl_message; 5] = [
60 wl_message {
61 name: c"destroy".as_ptr(),
62 signature: c"".as_ptr(),
63 types: {
64 static TYPES: [Option<&'static wl_interface>; 0] = [];
65 TYPES.as_ptr().cast()
66 },
67 },
68 wl_message {
69 name: c"get_toplevel".as_ptr(),
70 signature: c"n".as_ptr(),
71 types: {
72 static TYPES: [Option<&'static wl_interface>; 1] =
73 [Some(XdgToplevel::WL_INTERFACE)];
74 TYPES.as_ptr().cast()
75 },
76 },
77 wl_message {
78 name: c"get_popup".as_ptr(),
79 signature: c"n?oo".as_ptr(),
80 types: {
81 static TYPES: [Option<&'static wl_interface>; 3] = [
82 Some(XdgPopup::WL_INTERFACE),
83 Some(XdgSurface::WL_INTERFACE),
84 Some(XdgPositioner::WL_INTERFACE),
85 ];
86 TYPES.as_ptr().cast()
87 },
88 },
89 wl_message {
90 name: c"set_window_geometry".as_ptr(),
91 signature: c"iiii".as_ptr(),
92 types: {
93 static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
94 TYPES.as_ptr().cast()
95 },
96 },
97 wl_message {
98 name: c"ack_configure".as_ptr(),
99 signature: c"u".as_ptr(),
100 types: {
101 static TYPES: [Option<&'static wl_interface>; 1] = [None];
102 TYPES.as_ptr().cast()
103 },
104 },
105 ];
106 MESSAGES.as_ptr()
107 },
108 event_count: 1,
109 events: {
110 static MESSAGES: [wl_message; 1] = [wl_message {
111 name: c"configure".as_ptr(),
112 signature: c"u".as_ptr(),
113 types: {
114 static TYPES: [Option<&'static wl_interface>; 1] = [None];
115 TYPES.as_ptr().cast()
116 },
117 }];
118 MESSAGES.as_ptr()
119 },
120};
121
122/// An owned xdg_surface proxy.
123///
124/// See the documentation of [the module][self] for the interface description.
125#[derive(Clone, Eq, PartialEq)]
126#[repr(transparent)]
127pub struct XdgSurface {
128 /// This proxy has the interface INTERFACE.
129 proxy: UntypedOwnedProxy,
130}
131
132/// A borrowed xdg_surface proxy.
133///
134/// See the documentation of [the module][self] for the interface description.
135#[derive(Eq, PartialEq)]
136#[repr(transparent)]
137pub struct XdgSurfaceRef {
138 /// This proxy has the interface INTERFACE.
139 proxy: UntypedBorrowedProxy,
140}
141
142// SAFETY: XdgSurface is a transparent wrapper around UntypedOwnedProxy
143unsafe impl UntypedOwnedProxyWrapper for XdgSurface {}
144
145// SAFETY: - INTERFACE is a valid wl_interface
146// - The only invariant is that self.proxy has a compatible interface
147unsafe impl OwnedProxy for XdgSurface {
148 const INTERFACE: &'static str = "xdg_surface";
149 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
150 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
151 private::EventHandler(private::NoOpEventHandler);
152 const MAX_VERSION: u32 = 6;
153
154 type Borrowed = XdgSurfaceRef;
155 type Api = private::ProxyApi;
156 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
157}
158
159// SAFETY: XdgSurfaceRef is a transparent wrapper around UntypedBorrowedProxy
160unsafe impl UntypedBorrowedProxyWrapper for XdgSurfaceRef {}
161
162// SAFETY: - The only invariant is that self.proxy has a compatible interface
163unsafe impl BorrowedProxy for XdgSurfaceRef {
164 type Owned = XdgSurface;
165}
166
167impl Deref for XdgSurface {
168 type Target = XdgSurfaceRef;
169
170 fn deref(&self) -> &Self::Target {
171 proxy::low_level::deref(self)
172 }
173}
174
175mod private {
176 pub struct ProxyApi;
177
178 #[allow(dead_code)]
179 pub struct EventHandler<H>(pub(super) H);
180
181 #[allow(dead_code)]
182 pub struct NoOpEventHandler;
183}
184
185impl Debug for XdgSurface {
186 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
187 write!(f, "xdg_surface#{}", self.proxy.id())
188 }
189}
190
191impl Debug for XdgSurfaceRef {
192 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
193 write!(f, "xdg_surface#{}", self.proxy.id())
194 }
195}
196
197impl PartialEq<XdgSurfaceRef> for XdgSurface {
198 fn eq(&self, other: &XdgSurfaceRef) -> bool {
199 self.proxy == other.proxy
200 }
201}
202
203impl PartialEq<XdgSurface> for XdgSurfaceRef {
204 fn eq(&self, other: &XdgSurface) -> bool {
205 self.proxy == other.proxy
206 }
207}
208
209#[allow(dead_code)]
210impl XdgSurface {
211 /// Since when the destroy request is available.
212 #[allow(dead_code)]
213 pub const REQ__DESTROY__SINCE: u32 = 1;
214
215 /// destroy the xdg_surface
216 ///
217 /// Destroy the xdg_surface object. An xdg_surface must only be destroyed
218 /// after its role object has been destroyed, otherwise
219 /// a defunct_role_object error is raised.
220 #[inline]
221 pub fn destroy(&self) {
222 let mut args = [];
223 // SAFETY: - self.proxy has the interface INTERFACE
224 // - 0 < INTERFACE.method_count = 5
225 // - the request signature is ``
226 unsafe {
227 self.proxy.send_destructor(0, &mut args);
228 }
229 }
230
231 /// Since when the get_toplevel request is available.
232 #[allow(dead_code)]
233 pub const REQ__GET_TOPLEVEL__SINCE: u32 = 1;
234
235 /// assign the xdg_toplevel surface role
236 ///
237 /// This creates an xdg_toplevel object for the given xdg_surface and gives
238 /// the associated wl_surface the xdg_toplevel role.
239 ///
240 /// See the documentation of xdg_toplevel for more details about what an
241 /// xdg_toplevel is and how it is used.
242 #[inline]
243 pub fn get_toplevel(&self) -> XdgToplevel {
244 let mut args = [wl_argument { n: 0 }];
245 // SAFETY: - self.proxy has the interface INTERFACE
246 // - 1 < INTERFACE.method_count = 5
247 // - the request signature is `n`
248 // - OwnedProxy::WL_INTERFACE is always a valid interface
249 let data = unsafe {
250 self.proxy
251 .send_constructor::<false>(1, &mut args, XdgToplevel::WL_INTERFACE, None)
252 };
253 // SAFETY: data has the interface XdgToplevel::WL_INTERFACE
254 unsafe { proxy::low_level::from_untyped_owned(data) }
255 }
256
257 /// Since when the get_popup request is available.
258 #[allow(dead_code)]
259 pub const REQ__GET_POPUP__SINCE: u32 = 1;
260
261 /// assign the xdg_popup surface role
262 ///
263 /// This creates an xdg_popup object for the given xdg_surface and gives
264 /// the associated wl_surface the xdg_popup role.
265 ///
266 /// If null is passed as a parent, a parent surface must be specified using
267 /// some other protocol, before committing the initial state.
268 ///
269 /// See the documentation of xdg_popup for more details about what an
270 /// xdg_popup is and how it is used.
271 ///
272 /// # Arguments
273 ///
274 /// - `parent`:
275 /// - `positioner`:
276 #[inline]
277 pub fn get_popup(
278 &self,
279 parent: Option<&XdgSurfaceRef>,
280 positioner: &XdgPositionerRef,
281 ) -> XdgPopup {
282 let (arg1, arg2) = (parent, positioner);
283 let obj1_lock = arg1.map(|arg1| proxy::lock(arg1));
284 let obj1 = obj1_lock
285 .map(|obj1_lock| check_argument_proxy("parent", obj1_lock.wl_proxy()))
286 .unwrap_or(ptr::null_mut());
287 let obj2_lock = proxy::lock(arg2);
288 let obj2 = check_argument_proxy("positioner", obj2_lock.wl_proxy());
289 let mut args = [
290 wl_argument { n: 0 },
291 wl_argument { o: obj1 },
292 wl_argument { o: obj2 },
293 ];
294 // SAFETY: - self.proxy has the interface INTERFACE
295 // - 2 < INTERFACE.method_count = 5
296 // - the request signature is `n?oo`
297 // - OwnedProxy::WL_INTERFACE is always a valid interface
298 let data = unsafe {
299 self.proxy
300 .send_constructor::<false>(2, &mut args, XdgPopup::WL_INTERFACE, None)
301 };
302 // SAFETY: data has the interface XdgPopup::WL_INTERFACE
303 unsafe { proxy::low_level::from_untyped_owned(data) }
304 }
305}
306
307#[allow(dead_code)]
308impl XdgSurfaceRef {
309 /// assign the xdg_toplevel surface role
310 ///
311 /// This creates an xdg_toplevel object for the given xdg_surface and gives
312 /// the associated wl_surface the xdg_toplevel role.
313 ///
314 /// See the documentation of xdg_toplevel for more details about what an
315 /// xdg_toplevel is and how it is used.
316 ///
317 /// # Arguments
318 ///
319 /// - `_queue`: The queue that the returned proxy is assigned to.
320 #[inline]
321 pub fn get_toplevel(&self, _queue: &Queue) -> XdgToplevel {
322 let mut args = [wl_argument { n: 0 }];
323 // SAFETY: - self.proxy has the interface INTERFACE
324 // - 1 < INTERFACE.method_count = 5
325 // - the request signature is `n`
326 // - OwnedProxy::WL_INTERFACE is always a valid interface
327 let data = unsafe {
328 self.proxy
329 .send_constructor(_queue, 1, &mut args, XdgToplevel::WL_INTERFACE, None)
330 };
331 // SAFETY: data has the interface XdgToplevel::WL_INTERFACE
332 unsafe { proxy::low_level::from_untyped_owned(data) }
333 }
334
335 /// assign the xdg_popup surface role
336 ///
337 /// This creates an xdg_popup object for the given xdg_surface and gives
338 /// the associated wl_surface the xdg_popup role.
339 ///
340 /// If null is passed as a parent, a parent surface must be specified using
341 /// some other protocol, before committing the initial state.
342 ///
343 /// See the documentation of xdg_popup for more details about what an
344 /// xdg_popup is and how it is used.
345 ///
346 /// # Arguments
347 ///
348 /// - `_queue`: The queue that the returned proxy is assigned to.
349 /// - `parent`:
350 /// - `positioner`:
351 #[inline]
352 pub fn get_popup(
353 &self,
354 _queue: &Queue,
355 parent: Option<&XdgSurfaceRef>,
356 positioner: &XdgPositionerRef,
357 ) -> XdgPopup {
358 let (arg1, arg2) = (parent, positioner);
359 let obj1_lock = arg1.map(|arg1| proxy::lock(arg1));
360 let obj1 = obj1_lock
361 .map(|obj1_lock| check_argument_proxy("parent", obj1_lock.wl_proxy()))
362 .unwrap_or(ptr::null_mut());
363 let obj2_lock = proxy::lock(arg2);
364 let obj2 = check_argument_proxy("positioner", obj2_lock.wl_proxy());
365 let mut args = [
366 wl_argument { n: 0 },
367 wl_argument { o: obj1 },
368 wl_argument { o: obj2 },
369 ];
370 // SAFETY: - self.proxy has the interface INTERFACE
371 // - 2 < INTERFACE.method_count = 5
372 // - the request signature is `n?oo`
373 // - OwnedProxy::WL_INTERFACE is always a valid interface
374 let data = unsafe {
375 self.proxy
376 .send_constructor(_queue, 2, &mut args, XdgPopup::WL_INTERFACE, None)
377 };
378 // SAFETY: data has the interface XdgPopup::WL_INTERFACE
379 unsafe { proxy::low_level::from_untyped_owned(data) }
380 }
381
382 /// set the new window geometry
383 ///
384 /// The window geometry of a surface is its "visible bounds" from the
385 /// user's perspective. Client-side decorations often have invisible
386 /// portions like drop-shadows which should be ignored for the
387 /// purposes of aligning, placing and constraining windows.
388 ///
389 /// The window geometry is double-buffered state, see wl_surface.commit.
390 ///
391 /// When maintaining a position, the compositor should treat the (x, y)
392 /// coordinate of the window geometry as the top left corner of the window.
393 /// A client changing the (x, y) window geometry coordinate should in
394 /// general not alter the position of the window.
395 ///
396 /// Once the window geometry of the surface is set, it is not possible to
397 /// unset it, and it will remain the same until set_window_geometry is
398 /// called again, even if a new subsurface or buffer is attached.
399 ///
400 /// If never set, the value is the full bounds of the surface,
401 /// including any subsurfaces. This updates dynamically on every
402 /// commit. This unset is meant for extremely simple clients.
403 ///
404 /// The arguments are given in the surface-local coordinate space of
405 /// the wl_surface associated with this xdg_surface, and may extend outside
406 /// of the wl_surface itself to mark parts of the subsurface tree as part of
407 /// the window geometry.
408 ///
409 /// When applied, the effective window geometry will be the set window
410 /// geometry clamped to the bounding rectangle of the combined
411 /// geometry of the surface of the xdg_surface and the associated
412 /// subsurfaces.
413 ///
414 /// The effective geometry will not be recalculated unless a new call to
415 /// set_window_geometry is done and the new pending surface state is
416 /// subsequently applied.
417 ///
418 /// The width and height of the effective window geometry must be
419 /// greater than zero. Setting an invalid size will raise an
420 /// invalid_size error.
421 ///
422 /// # Arguments
423 ///
424 /// - `x`:
425 /// - `y`:
426 /// - `width`:
427 /// - `height`:
428 #[inline]
429 pub fn set_window_geometry(&self, x: i32, y: i32, width: i32, height: i32) {
430 let (arg0, arg1, arg2, arg3) = (x, y, width, height);
431 let mut args = [
432 wl_argument { i: arg0 },
433 wl_argument { i: arg1 },
434 wl_argument { i: arg2 },
435 wl_argument { i: arg3 },
436 ];
437 // SAFETY: - self.proxy has the interface INTERFACE
438 // - 3 < INTERFACE.method_count = 5
439 // - the request signature is `iiii`
440 unsafe {
441 self.proxy.send_request(3, &mut args);
442 }
443 }
444
445 /// ack a configure event
446 ///
447 /// When a configure event is received, if a client commits the
448 /// surface in response to the configure event, then the client
449 /// must make an ack_configure request sometime before the commit
450 /// request, passing along the serial of the configure event.
451 ///
452 /// For instance, for toplevel surfaces the compositor might use this
453 /// information to move a surface to the top left only when the client has
454 /// drawn itself for the maximized or fullscreen state.
455 ///
456 /// If the client receives multiple configure events before it
457 /// can respond to one, it only has to ack the last configure event.
458 /// Acking a configure event that was never sent raises an invalid_serial
459 /// error.
460 ///
461 /// A client is not required to commit immediately after sending
462 /// an ack_configure request - it may even ack_configure several times
463 /// before its next surface commit.
464 ///
465 /// A client may send multiple ack_configure requests before committing, but
466 /// only the last request sent before a commit indicates which configure
467 /// event the client really is responding to.
468 ///
469 /// Sending an ack_configure request consumes the serial number sent with
470 /// the request, as well as serial numbers sent by all configure events
471 /// sent on this xdg_surface prior to the configure event referenced by
472 /// the committed serial.
473 ///
474 /// It is an error to issue multiple ack_configure requests referencing a
475 /// serial from the same configure event, or to issue an ack_configure
476 /// request referencing a serial from a configure event issued before the
477 /// event identified by the last ack_configure request for the same
478 /// xdg_surface. Doing so will raise an invalid_serial error.
479 ///
480 /// # Arguments
481 ///
482 /// - `serial`: the serial from the configure event
483 #[inline]
484 pub fn ack_configure(&self, serial: u32) {
485 let (arg0,) = (serial,);
486 let mut args = [wl_argument { u: arg0 }];
487 // SAFETY: - self.proxy has the interface INTERFACE
488 // - 4 < INTERFACE.method_count = 5
489 // - the request signature is `u`
490 unsafe {
491 self.proxy.send_request(4, &mut args);
492 }
493 }
494}
495
496impl XdgSurface {
497 /// Since when the configure event is available.
498 #[allow(dead_code)]
499 pub const EVT__CONFIGURE__SINCE: u32 = 1;
500}
501
502/// An event handler for [XdgSurface] proxies.
503#[allow(dead_code)]
504pub trait XdgSurfaceEventHandler {
505 type Data: 'static;
506
507 /// suggest a surface change
508 ///
509 /// The configure event marks the end of a configure sequence. A configure
510 /// sequence is a set of one or more events configuring the state of the
511 /// xdg_surface, including the final xdg_surface.configure event.
512 ///
513 /// Where applicable, xdg_surface surface roles will during a configure
514 /// sequence extend this event as a latched state sent as events before the
515 /// xdg_surface.configure event. Such events should be considered to make up
516 /// a set of atomically applied configuration states, where the
517 /// xdg_surface.configure commits the accumulated state.
518 ///
519 /// Clients should arrange their surface for the new states, and then send
520 /// an ack_configure request with the serial sent in this configure event at
521 /// some point before committing the new surface.
522 ///
523 /// If the client receives multiple configure events before it can respond
524 /// to one, it is free to discard all but the last event it received.
525 ///
526 /// # Arguments
527 ///
528 /// - `serial`: serial of the configure event
529 #[inline]
530 fn configure(&self, _data: &mut Self::Data, _slf: &XdgSurfaceRef, serial: u32) {
531 let _ = serial;
532 }
533}
534
535impl XdgSurfaceEventHandler for private::NoOpEventHandler {
536 type Data = ();
537}
538
539// SAFETY: - INTERFACE is a valid wl_interface
540// - mutable_type always returns the same value
541unsafe impl<H> EventHandler for private::EventHandler<H>
542where
543 H: XdgSurfaceEventHandler,
544{
545 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
546
547 #[inline]
548 fn mutable_type() -> Option<(TypeId, &'static str)> {
549 let id = TypeId::of::<H::Data>();
550 let name = std::any::type_name::<H::Data>();
551 Some((id, name))
552 }
553
554 #[allow(unused_variables)]
555 unsafe fn handle_event(
556 &self,
557 queue: &Queue,
558 data: *mut u8,
559 slf: &UntypedBorrowedProxy,
560 opcode: u32,
561 args: *mut wl_argument,
562 ) {
563 // SAFETY: This function requires that slf has the interface INTERFACE
564 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<XdgSurfaceRef>(slf) };
565 // SAFETY: This function requires that data is `&mut T` where `T`
566 // has the type id returned by `Self::mutable_type`, i.e.,
567 // `T = H::Data`.
568 let data: &mut H::Data = unsafe { &mut *data.cast() };
569 match opcode {
570 0 => {
571 // SAFETY: INTERFACE requires that there are 1 arguments
572 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
573 // SAFETY: - INTERFACE requires that args[0] contains a uint
574 let arg0 = unsafe { args[0].u };
575 self.0.configure(data, slf, arg0);
576 }
577 _ => {
578 invalid_opcode("xdg_surface", opcode);
579 }
580 }
581 }
582}
583
584impl<H> CreateEventHandler<H> for private::ProxyApi
585where
586 H: XdgSurfaceEventHandler,
587{
588 type EventHandler = private::EventHandler<H>;
589
590 #[inline]
591 fn create_event_handler(handler: H) -> Self::EventHandler {
592 private::EventHandler(handler)
593 }
594}
595
596impl XdgSurface {
597 /// Since when the error.not_constructed enum variant is available.
598 #[allow(dead_code)]
599 pub const ENM__ERROR_NOT_CONSTRUCTED__SINCE: u32 = 1;
600 /// Since when the error.already_constructed enum variant is available.
601 #[allow(dead_code)]
602 pub const ENM__ERROR_ALREADY_CONSTRUCTED__SINCE: u32 = 1;
603 /// Since when the error.unconfigured_buffer enum variant is available.
604 #[allow(dead_code)]
605 pub const ENM__ERROR_UNCONFIGURED_BUFFER__SINCE: u32 = 1;
606 /// Since when the error.invalid_serial enum variant is available.
607 #[allow(dead_code)]
608 pub const ENM__ERROR_INVALID_SERIAL__SINCE: u32 = 1;
609 /// Since when the error.invalid_size enum variant is available.
610 #[allow(dead_code)]
611 pub const ENM__ERROR_INVALID_SIZE__SINCE: u32 = 1;
612 /// Since when the error.defunct_role_object enum variant is available.
613 #[allow(dead_code)]
614 pub const ENM__ERROR_DEFUNCT_ROLE_OBJECT__SINCE: u32 = 1;
615}
616
617#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
618#[allow(dead_code)]
619pub struct XdgSurfaceError(pub u32);
620
621impl XdgSurfaceError {
622 /// Surface was not fully constructed
623 #[allow(dead_code)]
624 pub const NOT_CONSTRUCTED: Self = Self(1);
625
626 /// Surface was already constructed
627 #[allow(dead_code)]
628 pub const ALREADY_CONSTRUCTED: Self = Self(2);
629
630 /// Attaching a buffer to an unconfigured surface
631 #[allow(dead_code)]
632 pub const UNCONFIGURED_BUFFER: Self = Self(3);
633
634 /// Invalid serial number when acking a configure event
635 #[allow(dead_code)]
636 pub const INVALID_SERIAL: Self = Self(4);
637
638 /// Width or height was zero or negative
639 #[allow(dead_code)]
640 pub const INVALID_SIZE: Self = Self(5);
641
642 /// Surface was destroyed before its role object
643 #[allow(dead_code)]
644 pub const DEFUNCT_ROLE_OBJECT: Self = Self(6);
645}
646
647impl Debug for XdgSurfaceError {
648 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
649 let name = match *self {
650 Self::NOT_CONSTRUCTED => "NOT_CONSTRUCTED",
651 Self::ALREADY_CONSTRUCTED => "ALREADY_CONSTRUCTED",
652 Self::UNCONFIGURED_BUFFER => "UNCONFIGURED_BUFFER",
653 Self::INVALID_SERIAL => "INVALID_SERIAL",
654 Self::INVALID_SIZE => "INVALID_SIZE",
655 Self::DEFUNCT_ROLE_OBJECT => "DEFUNCT_ROLE_OBJECT",
656 _ => return Debug::fmt(&self.0, f),
657 };
658 f.write_str(name)
659 }
660}
661
662/// Functional event handlers.
663pub mod event_handlers {
664 use super::*;
665
666 /// Event handler for configure events.
667 pub struct Configure<T, F>(F, PhantomData<fn(&mut T)>);
668 impl<T, F> XdgSurfaceEventHandler for Configure<T, F>
669 where
670 T: 'static,
671 F: Fn(&mut T, &XdgSurfaceRef, u32),
672 {
673 type Data = T;
674
675 #[inline]
676 fn configure(&self, _data: &mut T, _slf: &XdgSurfaceRef, serial: u32) {
677 self.0(_data, _slf, serial)
678 }
679 }
680
681 impl XdgSurface {
682 /// Creates an event handler for configure events.
683 ///
684 /// The event handler ignores all other events.
685 #[allow(dead_code)]
686 pub fn on_configure<T, F>(f: F) -> Configure<T, F>
687 where
688 T: 'static,
689 F: Fn(&mut T, &XdgSurfaceRef, u32),
690 {
691 Configure(f, PhantomData)
692 }
693 }
694}