gpui: Implement window_handle and display_handle for wayland platform (#28152)

Christian Bergschneider created

This PR implements the previously unimplemented window_handle and
display_handle methods in the wayland platform. It also exposes the
display_handle method through the Window struct.

Release Notes:

- N/A

Change summary

Cargo.lock                                       |  1 
crates/gpui/Cargo.toml                           |  1 
crates/gpui/src/platform/linux/wayland/window.rs | 20 ++++++++++++++++-
crates/gpui/src/window.rs                        | 10 ++++++++
4 files changed, 29 insertions(+), 3 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -7070,6 +7070,7 @@ dependencies = [
  "image",
  "inventory",
  "itertools 0.14.0",
+ "libc",
  "log",
  "lyon",
  "media",

crates/gpui/Cargo.toml 🔗

@@ -126,6 +126,7 @@ uuid.workspace = true
 waker-fn = "1.2.0"
 lyon = "1.0"
 workspace-hack.workspace = true
+libc.workspace = true
 
 [target.'cfg(target_os = "macos")'.dependencies]
 block = "0.1"

crates/gpui/src/platform/linux/wayland/window.rs 🔗

@@ -751,12 +751,28 @@ where
 
 impl rwh::HasWindowHandle for WaylandWindow {
     fn window_handle(&self) -> Result<rwh::WindowHandle<'_>, rwh::HandleError> {
-        unimplemented!()
+        let surface = self.0.surface().id().as_ptr() as *mut libc::c_void;
+        let c_ptr = NonNull::new(surface).ok_or(rwh::HandleError::Unavailable)?;
+        let handle = rwh::WaylandWindowHandle::new(c_ptr);
+        let raw_handle = rwh::RawWindowHandle::Wayland(handle);
+        Ok(unsafe { rwh::WindowHandle::borrow_raw(raw_handle) })
     }
 }
+
 impl rwh::HasDisplayHandle for WaylandWindow {
     fn display_handle(&self) -> Result<rwh::DisplayHandle<'_>, rwh::HandleError> {
-        unimplemented!()
+        let display = self
+            .0
+            .surface()
+            .backend()
+            .upgrade()
+            .ok_or(rwh::HandleError::Unavailable)?
+            .display_ptr() as *mut libc::c_void;
+
+        let c_ptr = NonNull::new(display).ok_or(rwh::HandleError::Unavailable)?;
+        let handle = rwh::WaylandDisplayHandle::new(c_ptr);
+        let raw_handle = rwh::RawDisplayHandle::Wayland(handle);
+        Ok(unsafe { rwh::DisplayHandle::borrow_raw(raw_handle) })
     }
 }
 

crates/gpui/src/window.rs 🔗

@@ -25,7 +25,7 @@ use derive_more::{Deref, DerefMut};
 use futures::FutureExt;
 use futures::channel::oneshot;
 use parking_lot::RwLock;
-use raw_window_handle::{HandleError, HasWindowHandle};
+use raw_window_handle::{HandleError, HasDisplayHandle, HasWindowHandle};
 use refineable::Refineable;
 use slotmap::SlotMap;
 use smallvec::SmallVec;
@@ -4428,6 +4428,14 @@ impl HasWindowHandle for Window {
     }
 }
 
+impl HasDisplayHandle for Window {
+    fn display_handle(
+        &self,
+    ) -> std::result::Result<raw_window_handle::DisplayHandle<'_>, HandleError> {
+        self.platform_window.display_handle()
+    }
+}
+
 /// An identifier for an [`Element`](crate::Element).
 ///
 /// Can be constructed with a string, a number, or both, as well