Repository: PistonDevelopers/glfw-rs (language: rust)

Issue:
raw-window-handle needs to be updated
raw-window-handle has been updated to 0.6.0. Right now glfw-rs can't be used with wgpu because it still depends on version 0.5.2.


Discussion / hints:

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 4ef97824..c67ae462 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,9 @@ rust-version = "1.56"
 
 [dependencies]
 bitflags = "1.0.0"
-raw-window-handle = "0.5.0"
+# would like one to enable when raw-window-handle-v0-6 is not enabled, but have not figured out how
+raw-window-handle-0-5 = { package = "raw-window-handle", version = "0.5.0"}
+raw-window-handle-0-6 = { package = "raw-window-handle", version = "0.6.0", optional = true }
 
 [target.'cfg(target_os = "macos")'.dependencies]
 objc = "0.2"
@@ -40,7 +42,8 @@ version = "0.37.2"
 log = "0.4"
 
 [features]
-all = ["image", "vulkan", "log", "wayland"]
-default = ["glfw-sys"]
+all = ["image", "vulkan", "log", "wayland", "raw-window-handle-v0-6"]
+default = ["glfw-sys", "raw-window-handle-v0-6"]
 vulkan = ["ash"]
 wayland = ["glfw-sys/wayland"]
+raw-window-handle-v0-6 = ["dep:raw-window-handle-0-6"]
diff --git a/examples/raw_window_handle.rs b/examples/raw_window_handle.rs
index 0067c6c3..f95944b4 100644
--- a/examples/raw_window_handle.rs
+++ b/examples/raw_window_handle.rs
@@ -14,9 +14,16 @@
 // limitations under the License.
 
 extern crate glfw;
-extern crate raw_window_handle;
+#[cfg(feature = "raw-window-handle-v0-6")]
+extern crate raw_window_handle_0_6 as raw_window_handle;
+
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
+extern crate raw_window_handle_0_5 as raw_window_handle;
 
 use glfw::{Action, Context, Key};
+#[cfg(feature = "raw-window-handle-v0-6")]
+use raw_window_handle::{HasWindowHandle, RawWindowHandle};
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
 use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
 
 fn main() {
@@ -28,8 +35,12 @@ fn main() {
 
     window.set_key_polling(true);
     window.make_current();
+    #[cfg(feature = "raw-window-handle-v0-6")]
+    let raw = window.window_handle().unwrap().as_raw();
+    #[cfg(not(feature = "raw-window-handle-v0-6"))]
+    let raw = window.raw_window_handle();
 
-    match window.raw_window_handle() {
+    match raw {
         RawWindowHandle::Win32(handle) => println!("raw handle: {:?}", handle),
         RawWindowHandle::Xlib(handle) => println!("raw handle: {:?}", handle),
         RawWindowHandle::Wayland(handle) => println!("raw handle: {:?}", handle),
diff --git a/examples/render_task.rs b/examples/render_task.rs
index 07cec42b..1f38919a 100644
--- a/examples/render_task.rs
+++ b/examples/render_task.rs
@@ -53,7 +53,7 @@ fn main() {
     let _ = render_task_done;
 }
 
-fn render(mut context: glfw::RenderContext, finish: Receiver<()>) {
+fn render(mut context: glfw::PRenderContext, finish: Receiver<()>) {
     context.make_current();
     loop {
         // Check if the rendering should stop.
diff --git a/src/lib.rs b/src/lib.rs
index 08f884db..3c2c6f87 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -229,12 +229,24 @@ extern crate log;
 extern crate bitflags;
 #[cfg(feature = "image")]
 extern crate image;
-#[cfg(all(target_os = "macos"))]
+#[cfg(target_os = "macos")]
 #[macro_use]
 extern crate objc;
 
+#[cfg(feature = "raw-window-handle-v0-6")]
+extern crate raw_window_handle_0_6 as raw_window_handle;
+
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
+extern crate raw_window_handle_0_5 as raw_window_handle;
+
 use std::collections::VecDeque;
-use raw_window_handle::{HasRawWindowHandle, RawWindowHandle, HasRawDisplayHandle, RawDisplayHandle};
+
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
+use raw_window_handle::{HasRawWindowHandle, HasRawDisplayHandle};
+
+#[cfg(feature = "raw-window-handle-v0-6")]
+use raw_window_handle::{HasDisplayHandle, HasWindowHandle, WindowHandle, HandleError, DisplayHandle};
+use raw_window_handle::{RawWindowHandle, RawDisplayHandle};
 
 use std::error;
 use std::ffi::{CStr, CString};
@@ -295,6 +307,25 @@ impl DerefMut for PWindow {
     }
 }
 
+unsafe impl Send for PWindow {}
+
+unsafe impl Sync for PWindow {}
+
+// these are technically already implemented, but somehow this fixed a error in wgpu
+#[cfg(feature = "raw-window-handle-v0-6")]
+impl HasWindowHandle for PWindow {
+    fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
+        self.0.window_handle()
+    }
+}
+
+#[cfg(feature = "raw-window-handle-v0-6")]
+impl HasDisplayHandle for PWindow {
+    fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
+        self.0.display_handle()
+    }
+}
+
 /// Unique identifier for a `Window`.
 pub type WindowId = usize;
 
@@ -2485,13 +2516,13 @@ impl Window {
 
     /// Returns a render context that can be shared between tasks, allowing
     /// for concurrent rendering.
-    pub fn render_context(&mut self) -> RenderContext {
-        RenderContext {
+    pub fn render_context(&mut self) -> PRenderContext {
+        PRenderContext(Box::new(RenderContext {
             ptr: self.ptr,
             glfw: self.glfw.clone(),
             // this will only be None after dropping so this is safe
             drop_sender: self.drop_sender.as_ref().unwrap().clone(),
-        }
+        }))
     }
 
     /// Wrapper for `glfwWindowShouldClose`.
@@ -3370,6 +3401,40 @@ impl Drop for Window {
     }
 }
 
+#[derive(Debug)]
+#[repr(transparent)]
+pub struct PRenderContext(Box<RenderContext>);
+
+impl Deref for PRenderContext {
+    type Target = RenderContext;
+    fn deref(&self) -> &Self::Target {
+        self.0.deref()
+    }
+}
+
+impl DerefMut for PRenderContext {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        self.0.deref_mut()
+    }
+}
+
+unsafe impl Send for PRenderContext {}
+unsafe impl Sync for PRenderContext {}
+
+#[cfg(feature = "raw-window-handle-v0-6")]
+impl HasWindowHandle for PRenderContext {
+    fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
+        self.0.window_handle()
+    }
+}
+
+#[cfg(feature = "raw-window-handle-v0-6")]
+impl HasDisplayHandle for PRenderContext {
+    fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
+        self.0.display_handle()
+    }
+}
+
 /// A rendering context that can be shared between tasks.
 #[derive(Debug)]
 pub struct RenderContext {
@@ -3491,30 +3556,149 @@ impl Context for RenderContext {
     }
 }
 
+#[cfg(feature = "raw-window-handle-v0-6")]
+impl HasWindowHandle for Window {
+    fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
+        Ok(unsafe { WindowHandle::borrow_raw(raw_window_handle(self)) })
+    }
+}
+
+#[cfg(feature = "raw-window-handle-v0-6")]
+impl HasWindowHandle for RenderContext {
+    fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
+        Ok(unsafe { WindowHandle::borrow_raw(raw_window_handle(self)) })
+    }
+}
+
+#[cfg(feature = "raw-window-handle-v0-6")]
+impl HasDisplayHandle for Window {
+    fn display_handle(&'_ self) -> Result<DisplayHandle<'_>, HandleError> {
+        Ok(unsafe { DisplayHandle::borrow_raw(raw_display_handle()) })
+    }
+}
+
+#[cfg(feature = "raw-window-handle-v0-6")]
+impl HasDisplayHandle for RenderContext {
+    fn display_handle(&'_ self) -> Result<DisplayHandle<'_>, HandleError> {
+        Ok(unsafe { DisplayHandle::borrow_raw(raw_display_handle()) })
+    }
+}
+
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
 unsafe impl HasRawWindowHandle for Window {
     fn raw_window_handle(&self) -> RawWindowHandle {
         raw_window_handle(self)
     }
 }
 
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
 unsafe impl HasRawWindowHandle for RenderContext {
     fn raw_window_handle(&self) -> RawWindowHandle {
         raw_window_handle(self)
     }
 }
 
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
 unsafe impl HasRawDisplayHandle for Window {
     fn raw_display_handle(&self) -> RawDisplayHandle {
         raw_display_handle()
     }
 }
 
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
 unsafe impl HasRawDisplayHandle for RenderContext {
     fn raw_display_handle(&self) -> RawDisplayHandle {
         raw_display_handle()
     }
 }
 
+#[cfg(feature = "raw-window-handle-v0-6")]
+fn raw_window_handle<C: Context>(context: &C) -> RawWindowHandle {
+    #[cfg(target_family = "windows")]
+    {
+        use raw_window_handle::Win32WindowHandle;
+        use std::num::NonZeroIsize;
+        let (hwnd, hinstance): (*mut std::ffi::c_void, *mut std::ffi::c_void) = unsafe {
+            let hwnd= ffi::glfwGetWin32Window(context.window_ptr());
+            let hinstance: *mut c_void = winapi::um::libloaderapi::GetModuleHandleW(std::ptr::null()) as _;
+            (hwnd, hinstance as _)
+        };
+        let mut handle = Win32WindowHandle::new(NonZeroIsize::new(hwnd as isize).unwrap());
+        handle.hinstance = NonZeroIsize::new(hinstance as isize);
+        RawWindowHandle::Win32(handle)
+    }
+    #[cfg(all(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly"), not(feature = "wayland")))]
+    {
+        use raw_window_handle::XlibWindowHandle;
+        let window = unsafe { ffi::glfwGetX11Window(context.window_ptr()) as std::os::raw::c_ulong };
+        RawWindowHandle::Xlib(XlibWindowHandle::new(window))
+    }
+    #[cfg(all(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly"), feature = "wayland"))]
+    {
+        use raw_window_handle::WaylandWindowHandle;
+        use std::ptr::NonNull;
+        let surface = unsafe { ffi::glfwGetWaylandWindow(context.window_ptr()) };
+        let mut handle = WaylandWindowHandle::new(NonNull::new(surface));
+        RawWindowHandle::Wayland(handle)
+    }
+    #[cfg(target_os = "macos")]
+    {
+        use std::ptr::NonNull;
+        use raw_window_handle::AppKitWindowHandle;
+        let ns_view = unsafe {
+            let ns_window: *mut objc::runtime::Object = ffi::glfwGetCocoaWindow(context.window_ptr()) as *mut _;
+            let ns_view: *mut objc::runtime::Object = objc::msg_send![ns_window, contentView];
+            assert_ne!(ns_view, std::ptr::null_mut());
+            ns_view as *mut std::ffi::c_void
+        };
+        let handle = AppKitWindowHandle::new(NonNull::new(ns_view).unwrap());
+        RawWindowHandle::AppKit(handle)
+    }
+    #[cfg(target_os = "emscripten")]
+    {
+        let _ = context; // to avoid unused lint
+        let mut wh = raw_window_handle::WebWindowHandle::new(1);
+        // glfw on emscripten only supports a single window. so, just hardcode it
+        // sdl2 crate does the same. users can just add `data-raw-handle="1"` attribute to their canvas element
+        RawWindowHandle::Web(wh)
+    }
+}
+
+#[cfg(feature = "raw-window-handle-v0-6")]
+fn raw_display_handle() -> RawDisplayHandle {
+    #[cfg(target_family = "windows")]
+    {
+        use raw_window_handle::WindowsDisplayHandle;
+        RawDisplayHandle::Windows(WindowsDisplayHandle::new())
+    }
+    #[cfg(all(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly"), not(feature = "wayland")))]
+    {
+        use raw_window_handle::XlibDisplayHandle;
+        use std::ptr::NonNull;
+        let display = NonNull::new(unsafe { ffi::glfwGetX11Display() });
+        let handle = XlibDisplayHandle::new(display, 0);
+        RawDisplayHandle::Xlib(handle)
+    }
+    #[cfg(all(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly"), feature = "wayland"))]
+    {
+        use raw_window_handle::WaylandDisplayHandle;
+        use std::ptr::NonNull;
+        let display = NonNull::new(unsafe { ffi::glfwGetWaylandDisplay() });
+        let handle = WaylandDisplayHandle::new(display, 0);
+        RawDisplayHandle::Wayland(handle)
+    }
+    #[cfg(target_os = "macos")]
+    {
+        use raw_window_handle::AppKitDisplayHandle;
+        RawDisplayHandle::AppKit(AppKitDisplayHandle::new())
+    }
+    #[cfg(target_os = "emscripten")]
+    {
+        RawDisplayHandle::Web(raw_window_handle::WebDisplayHandle::new())
+    }
+}
+
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
 fn raw_window_handle<C: Context>(context: &C) -> RawWindowHandle {
     #[cfg(target_family = "windows")]
     {
@@ -3572,6 +3756,7 @@ fn raw_window_handle<C: Context>(context: &C) -> RawWindowHandle {
     }
 }
 
+#[cfg(not(feature = "raw-window-handle-v0-6"))]
 fn raw_display_handle() -> RawDisplayHandle {
     #[cfg(target_family = "windows")]
     {
@@ -3603,6 +3788,7 @@ fn raw_display_handle() -> RawDisplayHandle {
     }
 }
 
+
 /// Wrapper for `glfwMakeContextCurrent`.
 pub fn make_context_current(context: Option<&dyn Context>) {
     match context {


Test patch: