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`.
16use std::marker::PhantomData;
17use std::os::raw::c_void;
18use std::ptr::NonNull;
19
20use rwh_06::HandleError;
21
22use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
23use crate::monitor::MonitorHandle;
24pub use crate::window::Theme;
25use crate::window::{Window as CoreWindow, WindowAttributes};
26
27/// Additional methods on [`ActiveEventLoop`] that are specific to Wayland.
28pub trait ActiveEventLoopExtWayland {
29    /// True if the [`ActiveEventLoop`] uses Wayland.
30    fn is_wayland(&self) -> bool;
31}
32
33impl ActiveEventLoopExtWayland for dyn ActiveEventLoop + '_ {
34    #[inline]
35    fn is_wayland(&self) -> bool {
36        self.as_any().downcast_ref::<crate::platform_impl::wayland::ActiveEventLoop>().is_some()
37    }
38}
39
40/// Additional methods on [`EventLoop`] that are specific to Wayland.
41pub trait EventLoopExtWayland {
42    /// True if the [`EventLoop`] uses Wayland.
43    fn is_wayland(&self) -> bool;
44}
45
46impl EventLoopExtWayland for EventLoop {
47    #[inline]
48    fn is_wayland(&self) -> bool {
49        self.event_loop.is_wayland()
50    }
51}
52
53/// Additional methods on [`EventLoopBuilder`] that are specific to Wayland.
54pub trait EventLoopBuilderExtWayland {
55    /// Force using Wayland.
56    fn with_wayland(&mut self) -> &mut Self;
57
58    /// Whether to allow the event loop to be created off of the main thread.
59    ///
60    /// By default, the window is only allowed to be created on the main
61    /// thread, to make platform compatibility easier.
62    fn with_any_thread(&mut self, any_thread: bool) -> &mut Self;
63}
64
65impl EventLoopBuilderExtWayland for EventLoopBuilder {
66    #[inline]
67    fn with_wayland(&mut self) -> &mut Self {
68        self.platform_specific.forced_backend = Some(crate::platform_impl::Backend::Wayland);
69        self
70    }
71
72    #[inline]
73    fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
74        self.platform_specific.any_thread = any_thread;
75        self
76    }
77}
78
79pub struct XdgSurfaceHandle<'a> {
80    raw: NonNull<c_void>,
81    _marker: PhantomData<&'a ()>,
82}
83
84impl<'a> XdgSurfaceHandle<'a> {
85    /// Create a `XdgSurfaceHandle` from a [`NonNull<c_void>`]
86    pub unsafe fn borrow_raw(raw: NonNull<c_void>) -> Self {
87        Self { raw, _marker: PhantomData }
88    }
89
90    /// Get the underlying raw xdg_surface handle.
91    pub fn as_raw(&self) -> NonNull<c_void> {
92        self.raw
93    }
94}
95
96pub trait HasXdgSurfaceHandle {
97    fn xdg_surface_handle(&self) -> Result<XdgSurfaceHandle<'_>, HandleError>;
98}
99
100/// Additional methods on [`Window`] that are specific to Wayland.
101///
102/// [`Window`]: crate::window::Window
103pub trait WindowExtWayland {
104    fn xdg_surface_handle<'a>(&'a self) -> Option<&dyn HasXdgSurfaceHandle>;
105}
106
107impl WindowExtWayland for dyn CoreWindow + '_ {
108    fn xdg_surface_handle(&self) -> Option<&dyn HasXdgSurfaceHandle> {
109        let window = self.as_any().downcast_ref::<crate::platform_impl::wayland::Window>();
110        window.map(|w| w as &dyn HasXdgSurfaceHandle)
111    }
112}
113
114/// Additional methods on [`WindowAttributes`] that are specific to Wayland.
115pub trait WindowAttributesExtWayland {
116    /// Build window with the given name.
117    ///
118    /// The `general` name sets an application ID, which should match the `.desktop`
119    /// file distributed with your program. The `instance` is a `no-op`.
120    ///
121    /// For details about application ID conventions, see the
122    /// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
123    fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
124}
125
126impl WindowAttributesExtWayland for WindowAttributes {
127    #[inline]
128    fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
129        self.platform_specific.name =
130            Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
131        self
132    }
133}
134
135/// Additional methods on `MonitorHandle` that are specific to Wayland.
136pub trait MonitorHandleExtWayland {
137    /// Returns the inner identifier of the monitor.
138    fn native_id(&self) -> u32;
139}
140
141impl MonitorHandleExtWayland for MonitorHandle {
142    #[inline]
143    fn native_id(&self) -> u32 {
144        self.inner.native_identifier()
145    }
146}