diff --git a/winit-wayland/src/lib.rs b/winit-wayland/src/lib.rs index b34dedad..0c89e972 100644 --- a/winit-wayland/src/lib.rs +++ b/winit-wayland/src/lib.rs @@ -14,10 +14,13 @@ //! * `wayland-csd-adwaita-crossfont`. //! * `wayland-csd-adwaita-notitle`. //! * `wayland-csd-adwaita-notitlebar`. +use std::any::Any; use std::ffi::c_void; +use std::marker::PhantomData; use std::ptr::NonNull; use dpi::{LogicalSize, PhysicalSize}; +use rwh_06::HandleError; use sctk::reexports::client::Proxy; use sctk::reexports::client::protocol::wl_surface::WlSurface; use sctk::shm::slot::{Buffer, CreateBufferError, SlotPool}; @@ -72,12 +75,35 @@ pub trait EventLoopBuilderExtWayland { fn with_any_thread(&mut self, any_thread: bool) -> &mut Self; } +pub struct XdgSurfaceHandle<'a> { + raw: NonNull, + _marker: PhantomData<&'a ()>, +} + +impl<'a> XdgSurfaceHandle<'a> { + /// Create a `XdgSurfaceHandle` from a [`NonNull`] + pub unsafe fn borrow_raw(raw: NonNull) -> Self { + Self { raw, _marker: PhantomData } + } + + /// Get the underlying raw xdg_surface handle. + pub fn as_raw(&self) -> NonNull { + self.raw + } +} + +pub trait HasXdgSurfaceHandle { + fn xdg_surface_handle(&self) -> Result, HandleError>; +} + /// Additional methods on [`Window`] that are specific to Wayland. /// /// [`Window`]: crate::window::Window pub trait WindowExtWayland { /// Returns `xdg_toplevel` of the window or [`None`] if the window is X11 window. fn xdg_toplevel(&self) -> Option>; + + fn xdg_surface_handle<'a>(&'a self) -> Option<&dyn HasXdgSurfaceHandle>; } impl WindowExtWayland for dyn CoreWindow + '_ { @@ -85,6 +111,12 @@ impl WindowExtWayland for dyn CoreWindow + '_ { fn xdg_toplevel(&self) -> Option> { self.cast_ref::()?.xdg_toplevel() } + + #[inline] + + fn xdg_surface_handle(&self) -> Option<&dyn HasXdgSurfaceHandle> { + Some(self.cast_ref::()? as &dyn HasXdgSurfaceHandle) + } } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/winit-wayland/src/window/mod.rs b/winit-wayland/src/window/mod.rs index 37021bb0..44d93011 100644 --- a/winit-wayland/src/window/mod.rs +++ b/winit-wayland/src/window/mod.rs @@ -12,6 +12,7 @@ use sctk::reexports::client::protocol::wl_surface::WlSurface; use sctk::reexports::client::{Proxy, QueueHandle}; use sctk::reexports::protocols::xdg::activation::v1::client::xdg_activation_v1::XdgActivationV1; use sctk::shell::WaylandSurface; +use sctk::shell::xdg::XdgSurface; use sctk::shell::xdg::window::{Window as SctkWindow, WindowDecorations}; use tracing::warn; use winit_core::cursor::Cursor; @@ -30,7 +31,7 @@ use super::event_loop::sink::EventSink; use super::output::MonitorHandle; use super::state::WinitState; use super::types::xdg_activation::XdgActivationTokenData; -use crate::{WindowAttributesWayland, output}; +use crate::{HasXdgSurfaceHandle, WindowAttributesWayland, XdgSurfaceHandle, output}; pub(crate) mod state; @@ -655,6 +656,17 @@ impl CoreWindow for Window { } } +impl HasXdgSurfaceHandle for Window { + fn xdg_surface_handle(&self) -> Result, rwh_06::HandleError> { + let raw = { + let ptr = self.window.xdg_surface().id().as_ptr(); + std::ptr::NonNull::new(ptr as *mut _).expect("wl_surface will never be null") + }; + + unsafe { Ok(XdgSurfaceHandle::borrow_raw(raw)) } + } +} + /// The request from the window to the event loop. #[derive(Debug)] pub struct WindowRequests {