Implement version 0.4 of the HasRawWindowHandle trait

This makes Winit 0.27 compatible with crates like Wgpu 0.13 that are
using the raw_window_handle v0.4 crate and aren't able to upgrade to 0.5
until they do a new release (since it requires a semver change).

The change is intended to be self-contained (instead of pushing
the details into all the platform_impl backends) since this is only
intended to be a temporary trait implementation for backwards
compatibility that will likely be removed before the next Winit release.

Fixes #2415.
This commit is contained in:
Robert Bragg 2022-08-11 15:33:02 +01:00 committed by GitHub
parent ad41eaf151
commit 11d4a301e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 1 deletions

View file

@ -12,6 +12,7 @@ And please only add new entries to the top of this list, right below the `# Unre
- On X11, fix min, max and resize increment hints not persisting for resizable windows (e.g. on DPI change).
- On Windows, respect min/max inner sizes when creating the window.
- **Breaking:** On Windows, device events are now ignored for unfocused windows by default, use `EventLoopWindowTarget::set_device_event_filter` to set the filter level.
- For backwards compatibility, `Window` now (additionally) implements the old version (`0.4`) of the `HasRawWindowHandle` trait
# 0.27.1 (2022-07-30)

View file

@ -46,7 +46,8 @@ instant = { version = "0.1", features = ["wasm-bindgen"] }
once_cell = "1.12"
log = "0.4"
serde = { version = "1", optional = true, features = ["serde_derive"] }
raw-window-handle = "0.5.0"
raw_window_handle = { package = "raw-window-handle", version = "0.5" }
raw_window_handle_04 = { package = "raw-window-handle", version = "0.4" }
bitflags = "1"
mint = { version = "0.5.6", optional = true }

View file

@ -1066,6 +1066,109 @@ unsafe impl HasRawDisplayHandle for Window {
self.window.raw_display_handle()
}
}
unsafe impl raw_window_handle_04::HasRawWindowHandle for Window {
/// Returns a [`raw_window_handle_04::RawWindowHandle`] for the Window
///
/// This provides backwards compatibility for downstream crates that have not yet
/// upgraded to `raw_window_handle` version 0.5, such as Wgpu version 0.13.
///
/// ## Platform-specific
///
/// ### Android
///
/// Only available after receiving [`Event::Resumed`] and before [`Event::Suspended`]. *If you
/// try to get the handle outside of that period, this function will panic*!
///
/// Make sure to release or destroy any resources created from this `RawWindowHandle` (ie. Vulkan
/// or OpenGL surfaces) before returning from [`Event::Suspended`], at which point Android will
/// release the underlying window/surface: any subsequent interaction is undefined behavior.
///
/// [`Event::Resumed`]: crate::event::Event::Resumed
/// [`Event::Suspended`]: crate::event::Event::Suspended
fn raw_window_handle(&self) -> raw_window_handle_04::RawWindowHandle {
use raw_window_handle_04::{
AndroidNdkHandle, AppKitHandle, HaikuHandle, OrbitalHandle, UiKitHandle, WaylandHandle,
WebHandle, Win32Handle, WinRtHandle, XcbHandle, XlibHandle,
};
// XXX: Ideally this would be encapsulated either through a
// compatibility API from raw_window_handle_05 or else within the
// backends but since this is only to provide short-term backwards
// compatibility, we just handle the full mapping inline here.
//
// The intention is to remove this trait implementation before Winit
// 0.28, once crates have had time to upgrade to raw_window_handle 0.5
match (self.window.raw_window_handle(), self.window.raw_display_handle()) {
(RawWindowHandle::UiKit(window_handle), _) => {
let mut handle = UiKitHandle::empty();
handle.ui_view = window_handle.ui_view;
handle.ui_window = window_handle.ui_window;
handle.ui_view_controller = window_handle.ui_view_controller;
raw_window_handle_04::RawWindowHandle::UiKit(handle)
},
(RawWindowHandle::AppKit(window_handle), _) => {
let mut handle = AppKitHandle::empty();
handle.ns_window = window_handle.ns_window;
handle.ns_view = window_handle.ns_view;
raw_window_handle_04::RawWindowHandle::AppKit(handle)
},
(RawWindowHandle::Orbital(window_handle), _) => {
let mut handle = OrbitalHandle::empty();
handle.window = window_handle.window;
raw_window_handle_04::RawWindowHandle::Orbital(handle)
},
(RawWindowHandle::Xlib(window_handle), RawDisplayHandle::Xlib(display_handle)) => {
let mut handle = XlibHandle::empty();
handle.display = display_handle.display;
handle.window = window_handle.window;
handle.visual_id = window_handle.visual_id;
raw_window_handle_04::RawWindowHandle::Xlib(handle)
},
(RawWindowHandle::Xcb(window_handle), RawDisplayHandle::Xcb(display_handle)) => {
let mut handle = XcbHandle::empty();
handle.connection = display_handle.connection;
handle.window = window_handle.window;
handle.visual_id = window_handle.visual_id;
raw_window_handle_04::RawWindowHandle::Xcb(handle)
},
(RawWindowHandle::Wayland(window_handle), RawDisplayHandle::Wayland(display_handle)) => {
let mut handle = WaylandHandle::empty();
handle.display = display_handle.display;
handle.surface = window_handle.surface;
raw_window_handle_04::RawWindowHandle::Wayland(handle)
},
(RawWindowHandle::Win32(window_handle), _) => {
let mut handle = Win32Handle::empty();
handle.hwnd = window_handle.hwnd;
handle.hinstance = window_handle.hinstance;
raw_window_handle_04::RawWindowHandle::Win32(handle)
},
(RawWindowHandle::WinRt(window_handle), _) => {
let mut handle = WinRtHandle::empty();
handle.core_window = window_handle.core_window;
raw_window_handle_04::RawWindowHandle::WinRt(handle)
},
(RawWindowHandle::Web(window_handle), _) => {
let mut handle = WebHandle::empty();
handle.id = window_handle.id;
raw_window_handle_04::RawWindowHandle::Web(handle)
},
(RawWindowHandle::AndroidNdk(window_handle), _) => {
let mut handle = AndroidNdkHandle::empty();
handle.a_native_window = window_handle.a_native_window;
raw_window_handle_04::RawWindowHandle::AndroidNdk(handle)
},
(RawWindowHandle::Haiku(window_handle), _) => {
let mut handle = HaikuHandle::empty();
handle.b_window = window_handle.b_window;
handle.b_direct_window = window_handle.b_direct_window;
raw_window_handle_04::RawWindowHandle::Haiku(handle)
},
_ => panic!("No HasRawWindowHandle version 0.4 backwards compatibility for new Winit window type"),
}
}
}
/// The behavior of cursor grabbing.
///