smithay_client_toolkit/
globals.rs

1use crate::error::GlobalError;
2use wayland_client::Proxy;
3
4/// A trait implemented by types that provide access to capability globals.
5///
6/// The returned global must be fully compatible with the provided `API_COMPAT_VERSION` generic
7/// argument.  For example:
8///
9/// - A global that binds to `wl_compositor` with maximum version 4 could implement
10/// `ProvidesBoundGlobal<WlCompositor, 4>`, `ProvidesBoundGlobal<WlCompositor, 3>`,
11/// `ProvidesBoundGlobal<WlCompositor, 2>`, and `ProvidesBoundGlobal<WlCompositor, 1>` because
12/// versions 2-4 only add additional requests to the `wl_surface` API.
13/// - A global that binds to `wl_compositor` with maximum version 5 may only implement
14/// `ProvidesBoundGlobal<WlCompositor, 5>` because version 5 makes using `wl_surface::attach` with
15/// a nonzero offset a protocol error.  A caller who is only aware of the version 4 API risks
16/// causing these protocol errors if it uses surfaces created by such a global.
17///
18/// Changes that cause compatibility breaks include:
19///
20/// - Adding a new event to the global or to any object created by the global.
21/// - Adding a new requirement to an existing request.
22///
23/// The resulting global may have a version lower than `API_COMPAT_VERSION` if, at runtime, the
24/// compositor does not support the new version.  Clients should either be prepared to handle
25/// earlier versions of the protocol or use [`ProvidesBoundGlobal::with_min_version`] to produce an
26/// error in this case.
27///
28/// It is permitted to implement `ProvidesBoundGlobal` for versions that are higher than the
29/// maximum version you bind.  When rustc gains the ability to constrain const parameters with
30/// integer bounds (`where API_COMPAT_VERSION >= 5`), implementations of this trait should be
31/// provided by specifying a lower bound for the compat version in order to avoid requiring version
32/// updates be done in lock-step.
33pub trait ProvidesBoundGlobal<I: Proxy, const API_COMPAT_VERSION: u32> {
34    fn bound_global(&self) -> Result<I, GlobalError>;
35    fn with_min_version(&self, version: u32) -> Result<I, GlobalError> {
36        let proxy = self.bound_global()?;
37        if proxy.version() < version {
38            Err(GlobalError::InvalidVersion {
39                name: I::interface().name,
40                required: version,
41                available: proxy.version(),
42            })
43        } else {
44            Ok(proxy)
45        }
46    }
47}
48
49/// A struct used as the UserData field for globals bound by SCTK.
50///
51/// This is used instead of `()` to allow multiple `Dispatch` impls on the same object.
52#[derive(Debug)]
53pub struct GlobalData;