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: #2415
  • Loading branch information
rib committed Aug 10, 2022
1 parent cdbaf48 commit 96c0cde
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 9 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
4 changes: 2 additions & 2 deletions 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 Expand Up @@ -339,7 +339,7 @@ impl<T> EventLoopWindowTarget<T> {
}

unsafe impl<T> HasRawDisplayHandle for EventLoopWindowTarget<T> {
/// Returns a [`raw_window_handle::RawDisplayHandle`] for the event loop.
/// Returns a [`raw_window_handle_05::RawDisplayHandle`] for the event loop.
fn raw_display_handle(&self) -> RawDisplayHandle {
self.p.raw_display_handle()
}
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
122 changes: 118 additions & 4 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 @@ -1037,7 +1037,7 @@ impl Window {
}
}
unsafe impl HasRawWindowHandle for Window {
/// Returns a [`raw_window_handle::RawWindowHandle`] for the Window
/// Returns a [`raw_window_handle_05::RawWindowHandle`] for the Window
///
/// ## Platform-specific
///
Expand All @@ -1056,16 +1056,130 @@ 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
/// Returns a [`raw_window_handle_05::RawDisplayHandle`] used by the [`EventLoop`] that
/// created a window.
///
/// [`EventLoop`]: crate::event_loop::EventLoop
fn raw_display_handle(&self) -> RawDisplayHandle {
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() {
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 96c0cde

Please sign in to comment.