async_winit/platform/
wayland.rs

1/*
2
3`async-winit` is free software: you can redistribute it and/or modify it under the terms of one of
4the following licenses:
5
6* GNU Lesser General Public License as published by the Free Software Foundation, either
7  version 3 of the License, or (at your option) any later version.
8* Mozilla Public License as published by the Mozilla Foundation, version 2.
9
10`async-winit` is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
11the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
12Public License and the Patron License for more details.
13
14You should have received a copy of the GNU Lesser General Public License and the Mozilla
15Public License along with `async-winit`. If not, see <https://www.gnu.org/licenses/>.
16
17*/
18
19// This file is partially derived from `winit`, which was originally created by Pierre Krieger and
20// contributers. It was originally released under the MIT license.
21
22//! Platform-specific features for Wayland.
23
24use super::__private as sealed;
25use crate::event_loop::{EventLoopBuilder, EventLoopWindowTarget};
26use crate::sync::ThreadSafety;
27use crate::window::{Window, WindowBuilder};
28
29use std::os::raw;
30
31use winit::platform::wayland::{
32    EventLoopBuilderExtWayland as _, WindowBuilderExtWayland as _, WindowExtWayland as _,
33};
34
35#[doc(inline)]
36pub use winit::platform::wayland::MonitorHandleExtWayland;
37
38/// Additional methods on [`EventLoopWindowTarget`] that are specific to Wayland.
39///
40/// [`EventLoopWindowTarget`]: crate::event_loop::EventLoopWindowTarget
41pub trait EventLoopWindowTargetExtWayland: sealed::EventLoopWindowTargetPrivate {
42    /// True if the [`EventLoopWindowTarget`] uses Wayland.
43    fn is_wayland(&self) -> bool;
44
45    /// Returns a pointer to the `wl_display` object of wayland that is used by this
46    /// [`EventLoopWindowTarget`].
47    ///
48    /// Returns `None` if the [`EventLoop`] doesn't use wayland (if it uses xlib for example).
49    ///
50    /// The pointer will become invalid when the winit [`EventLoop`] is destroyed.
51    ///
52    /// [`EventLoop`]: crate::event_loop::EventLoop
53    fn wayland_display(&self) -> Option<*mut raw::c_void>;
54}
55
56impl<TS: ThreadSafety> EventLoopWindowTargetExtWayland for EventLoopWindowTarget<TS> {
57    #[inline]
58    fn is_wayland(&self) -> bool {
59        self.is_wayland
60    }
61
62    #[inline]
63    fn wayland_display(&self) -> Option<*mut raw::c_void> {
64        todo!()
65    }
66}
67
68/// Additional methods on [`EventLoopBuilder`] that are specific to Wayland.
69///
70/// [`EventLoopBuilder`]: crate::event_loop::EventLoopBuilder
71pub trait EventLoopBuilderExtWayland: sealed::EventLoopBuilderPrivate {
72    /// Force using Wayland.
73    fn with_wayland(&mut self) -> &mut Self;
74
75    /// Whether to allow the event loop to be created off of the main thread.
76    ///
77    /// By default, the window is only allowed to be created on the main
78    /// thread, to make platform compatibility easier.
79    fn with_any_thread(&mut self, any_thread: bool) -> &mut Self;
80}
81
82impl EventLoopBuilderExtWayland for EventLoopBuilder {
83    fn with_wayland(&mut self) -> &mut Self {
84        self.inner.with_wayland();
85        self
86    }
87
88    fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
89        self.inner.with_any_thread(any_thread);
90        self
91    }
92}
93
94/// Additional methods on [`Window`] that are specific to Wayland.
95///
96/// [`Window`]: crate::window::Window
97pub trait WindowExtWayland: sealed::WindowPrivate {
98    /// Returns a pointer to the `wl_surface` object of wayland that is used by this window.
99    ///
100    /// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
101    ///
102    /// The pointer will become invalid when the [`Window`] is destroyed.
103    fn wayland_surface(&self) -> Option<*mut raw::c_void>;
104
105    /// Returns a pointer to the `wl_display` object of wayland that is used by this window.
106    ///
107    /// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
108    ///
109    /// The pointer will become invalid when the [`Window`] is destroyed.
110    fn wayland_display(&self) -> Option<*mut raw::c_void>;
111}
112
113impl<TS: ThreadSafety> WindowExtWayland for Window<TS> {
114    #[inline]
115    fn wayland_surface(&self) -> Option<*mut raw::c_void> {
116        self.window().wayland_surface()
117    }
118
119    #[inline]
120    fn wayland_display(&self) -> Option<*mut raw::c_void> {
121        self.window().wayland_display()
122    }
123}
124
125/// Additional methods on [`WindowBuilder`] that are specific to Wayland.
126///
127/// [`WindowBuilder`]: crate::window::WindowBuilder
128pub trait WindowBuilderExtWayland: sealed::WindowBuilderPrivate {
129    /// Build window with the given name.
130    ///
131    /// The `general` name sets an application ID, which should match the `.desktop`
132    /// file destributed with your program. The `instance` is a `no-op`.
133    ///
134    /// For details about application ID conventions, see the
135    /// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
136    fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
137}
138
139impl WindowBuilderExtWayland for WindowBuilder {
140    #[inline]
141    fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
142        self.platform
143            .set_x11_name((general.into(), instance.into()));
144        self
145    }
146}
147
148#[derive(Default)]
149pub(crate) struct PlatformSpecific {
150    pub name: Option<(String, String)>,
151}
152
153impl PlatformSpecific {
154    pub fn set_x11_name(&mut self, x11_name: (String, String)) {
155        self.name = Some(x11_name);
156    }
157
158    pub fn apply_to(
159        self,
160        window_builder: winit::window::WindowBuilder,
161    ) -> winit::window::WindowBuilder {
162        let mut window_builder = window_builder;
163
164        if let Some((general, instance)) = self.name {
165            window_builder = window_builder.with_name(general, instance);
166        }
167
168        window_builder
169    }
170}