Skip to content

Commit 427cda9

Browse files
committed
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. Addresses: rust-windowing#2415
1 parent cdbaf48 commit 427cda9

File tree

3 files changed

+118
-1
lines changed

3 files changed

+118
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ And please only add new entries to the top of this list, right below the `# Unre
1010

1111
- On X11, fix min, max and resize increment hints not persisting for resizable windows (e.g. on DPI change).
1212
- On Windows, respect min/max inner sizes when creating the window.
13+
- For backwards compatibility, `Window` now (additionally) implements the old version (`0.4`) of the `HasRawWindowHandle` trait
1314

1415
# 0.27.1 (2022-07-30)
1516

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ instant = { version = "0.1", features = ["wasm-bindgen"] }
4646
once_cell = "1.12"
4747
log = "0.4"
4848
serde = { version = "1", optional = true, features = ["serde_derive"] }
49-
raw-window-handle = "0.5.0"
49+
raw_window_handle = { package = "raw-window-handle", version = "0.5" }
50+
raw_window_handle_04 = { package = "raw-window-handle", version = "0.4" }
5051
bitflags = "1"
5152
mint = { version = "0.5.6", optional = true }
5253

src/window.rs

+115
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,121 @@ unsafe impl HasRawDisplayHandle for Window {
10661066
self.window.raw_display_handle()
10671067
}
10681068
}
1069+
unsafe impl raw_window_handle_04::HasRawWindowHandle for Window {
1070+
/// Returns a [`raw_window_handle_04::RawWindowHandle`] for the Window
1071+
///
1072+
/// This provides backwards compatibility for downstream crates that have not yet
1073+
/// upgraded to `raw_window_handle` version 0.5, such as Wgpu version 0.13.
1074+
///
1075+
/// ## Platform-specific
1076+
///
1077+
/// ### Android
1078+
///
1079+
/// Only available after receiving [`Event::Resumed`] and before [`Event::Suspended`]. *If you
1080+
/// try to get the handle outside of that period, this function will panic*!
1081+
///
1082+
/// Make sure to release or destroy any resources created from this `RawWindowHandle` (ie. Vulkan
1083+
/// or OpenGL surfaces) before returning from [`Event::Suspended`], at which point Android will
1084+
/// release the underlying window/surface: any subsequent interaction is undefined behavior.
1085+
///
1086+
/// [`Event::Resumed`]: crate::event::Event::Resumed
1087+
/// [`Event::Suspended`]: crate::event::Event::Suspended
1088+
fn raw_window_handle(&self) -> raw_window_handle_04::RawWindowHandle {
1089+
use raw_window_handle_04::{
1090+
AndroidNdkHandle, AppKitHandle, HaikuHandle, OrbitalHandle, UiKitHandle, WaylandHandle,
1091+
WebHandle, Win32Handle, WinRtHandle, XcbHandle, XlibHandle,
1092+
};
1093+
1094+
// XXX: Ideally this would be encapsulated either through a
1095+
// compatibility API from raw_window_handle_05 or else within the
1096+
// backends but since this is only to provide short-term backwards
1097+
// compatibility, we just handle the full mapping inline here.
1098+
//
1099+
// The intention is to remove this trait implementation before Winit
1100+
// 0.28, once crates have had time to upgrade to raw_window_handle 0.5
1101+
1102+
match self.window.raw_window_handle() {
1103+
RawWindowHandle::UiKit(window_handle) => {
1104+
let mut handle = UiKitHandle::empty();
1105+
handle.ui_view = window_handle.ui_view;
1106+
handle.ui_window = window_handle.ui_window;
1107+
handle.ui_view_controller = window_handle.ui_view_controller;
1108+
raw_window_handle_04::RawWindowHandle::UiKit(handle)
1109+
},
1110+
RawWindowHandle::AppKit(window_handle) => {
1111+
let mut handle = AppKitHandle::empty();
1112+
handle.ns_window = window_handle.ns_window;
1113+
handle.ns_view = window_handle.ns_view;
1114+
raw_window_handle_04::RawWindowHandle::AppKit(handle)
1115+
},
1116+
RawWindowHandle::Orbital(window_handle) => {
1117+
let mut handle = OrbitalHandle::empty();
1118+
handle.window = window_handle.window;
1119+
raw_window_handle_04::RawWindowHandle::Orbital(handle)
1120+
},
1121+
RawWindowHandle::Xlib(window_handle) => {
1122+
if let RawDisplayHandle::Xlib(display_handle) = self.window.raw_display_handle() {
1123+
let mut handle = XlibHandle::empty();
1124+
handle.display = display_handle.display;
1125+
handle.window = window_handle.window;
1126+
handle.visual_id = window_handle.visual_id;
1127+
raw_window_handle_04::RawWindowHandle::Xlib(handle)
1128+
} else {
1129+
panic!("Unsupported display handle associated with Xlib window");
1130+
}
1131+
},
1132+
RawWindowHandle::Xcb(window_handle) => {
1133+
if let RawDisplayHandle::Xcb(display_handle) = self.window.raw_display_handle() {
1134+
let mut handle = XcbHandle::empty();
1135+
handle.connection = display_handle.connection;
1136+
handle.window = window_handle.window;
1137+
handle.visual_id = window_handle.visual_id;
1138+
raw_window_handle_04::RawWindowHandle::Xcb(handle)
1139+
} else {
1140+
panic!("Unsupported display handle associated with Xcb window");
1141+
}
1142+
},
1143+
RawWindowHandle::Wayland(window_handle) => {
1144+
if let RawDisplayHandle::Wayland(display_handle) = self.window.raw_display_handle() {
1145+
let mut handle = WaylandHandle::empty();
1146+
handle.display = display_handle.display;
1147+
handle.surface = window_handle.surface;
1148+
raw_window_handle_04::RawWindowHandle::Wayland(handle)
1149+
} else {
1150+
panic!("Unsupported display handle associated with Xcb window");
1151+
}
1152+
},
1153+
RawWindowHandle::Win32(window_handle) => {
1154+
let mut handle = Win32Handle::empty();
1155+
handle.hwnd = window_handle.hwnd;
1156+
handle.hinstance = window_handle.hinstance;
1157+
raw_window_handle_04::RawWindowHandle::Win32(handle)
1158+
},
1159+
RawWindowHandle::WinRt(window_handle) => {
1160+
let mut handle = WinRtHandle::empty();
1161+
handle.core_window = window_handle.core_window;
1162+
raw_window_handle_04::RawWindowHandle::WinRt(handle)
1163+
},
1164+
RawWindowHandle::Web(window_handle) => {
1165+
let mut handle = WebHandle::empty();
1166+
handle.id = window_handle.id;
1167+
raw_window_handle_04::RawWindowHandle::Web(handle)
1168+
},
1169+
RawWindowHandle::AndroidNdk(window_handle) => {
1170+
let mut handle = AndroidNdkHandle::empty();
1171+
handle.a_native_window = window_handle.a_native_window;
1172+
raw_window_handle_04::RawWindowHandle::AndroidNdk(handle)
1173+
},
1174+
RawWindowHandle::Haiku(window_handle) => {
1175+
let mut handle = HaikuHandle::empty();
1176+
handle.b_window = window_handle.b_window;
1177+
handle.b_direct_window = window_handle.b_direct_window;
1178+
raw_window_handle_04::RawWindowHandle::Haiku(handle)
1179+
},
1180+
_ => panic!("No HasRawWindowHandle version 0.4 backwards compatibility for new Winit window type"),
1181+
}
1182+
}
1183+
}
10691184

10701185
/// The behavior of cursor grabbing.
10711186
///

0 commit comments

Comments
 (0)