Skip to content

Commit

Permalink
Implement version 0.4 of the HasRawWindowHandle trait
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rib committed Aug 11, 2022
1 parent ad41eaf commit 11d4a30
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down
103 changes: 103 additions & 0 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down

0 comments on commit 11d4a30

Please sign in to comment.