From a54eaaeceeea9ef3874de4e699d9523fb9482293 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Tue, 30 Jan 2024 11:42:28 -0800 Subject: [PATCH] Add raw window handle implementations to GPUI (#7101) This is in preparation for experiments with wgpu. This should have no external effect. Release Notes: - N/A --- Cargo.lock | 9 +++++++- crates/gpui/Cargo.toml | 1 + crates/gpui/src/platform.rs | 9 ++++---- crates/gpui/src/platform/mac/window.rs | 30 ++++++++++++++++++++++++- crates/gpui/src/platform/test/window.rs | 17 ++++++++++++++ 5 files changed, 60 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3921a00b1d3d726d4d0a4e5cc6daa30749e39b2..a9c91d04d4c4f1ff89172538320ffb240b4e06af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3129,6 +3129,7 @@ dependencies = [ "png", "postage", "rand 0.8.5", + "raw-window-handle 0.6.0", "refineable", "resvg", "schemars", @@ -4495,7 +4496,7 @@ dependencies = [ "jni-sys", "ndk-sys", "num_enum", - "raw-window-handle", + "raw-window-handle 0.5.2", "thiserror", ] @@ -5953,6 +5954,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +[[package]] +name = "raw-window-handle" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" + [[package]] name = "rawpointer" version = "0.2.1" diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 76d0cdb43d8d87e8cc2e8593e0f1d65e749990a1..66acb0c1e60f938290f0b6d5e8e8b30a155c2326 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -58,6 +58,7 @@ slotmap = "1.0.6" schemars.workspace = true bitflags = "2.4.0" anyhow.workspace = true +raw-window-handle = "0.6.0" [dev-dependencies] backtrace = "0.3" diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 92dd08f0598c3bd2a9683a1ba39e30a50d0139dc..67c3a70ccb9c9c55d258fa2c1871d37dc2b37f5b 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -8,13 +8,14 @@ mod test; use crate::{ Action, AnyWindowHandle, AsyncWindowContext, BackgroundExecutor, Bounds, DevicePixels, Font, FontId, FontMetrics, FontRun, ForegroundExecutor, GlobalPixels, GlyphId, Keymap, LineLayout, - Pixels, PlatformInput, Point, RenderGlyphParams, RenderImageParams, RenderSvgParams, Result, - Scene, SharedString, Size, Task, TaskLabel, WindowContext, + Pixels, PlatformInput, Point, RenderGlyphParams, RenderImageParams, RenderSvgParams, Scene, + SharedString, Size, Task, TaskLabel, WindowContext, }; -use anyhow::anyhow; +use anyhow::{anyhow, Result}; use async_task::Runnable; use futures::channel::oneshot; use parking::Unparker; +use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; use seahash::SeaHasher; use serde::{Deserialize, Serialize}; use std::borrow::Cow; @@ -138,7 +139,7 @@ impl Debug for DisplayId { unsafe impl Send for DisplayId {} -pub(crate) trait PlatformWindow { +pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle { fn bounds(&self) -> WindowBounds; fn content_size(&self) -> Size; fn scale_factor(&self) -> f32; diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index a244286c2d3a96b46fe3b711dd4f9753d7823eb5..ce25c4d6eb57e3709243763c5a360cd2ea2c1c7e 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -32,6 +32,10 @@ use objc::{ sel, sel_impl, }; use parking_lot::Mutex; +use raw_window_handle::{ + AppKitDisplayHandle, AppKitWindowHandle, DisplayHandle, HasDisplayHandle, HasWindowHandle, + RawWindowHandle, WindowHandle, +}; use smallvec::SmallVec; use std::{ any::Any, @@ -41,7 +45,7 @@ use std::{ ops::Range, os::raw::c_char, path::PathBuf, - ptr, + ptr::{self, NonNull}, rc::Rc, sync::{Arc, Weak}, time::Duration, @@ -316,6 +320,7 @@ struct MacWindowState { handle: AnyWindowHandle, executor: ForegroundExecutor, native_window: id, + native_view: NonNull, renderer: MetalRenderer, kind: WindowKind, request_frame_callback: Option>, @@ -523,6 +528,7 @@ impl MacWindow { handle, executor, native_window, + native_view: NonNull::new_unchecked(native_view as *mut _), renderer: MetalRenderer::new(true), kind: options.kind, request_frame_callback: None, @@ -1011,6 +1017,28 @@ impl PlatformWindow for MacWindow { } } +impl HasWindowHandle for MacWindow { + fn window_handle( + &self, + ) -> Result, raw_window_handle::HandleError> { + // SAFETY: The AppKitWindowHandle is a wrapper around a pointer to an NSView + unsafe { + Ok(WindowHandle::borrow_raw(RawWindowHandle::AppKit( + AppKitWindowHandle::new(self.0.lock().native_view.cast()), + ))) + } + } +} + +impl HasDisplayHandle for MacWindow { + fn display_handle( + &self, + ) -> Result, raw_window_handle::HandleError> { + // SAFETY: This is a no-op on macOS + unsafe { Ok(DisplayHandle::borrow_raw(AppKitDisplayHandle::new().into())) } + } +} + fn get_scale_factor(native_window: id) -> f32 { let factor = unsafe { let screen: id = msg_send![native_window, screen]; diff --git a/crates/gpui/src/platform/test/window.rs b/crates/gpui/src/platform/test/window.rs index af58707c6d444d3b321ccc6385fbdca1f89ff42f..b310084fc490de79b41d8b4284b46332a1b12b8e 100644 --- a/crates/gpui/src/platform/test/window.rs +++ b/crates/gpui/src/platform/test/window.rs @@ -5,6 +5,7 @@ use crate::{ }; use collections::HashMap; use parking_lot::Mutex; +use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; use std::{ rc::{Rc, Weak}, sync::{self, Arc}, @@ -29,6 +30,22 @@ pub(crate) struct TestWindowState { #[derive(Clone)] pub(crate) struct TestWindow(pub(crate) Arc>); +impl HasWindowHandle for TestWindow { + fn window_handle( + &self, + ) -> Result, raw_window_handle::HandleError> { + unimplemented!("Test Windows are not backed by a real platform window") + } +} + +impl HasDisplayHandle for TestWindow { + fn display_handle( + &self, + ) -> Result, raw_window_handle::HandleError> { + unimplemented!("Test Windows are not backed by a real platform window") + } +} + impl TestWindow { pub fn new( options: WindowOptions,