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.

Addresses: rust-windowing#2415
  • Loading branch information
rib committed Aug 10, 2022
1 parent cdbaf48 commit 03f591c
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,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.
- 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_05 = { 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
2 changes: 1 addition & 1 deletion src/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::{error, fmt};

use instant::Instant;
use once_cell::sync::OnceCell;
use raw_window_handle::{HasRawDisplayHandle, RawDisplayHandle};
use raw_window_handle_05::{HasRawDisplayHandle, RawDisplayHandle};

use crate::{event::Event, monitor::MonitorHandle, platform_impl};

Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::{

use once_cell::sync::Lazy;
use parking_lot::Mutex;
use raw_window_handle::{RawDisplayHandle, WindowsDisplayHandle};
use raw_window_handle_05::{RawDisplayHandle, WindowsDisplayHandle};

use windows_sys::Win32::{
Devices::HumanInterfaceDevice::MOUSE_MOVE_RELATIVE,
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![cfg(target_os = "windows")]

use parking_lot::Mutex;
use raw_window_handle::{
use raw_window_handle_05::{
RawDisplayHandle, RawWindowHandle, Win32WindowHandle, WindowsDisplayHandle,
};
use std::{
Expand Down
114 changes: 112 additions & 2 deletions src/window.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! The [`Window`] struct and associated types.
use std::fmt;

use raw_window_handle::{
use raw_window_handle_05::{
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
};

Expand Down Expand Up @@ -1056,7 +1056,6 @@ unsafe impl HasRawWindowHandle for Window {
self.window.raw_window_handle()
}
}

unsafe impl HasRawDisplayHandle for Window {
/// Returns a [`raw_window_handle::RawDisplayHandle`] used by the [`EventLoop`] that
/// created a window.
Expand All @@ -1066,6 +1065,117 @@ 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 to make it easier to crates to
// adopt Winit 0.27 then we just handle the full mapping inline here
match self.window.raw_window_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) => {
if let RawDisplayHandle::Xlib(display_handle) = self.window.raw_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)
} else {
panic!("Unsupported display handle associated with Xlib window");
}
},
RawWindowHandle::Xcb(window_handle) => {
if let RawDisplayHandle::Xcb(display_handle) = self.window.raw_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)
} else {
panic!("Unsupported display handle associated with Xcb window");
}
},
RawWindowHandle::Wayland(window_handle) => {
if let RawDisplayHandle::Wayland(display_handle) = self.window.raw_display_handle() {
let mut handle = WaylandHandle::empty();
handle.display = display_handle.display;
handle.surface = window_handle.surface;
raw_window_handle_04::RawWindowHandle::Wayland(handle)
} else {
panic!("Unsupported display handle associated with Xcb window");
}
},
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 03f591c

Please sign in to comment.