From 31a0924825aaaa1470539ed0a24a8db4272374bf Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 26 Jan 2022 17:39:27 +0100 Subject: [PATCH] WIP: Provide an implementation for the HasRawWindowHandle trait in Rust for sixtyfps::Window RWH is the de-facto standard crate in Rust to express window handles (and associated windowing system connections). This should be safe to use in the public API. This patch implements RWH for the GL backend. cc #877 --- sixtyfps_runtime/corelib/Cargo.toml | 2 +- sixtyfps_runtime/corelib/window.rs | 9 ++++++++- sixtyfps_runtime/rendering_backends/gl/Cargo.toml | 1 + sixtyfps_runtime/rendering_backends/gl/glwindow.rs | 10 ++++++++++ sixtyfps_runtime/rendering_backends/qt/Cargo.toml | 1 + sixtyfps_runtime/rendering_backends/qt/qt_window.rs | 6 ++++++ sixtyfps_runtime/rendering_backends/testing/Cargo.toml | 1 + sixtyfps_runtime/rendering_backends/testing/lib.rs | 6 ++++++ 8 files changed, 34 insertions(+), 2 deletions(-) diff --git a/sixtyfps_runtime/corelib/Cargo.toml b/sixtyfps_runtime/corelib/Cargo.toml index fcdafe76b4c..af13308108d 100644 --- a/sixtyfps_runtime/corelib/Cargo.toml +++ b/sixtyfps_runtime/corelib/Cargo.toml @@ -60,7 +60,7 @@ pin-project = "1" atomic-polyfill = { version = "0.1.5" } num-traits = { version = "0.2", default-features = false } sixtyfps-common = { version = "=0.2.0", path = "../common" } - +raw-window-handle = { version = "0.4.2" } defmt = { version = "0.3.0", optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/sixtyfps_runtime/corelib/window.rs b/sixtyfps_runtime/corelib/window.rs index 5a8cfa5ed07..67b31d884cc 100644 --- a/sixtyfps_runtime/corelib/window.rs +++ b/sixtyfps_runtime/corelib/window.rs @@ -17,7 +17,7 @@ use core::pin::Pin; /// This trait represents the interface that the generated code and the run-time /// require in order to implement functionality such as device-independent pixels, /// window resizing and other typically windowing system related tasks. -pub trait PlatformWindow { +pub trait PlatformWindow: raw_window_handle::HasRawWindowHandle { /// Registers the window with the windowing system. fn show(self: Rc); /// De-registers the window from the windowing system. @@ -591,6 +591,13 @@ pub mod api { self.0.hide(); } } + + unsafe impl raw_window_handle::HasRawWindowHandle for Window { + #![allow(unsafe_code)] + fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { + self.0.raw_window_handle() + } + } } impl WindowHandleAccess for api::Window { diff --git a/sixtyfps_runtime/rendering_backends/gl/Cargo.toml b/sixtyfps_runtime/rendering_backends/gl/Cargo.toml index 935df35a92d..1de34e7c0c3 100644 --- a/sixtyfps_runtime/rendering_backends/gl/Cargo.toml +++ b/sixtyfps_runtime/rendering_backends/gl/Cargo.toml @@ -50,6 +50,7 @@ ttf-parser = "0.14.0" unicode-script = "0.5.3" cfg-if = "1" winit = { version = "0.26", default-features = false } +raw-window-handle = { version = "0.4.2" } [target.'cfg(target_arch = "wasm32")'.dependencies] web_sys = { version = "0.3", package = "web-sys", features=["console", "WebGlContextAttributes"] } diff --git a/sixtyfps_runtime/rendering_backends/gl/glwindow.rs b/sixtyfps_runtime/rendering_backends/gl/glwindow.rs index 4df10366c45..82fc5a2511d 100644 --- a/sixtyfps_runtime/rendering_backends/gl/glwindow.rs +++ b/sixtyfps_runtime/rendering_backends/gl/glwindow.rs @@ -621,6 +621,16 @@ impl PlatformWindow for GLWindow { } } +unsafe impl raw_window_handle::HasRawWindowHandle for GLWindow { + fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { + if let Some(mapped_window) = self.borrow_mapped_window() { + mapped_window.opengl_context.window().raw_window_handle() + } else { + raw_window_handle::RawWindowHandle::Xcb(raw_window_handle::XcbHandle::empty()) + } + } +} + struct MappedWindow { canvas: Option, opengl_context: crate::OpenGLContext, diff --git a/sixtyfps_runtime/rendering_backends/qt/Cargo.toml b/sixtyfps_runtime/rendering_backends/qt/Cargo.toml index ea2ce9b7c37..286f1db406b 100644 --- a/sixtyfps_runtime/rendering_backends/qt/Cargo.toml +++ b/sixtyfps_runtime/rendering_backends/qt/Cargo.toml @@ -30,6 +30,7 @@ euclid = "0.22.1" pin-weak = "1" once_cell = "1" lyon_path = "0.17" +raw-window-handle = { version = "0.4.2" } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] qttypes = { version = "0.2.5", default-features = false } diff --git a/sixtyfps_runtime/rendering_backends/qt/qt_window.rs b/sixtyfps_runtime/rendering_backends/qt/qt_window.rs index b32ff26816a..2e8f0d667cf 100644 --- a/sixtyfps_runtime/rendering_backends/qt/qt_window.rs +++ b/sixtyfps_runtime/rendering_backends/qt/qt_window.rs @@ -1512,6 +1512,12 @@ impl PlatformWindow for QtWindow { } } +unsafe impl raw_window_handle::HasRawWindowHandle for QtWindow { + fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { + unimplemented!() + } +} + fn get_font(request: FontRequest) -> QFont { let family: qttypes::QString = request.family.unwrap_or_default().as_str().into(); let pixel_size: f32 = request.pixel_size.unwrap_or(0.); diff --git a/sixtyfps_runtime/rendering_backends/testing/Cargo.toml b/sixtyfps_runtime/rendering_backends/testing/Cargo.toml index 60dcae47d37..44437ac3154 100644 --- a/sixtyfps_runtime/rendering_backends/testing/Cargo.toml +++ b/sixtyfps_runtime/rendering_backends/testing/Cargo.toml @@ -18,3 +18,4 @@ path = "lib.rs" [dependencies] sixtyfps-corelib = { version = "=0.2.0", path = "../../corelib" } image = { version = "0.23.14", default-features = false, features = ["png"] } +raw-window-handle = { version = "0.4.2" } \ No newline at end of file diff --git a/sixtyfps_runtime/rendering_backends/testing/lib.rs b/sixtyfps_runtime/rendering_backends/testing/lib.rs index 27cdd29dae8..c656be47913 100644 --- a/sixtyfps_runtime/rendering_backends/testing/lib.rs +++ b/sixtyfps_runtime/rendering_backends/testing/lib.rs @@ -157,6 +157,12 @@ impl PlatformWindow for TestingWindow { } } +unsafe impl raw_window_handle::HasRawWindowHandle for TestingWindow { + fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { + unimplemented!() + } +} + /// Initialize the testing backend. /// Must be called before any call that would otherwise initialize the rendering backend. /// Calling it when the rendering backend is already initialized will have no effects