winit/platform/
wayland.rs

1//! # Wayland
2//!
3//! **Note:** Windows don't appear on Wayland until you draw/present to them.
4//!
5//! By default, Winit loads system libraries using `dlopen`. This can be
6//! disabled by disabling the `"wayland-dlopen"` cargo feature.
7//!
8//! ## Client-side decorations
9//!
10//! Winit provides client-side decorations by default, but the behaviour can
11//! be controlled with the following feature flags:
12//!
13//! * `wayland-csd-adwaita` (default).
14//! * `wayland-csd-adwaita-crossfont`.
15//! * `wayland-csd-adwaita-notitle`.
16
17use std::ffi::c_void;
18use std::ptr::NonNull;
19
20use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
21use crate::monitor::MonitorHandle;
22use crate::window::{Window, WindowAttributes};
23
24pub use crate::window::Theme;
25
26/// Additional methods on [`ActiveEventLoop`] that are specific to Wayland.
27pub trait ActiveEventLoopExtWayland {
28    /// True if the [`ActiveEventLoop`] uses Wayland.
29    fn is_wayland(&self) -> bool;
30}
31
32impl ActiveEventLoopExtWayland for ActiveEventLoop {
33    #[inline]
34    fn is_wayland(&self) -> bool {
35        self.p.is_wayland()
36    }
37}
38
39/// Additional methods on [`EventLoop`] that are specific to Wayland.
40pub trait EventLoopExtWayland {
41    /// True if the [`EventLoop`] uses Wayland.
42    fn is_wayland(&self) -> bool;
43}
44
45impl<T: 'static> EventLoopExtWayland for EventLoop<T> {
46    #[inline]
47    fn is_wayland(&self) -> bool {
48        self.event_loop.is_wayland()
49    }
50}
51
52/// Additional methods on [`EventLoopBuilder`] that are specific to Wayland.
53pub trait EventLoopBuilderExtWayland {
54    /// Force using Wayland.
55    fn with_wayland(&mut self) -> &mut Self;
56
57    /// Whether to allow the event loop to be created off of the main thread.
58    ///
59    /// By default, the window is only allowed to be created on the main
60    /// thread, to make platform compatibility easier.
61    fn with_any_thread(&mut self, any_thread: bool) -> &mut Self;
62}
63
64impl<T> EventLoopBuilderExtWayland for EventLoopBuilder<T> {
65    #[inline]
66    fn with_wayland(&mut self) -> &mut Self {
67        self.platform_specific.forced_backend = Some(crate::platform_impl::Backend::Wayland);
68        self
69    }
70
71    #[inline]
72    fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
73        self.platform_specific.any_thread = any_thread;
74        self
75    }
76}
77
78/// Additional methods on [`Window`] that are specific to Wayland.
79///
80/// [`Window`]: crate::window::Window
81pub trait WindowExtWayland {
82    /// Returns `xdg_toplevel` of the window or [`None`] if the window is X11 window.
83    fn xdg_toplevel(&self) -> Option<NonNull<c_void>>;
84}
85
86impl WindowExtWayland for Window {
87    #[inline]
88    fn xdg_toplevel(&self) -> Option<NonNull<c_void>> {
89        #[allow(clippy::single_match)]
90        match &self.window {
91            #[cfg(x11_platform)]
92            crate::platform_impl::Window::X(_) => None,
93            #[cfg(wayland_platform)]
94            crate::platform_impl::Window::Wayland(window) => window.xdg_toplevel(),
95        }
96    }
97}
98
99/// Additional methods on [`WindowAttributes`] that are specific to Wayland.
100pub trait WindowAttributesExtWayland {
101    /// Build window with the given name.
102    ///
103    /// The `general` name sets an application ID, which should match the `.desktop`
104    /// file distributed with your program. The `instance` is a `no-op`.
105    ///
106    /// For details about application ID conventions, see the
107    /// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
108    fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
109}
110
111impl WindowAttributesExtWayland for WindowAttributes {
112    #[inline]
113    fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
114        self.platform_specific.name =
115            Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
116        self
117    }
118}
119
120/// Additional methods on `MonitorHandle` that are specific to Wayland.
121pub trait MonitorHandleExtWayland {
122    /// Returns the inner identifier of the monitor.
123    fn native_id(&self) -> u32;
124}
125
126impl MonitorHandleExtWayland for MonitorHandle {
127    #[inline]
128    fn native_id(&self) -> u32 {
129        self.inner.native_identifier()
130    }
131}