diff --git a/.changes/rwh-06.md b/.changes/rwh-06.md new file mode 100644 index 000000000..65375f20f --- /dev/null +++ b/.changes/rwh-06.md @@ -0,0 +1,9 @@ +--- +"tao": "patch" +--- + +This release includes an update to `raw-window-handle` crate to `0.6` but will also provide a feature flags to select which `raw-window-handle` to use: + +- `rwh_06` (default): `raw-window-handle@0.6` +- `rwh_05: `raw-window-handle@0.5` +- `rwh_04: `raw-window-handle@0.4` diff --git a/Cargo.toml b/Cargo.toml index b3779a9f8..2141e9aa1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,8 +15,11 @@ repository = "https://github.com/tauri-apps/tao" documentation = "https://docs.rs/tao" categories = [ "gui" ] +[features] +default = ["rwh_06"] + [package.metadata.docs.rs] -features = [ "serde" ] +features = ["rwh_04", "rwh_05", "rwh_06", "serde"] default-target = "x86_64-unknown-linux-gnu" targets = [ "i686-pc-windows-msvc", @@ -29,9 +32,6 @@ targets = [ [workspace] members = [ "tao-macros" ] -[features] -default = [ ] - [build-dependencies] cc = "1" @@ -41,7 +41,9 @@ lazy_static = "1" libc = "0.2" log = "0.4" serde = { version = "1", optional = true, features = [ "serde_derive" ] } -raw-window-handle = "0.5" +rwh_04 = { package = "raw-window-handle", version = "0.4", optional = true } +rwh_05 = { package = "raw-window-handle", version = "0.5", features = ["std"], optional = true } +rwh_06 = { package = "raw-window-handle", version = "0.6", features = ["std"], optional = true } bitflags = "1" crossbeam-channel = "0.5" url = "2" @@ -110,18 +112,10 @@ windows-implement = "0.51" ] [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies] -cairo-rs = "0.18" -gio = "0.18" -glib = "0.18" -glib-sys = "0.18" gtk = "0.18" -gdk = "0.18" -gdk-sys = "0.18" gdkx11-sys = "0.18" gdkwayland-sys = "0.18.0" -gdk-pixbuf = "0.18" x11-dl = "2.21" zbus = "3" -uuid = { version = "1.5", features = [ "v4" ] } png = "0.17" parking_lot = "0.12" diff --git a/src/event_loop.rs b/src/event_loop.rs index c94d69e6a..dbc2146cc 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -14,7 +14,6 @@ //! [event_loop_proxy]: crate::event_loop::EventLoopProxy //! [send_event]: crate::event_loop::EventLoopProxy::send_event use instant::Instant; -use raw_window_handle::{HasRawDisplayHandle, RawDisplayHandle}; use std::{error, fmt, marker::PhantomData, ops::Deref}; use crate::{ @@ -299,10 +298,33 @@ impl EventLoopWindowTarget { } } -unsafe impl HasRawDisplayHandle for EventLoopWindowTarget { - /// Returns a [`raw_window_handle::RawDisplayHandle`] for the event loop. - fn raw_display_handle(&self) -> RawDisplayHandle { - self.p.raw_display_handle() +#[cfg(feature = "rwh_05")] +unsafe impl rwh_05::HasRawDisplayHandle for EventLoop { + fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { + rwh_05::HasRawDisplayHandle::raw_display_handle(&**self) + } +} + +#[cfg(feature = "rwh_06")] +impl rwh_06::HasDisplayHandle for EventLoop { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + rwh_06::HasDisplayHandle::display_handle(&**self) + } +} + +#[cfg(feature = "rwh_05")] +unsafe impl rwh_05::HasRawDisplayHandle for EventLoopWindowTarget { + fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { + self.p.raw_display_handle_rwh_05() + } +} + +#[cfg(feature = "rwh_06")] +impl rwh_06::HasDisplayHandle for EventLoopWindowTarget { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = self.p.raw_display_handle_rwh_06()?; + // SAFETY: The display will never be deallocated while the event loop is alive. + Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw) }) } } diff --git a/src/lib.rs b/src/lib.rs index dfa702d3d..43e34c923 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -150,6 +150,13 @@ #[cfg(target_os = "android")] pub use tao_macros::{android_fn, generate_package_name}; +#[cfg(feature = "rwh_04")] +pub use rwh_04 as raw_window_handle; +#[cfg(feature = "rwh_05")] +pub use rwh_05 as raw_window_handle; +#[cfg(feature = "rwh_06")] +pub use rwh_06 as raw_window_handle; + #[allow(unused_imports)] #[macro_use] extern crate lazy_static; diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 6bd64dc67..11e1b8389 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -18,9 +18,6 @@ use ndk::{ looper::{ForeignLooper, Poll, ThreadLooper}, }; use ndk_sys::AKeyEvent_getKeyCode; -use raw_window_handle::{ - AndroidDisplayHandle, AndroidNdkWindowHandle, RawDisplayHandle, RawWindowHandle, -}; use std::{ collections::VecDeque, convert::TryInto, @@ -446,8 +443,18 @@ impl EventLoopWindowTarget { v } - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Android(AndroidDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Android(rwh_05::AndroidDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::Android( + rwh_06::AndroidDisplayHandle::new(), + )) } pub fn cursor_position(&self) -> Result, error::ExternalError> { @@ -681,21 +688,55 @@ impl Window { Ok((0, 0).into()) } - pub fn raw_window_handle(&self) -> RawWindowHandle { + #[cfg(feature = "rwh_04")] + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + // TODO: Use main activity instead? + let mut handle = rwh_04::AndroidNdkHandle::empty(); + if let Some(w) = ndk_glue::window_manager() { + handle.a_native_window = w.as_obj().as_raw() as *mut _; + } else { + panic!("Cannot get the native window, it's null and will always be null before Event::Resumed and after Event::Suspended. Make sure you only call this function between those events."); + }; + rwh_04::RawWindowHandle::AndroidNdk(handle) + } + + #[cfg(feature = "rwh_05")] + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { // TODO: Use main activity instead? - let mut handle = AndroidNdkWindowHandle::empty(); + let mut handle = rwh_05::AndroidNdkWindowHandle::empty(); if let Some(w) = ndk_glue::window_manager() { handle.a_native_window = w.as_obj().as_raw() as *mut _; } else { panic!("Cannot get the native window, it's null and will always be null before Event::Resumed and after Event::Suspended. Make sure you only call this function between those events."); }; - RawWindowHandle::AndroidNdk(handle) + rwh_05::RawWindowHandle::AndroidNdk(handle) } - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Android(AndroidDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Android(rwh_05::AndroidDisplayHandle::empty()) } + #[cfg(feature = "rwh_06")] + pub fn raw_window_handle_rwh_06(&self) -> Result { + // TODO: Use main activity instead? + if let Some(w) = ndk_glue::window_manager() { + let native_window = + unsafe { std::ptr::NonNull::new_unchecked(w.as_obj().as_raw() as *mut _) }; + // native_window shuldn't be null + let handle = rwh_06::AndroidNdkWindowHandle::new(native_window); + Ok(rwh_06::RawWindowHandle::AndroidNdk(handle)) + } else { + Err(rwh_06::HandleError::Unavailable) + } + } + + #[cfg(feature = "rwh_06")] + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::Android( + rwh_06::AndroidDisplayHandle::new(), + )) + } pub fn config(&self) -> Configuration { CONFIG.read().unwrap().clone() } diff --git a/src/platform_impl/ios/event_loop.rs b/src/platform_impl/ios/event_loop.rs index 0ebc02219..6971ddfaf 100644 --- a/src/platform_impl/ios/event_loop.rs +++ b/src/platform_impl/ios/event_loop.rs @@ -12,8 +12,6 @@ use std::{ use crossbeam_channel::{self as channel, Receiver, Sender}; -use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle}; - use crate::{ dpi::{LogicalSize, PhysicalPosition}, error::ExternalError, @@ -66,7 +64,7 @@ impl EventLoopWindowTarget { } #[inline] - pub fn monitor_from_point(&self, x: f64, y: f64) -> Option { + pub fn monitor_from_point(&self, _x: f64, _y: f64) -> Option { warn!("`Window::monitor_from_point` is ignored on iOS"); return None; } @@ -78,8 +76,18 @@ impl EventLoopWindowTarget { Some(RootMonitorHandle { inner: monitor }) } - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::UiKit(UiKitDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::UiKit(rwh_05::UiKitDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::UiKit( + rwh_06::UiKitDisplayHandle::new(), + )) } pub fn cursor_position(&self) -> Result, ExternalError> { diff --git a/src/platform_impl/ios/mod.rs b/src/platform_impl/ios/mod.rs index 1e5565a2b..b788c57d6 100644 --- a/src/platform_impl/ios/mod.rs +++ b/src/platform_impl/ios/mod.rs @@ -91,7 +91,7 @@ pub use self::{ window::{PlatformSpecificWindowBuilderAttributes, Window, WindowId}, }; -pub(crate) use crate::icon::{Icon, NoIcon as PlatformIcon}; +pub(crate) use crate::icon::NoIcon as PlatformIcon; // todo: implement iOS keyboard event #[derive(Debug, Clone, Eq, PartialEq, Hash)] diff --git a/src/platform_impl/ios/monitor.rs b/src/platform_impl/ios/monitor.rs index fea1a10c0..6887a2195 100644 --- a/src/platform_impl/ios/monitor.rs +++ b/src/platform_impl/ios/monitor.rs @@ -169,6 +169,7 @@ impl Drop for MonitorHandle { impl fmt::Debug for MonitorHandle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[derive(Debug)] + #[allow(unused)] struct MonitorHandle { name: Option, size: PhysicalSize, diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 8e1f77f6f..dfda97753 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -2,7 +2,6 @@ // Copyright 2021-2023 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 -use raw_window_handle::{RawDisplayHandle, RawWindowHandle, UiKitDisplayHandle, UiKitWindowHandle}; use std::{ collections::VecDeque, ops::{Deref, DerefMut}, @@ -374,7 +373,7 @@ impl Inner { } #[inline] - pub fn monitor_from_point(&self, x: f64, y: f64) -> Option { + pub fn monitor_from_point(&self, _x: f64, _y: f64) -> Option { warn!("`Window::monitor_from_point` is ignored on iOS"); None } @@ -388,16 +387,43 @@ impl Inner { self.window.into() } - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut window_handle = UiKitWindowHandle::empty(); + #[cfg(feature = "rwh_04")] + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut window_handle = rwh_04::UiKitHandle::empty(); window_handle.ui_window = self.window as _; window_handle.ui_view = self.view as _; window_handle.ui_view_controller = self.view_controller as _; - RawWindowHandle::UiKit(window_handle) + rwh_04::RawWindowHandle::UiKit(window_handle) } - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::UiKit(UiKitDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut window_handle = rwh_05::UiKitWindowHandle::empty(); + window_handle.ui_window = self.window as _; + window_handle.ui_view = self.view as _; + window_handle.ui_view_controller = self.view_controller as _; + rwh_05::RawWindowHandle::UiKit(window_handle) + } + + #[cfg(feature = "rwh_05")] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::UiKit(rwh_05::UiKitDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + pub fn raw_window_handle_rwh_06(&self) -> Result { + let mut window_handle = rwh_06::UiKitWindowHandle::new({ + std::ptr::NonNull::new(self.view as _).expect("self.view should never be null") + }); + window_handle.ui_view_controller = std::ptr::NonNull::new(self.view_controller as _); + Ok(rwh_06::RawWindowHandle::UiKit(window_handle)) + } + + #[cfg(feature = "rwh_06")] + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::UiKit( + rwh_06::UiKitDisplayHandle::new(), + )) } pub fn theme(&self) -> Theme { diff --git a/src/platform_impl/linux/device.rs b/src/platform_impl/linux/device.rs index a2784d03e..860860379 100644 --- a/src/platform_impl/linux/device.rs +++ b/src/platform_impl/linux/device.rs @@ -3,6 +3,7 @@ use std::{ ptr, }; +use gtk::glib; use x11_dl::{xinput2, xlib}; use crate::event::{DeviceEvent, ElementState, RawKeyEvent}; diff --git a/src/platform_impl/linux/event_loop.rs b/src/platform_impl/linux/event_loop.rs index e2354d9cb..ed3e96cd5 100644 --- a/src/platform_impl/linux/event_loop.rs +++ b/src/platform_impl/linux/event_loop.rs @@ -15,11 +15,9 @@ use std::{ use cairo::{RectangleInt, Region}; use crossbeam_channel::SendError; use gdk::{Cursor, CursorType, EventKey, EventMask, ScrollDirection, WindowEdge, WindowState}; -use gio::{prelude::*, Cancellable}; +use gio::Cancellable; use glib::{source::Priority, MainContext}; -use gtk::prelude::*; - -use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle, XlibDisplayHandle}; +use gtk::{cairo, gdk, gio, glib, prelude::*}; use crate::{ dpi::{LogicalPosition, LogicalSize, PhysicalPosition}, @@ -86,15 +84,16 @@ impl EventLoopWindowTarget { }) } - pub fn raw_display_handle(&self) -> RawDisplayHandle { + #[cfg(feature = "rwh_05")] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { if self.is_wayland() { - let mut display_handle = WaylandDisplayHandle::empty(); + let mut display_handle = rwh_05::WaylandDisplayHandle::empty(); display_handle.display = unsafe { gdk_wayland_sys::gdk_wayland_display_get_wl_display(self.display.as_ptr() as *mut _) }; - RawDisplayHandle::Wayland(display_handle) + rwh_05::RawDisplayHandle::Wayland(display_handle) } else { - let mut display_handle = XlibDisplayHandle::empty(); + let mut display_handle = rwh_05::XlibDisplayHandle::empty(); unsafe { if let Ok(xlib) = x11_dl::xlib::Xlib::open() { let display = (xlib.XOpenDisplay)(std::ptr::null()); @@ -103,7 +102,31 @@ impl EventLoopWindowTarget { } } - RawDisplayHandle::Xlib(display_handle) + rwh_05::RawDisplayHandle::Xlib(display_handle) + } + } + + #[cfg(feature = "rwh_06")] + pub fn raw_display_handle_rwh_06(&self) -> Result { + if self.is_wayland() { + let display = unsafe { + gdk_wayland_sys::gdk_wayland_display_get_wl_display(self.display.as_ptr() as *mut _) + }; + let display = unsafe { std::ptr::NonNull::new_unchecked(display) }; + let display_handle = rwh_06::WaylandDisplayHandle::new(display); + Ok(rwh_06::RawDisplayHandle::Wayland(display_handle)) + } else { + unsafe { + if let Ok(xlib) = x11_dl::xlib::Xlib::open() { + let display = (xlib.XOpenDisplay)(std::ptr::null()); + let screen = (xlib.XDefaultScreen)(display) as _; + let display = std::ptr::NonNull::new_unchecked(display as _); + let display_handle = rwh_06::XlibDisplayHandle::new(Some(display), screen); + Ok(rwh_06::RawDisplayHandle::Xlib(display_handle)) + } else { + Err(rwh_06::HandleError::Unavailable) + } + } } } @@ -239,7 +262,7 @@ impl EventLoop { } } WindowRequest::Focus => { - window.present_with_time(gdk_sys::GDK_CURRENT_TIME as _); + window.present_with_time(gdk::ffi::GDK_CURRENT_TIME as _); } WindowRequest::Resizable(resizable) => window.set_resizable(resizable), WindowRequest::Closable(closable) => window.set_deletable(closable), diff --git a/src/platform_impl/linux/icon.rs b/src/platform_impl/linux/icon.rs index 2a13f5c0a..2d2f0ecef 100644 --- a/src/platform_impl/linux/icon.rs +++ b/src/platform_impl/linux/icon.rs @@ -4,7 +4,7 @@ use std::{fs::File, io::BufWriter, path::Path}; -use gdk_pixbuf::{Colorspace, Pixbuf}; +use gtk::gdk_pixbuf::{Colorspace, Pixbuf}; use crate::window::BadIcon; @@ -21,7 +21,7 @@ impl From for Pixbuf { fn from(icon: PlatformIcon) -> Self { Pixbuf::from_mut_slice( icon.raw, - gdk_pixbuf::Colorspace::Rgb, + Colorspace::Rgb, true, 8, icon.width, diff --git a/src/platform_impl/linux/keyboard.rs b/src/platform_impl/linux/keyboard.rs index ed56abd92..be0198d0d 100644 --- a/src/platform_impl/linux/keyboard.rs +++ b/src/platform_impl/linux/keyboard.rs @@ -7,7 +7,10 @@ use crate::{ event::{ElementState, KeyEvent}, keyboard::{Key, KeyCode, KeyLocation, ModifiersState, NativeKeyCode}, }; -use gdk::{keys::constants::*, EventKey}; +use gtk::{ + gdk::{self, keys::constants::*, EventKey}, + glib, +}; use std::{ collections::HashSet, ffi::c_void, @@ -235,17 +238,17 @@ pub(crate) fn make_key_event( fn hardware_keycode_to_keyval(keycode: u16) -> Option { use glib::translate::FromGlib; unsafe { - let keymap = gdk_sys::gdk_keymap_get_default(); + let keymap = gdk::ffi::gdk_keymap_get_default(); let mut nkeys = 0; - let mut keys: *mut gdk_sys::GdkKeymapKey = ptr::null_mut(); + let mut keys: *mut gdk::ffi::GdkKeymapKey = ptr::null_mut(); let mut keyvals: *mut c_uint = ptr::null_mut(); // call into gdk to retrieve the keyvals and keymap keys - gdk_sys::gdk_keymap_get_entries_for_keycode( + gdk::ffi::gdk_keymap_get_entries_for_keycode( keymap, c_uint::from(keycode), - &mut keys as *mut *mut gdk_sys::GdkKeymapKey, + &mut keys as *mut *mut gdk::ffi::GdkKeymapKey, &mut keyvals as *mut *mut c_uint, &mut nkeys as *mut c_int, ); @@ -263,8 +266,8 @@ fn hardware_keycode_to_keyval(keycode: u16) -> Option { }); // notify glib to free the allocated arrays - glib_sys::g_free(keyvals as *mut c_void); - glib_sys::g_free(keys as *mut c_void); + glib::ffi::g_free(keyvals as *mut c_void); + glib::ffi::g_free(keys as *mut c_void); return resolved_keyval; } diff --git a/src/platform_impl/linux/monitor.rs b/src/platform_impl/linux/monitor.rs index 205f6c9d6..ceeea1265 100644 --- a/src/platform_impl/linux/monitor.rs +++ b/src/platform_impl/linux/monitor.rs @@ -2,7 +2,7 @@ // Copyright 2021-2023 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 -use gdk::{prelude::MonitorExt, Display}; +use gtk::gdk::{self, prelude::MonitorExt, Display}; use crate::{ dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}, diff --git a/src/platform_impl/linux/util.rs b/src/platform_impl/linux/util.rs index 514a04b50..93ccd4e96 100644 --- a/src/platform_impl/linux/util.rs +++ b/src/platform_impl/linux/util.rs @@ -1,4 +1,5 @@ -use gdk::{ +use gtk::gdk::{ + self, prelude::{DeviceExt, SeatExt}, Display, }; diff --git a/src/platform_impl/linux/window.rs b/src/platform_impl/linux/window.rs index 0f6c6009a..9c3f41a2b 100644 --- a/src/platform_impl/linux/window.rs +++ b/src/platform_impl/linux/window.rs @@ -12,13 +12,11 @@ use std::{ }, }; -use gdk::{WindowEdge, WindowState}; -use glib::translate::ToGlibPtr; -use gtk::{prelude::*, Settings}; -use raw_window_handle::{ - RawDisplayHandle, RawWindowHandle, WaylandDisplayHandle, WaylandWindowHandle, XlibDisplayHandle, - XlibWindowHandle, +use gtk::{ + gdk::{self, WindowEdge, WindowState}, + glib::{self, translate::ToGlibPtr}, }; +use gtk::{prelude::*, Settings}; use crate::{ dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}, @@ -717,35 +715,61 @@ impl Window { self.window.display().backend().is_wayland() } - pub fn raw_window_handle(&self) -> RawWindowHandle { + #[cfg(feature = "rwh_04")] + #[inline] + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { if self.is_wayland() { - let mut window_handle = WaylandWindowHandle::empty(); + let mut window_handle = rwh_04::WaylandHandle::empty(); if let Some(window) = self.window.window() { window_handle.surface = unsafe { gdk_wayland_sys::gdk_wayland_window_get_wl_surface(window.as_ptr() as *mut _) }; } - RawWindowHandle::Wayland(window_handle) + rwh_04::RawWindowHandle::Wayland(window_handle) } else { - let mut window_handle = XlibWindowHandle::empty(); + let mut window_handle = rwh_04::XlibHandle::empty(); unsafe { if let Some(window) = self.window.window() { window_handle.window = gdk_x11_sys::gdk_x11_window_get_xid(window.as_ptr() as *mut _); } } - RawWindowHandle::Xlib(window_handle) + rwh_04::RawWindowHandle::Xlib(window_handle) } } - pub fn raw_display_handle(&self) -> RawDisplayHandle { + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { if self.is_wayland() { - let mut display_handle = WaylandDisplayHandle::empty(); + let mut window_handle = rwh_05::WaylandWindowHandle::empty(); + if let Some(window) = self.window.window() { + window_handle.surface = + unsafe { gdk_wayland_sys::gdk_wayland_window_get_wl_surface(window.as_ptr() as *mut _) }; + } + + rwh_05::RawWindowHandle::Wayland(window_handle) + } else { + let mut window_handle = rwh_05::XlibWindowHandle::empty(); + unsafe { + if let Some(window) = self.window.window() { + window_handle.window = gdk_x11_sys::gdk_x11_window_get_xid(window.as_ptr() as *mut _); + } + } + rwh_05::RawWindowHandle::Xlib(window_handle) + } + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + if self.is_wayland() { + let mut display_handle = rwh_05::WaylandDisplayHandle::empty(); display_handle.display = unsafe { gdk_wayland_sys::gdk_wayland_display_get_wl_display(self.window.display().as_ptr() as *mut _) }; - RawDisplayHandle::Wayland(display_handle) + rwh_05::RawDisplayHandle::Wayland(display_handle) } else { - let mut display_handle = XlibDisplayHandle::empty(); + let mut display_handle = rwh_05::XlibDisplayHandle::empty(); unsafe { if let Ok(xlib) = x11_dl::xlib::Xlib::open() { let display = (xlib.XOpenDisplay)(std::ptr::null()); @@ -754,7 +778,52 @@ impl Window { } } - RawDisplayHandle::Xlib(display_handle) + rwh_05::RawDisplayHandle::Xlib(display_handle) + } + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_window_handle_rwh_06(&self) -> Result { + if let Some(window) = self.window.window() { + if self.is_wayland() { + let surface = + unsafe { gdk_wayland_sys::gdk_wayland_window_get_wl_surface(window.as_ptr() as *mut _) }; + let surface = unsafe { std::ptr::NonNull::new_unchecked(surface) }; + let window_handle = rwh_06::WaylandWindowHandle::new(surface); + Ok(rwh_06::RawWindowHandle::Wayland(window_handle)) + } else { + let xid = unsafe { gdk_x11_sys::gdk_x11_window_get_xid(window.as_ptr() as *mut _) }; + let window_handle = rwh_06::XlibWindowHandle::new(xid); + Ok(rwh_06::RawWindowHandle::Xlib(window_handle)) + } + } else { + Err(rwh_06::HandleError::Unavailable) + } + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06(&self) -> Result { + if self.is_wayland() { + let display = unsafe { + gdk_wayland_sys::gdk_wayland_display_get_wl_display(self.window.display().as_ptr() as *mut _) + }; + let display = unsafe { std::ptr::NonNull::new_unchecked(display) }; + let display_handle = rwh_06::WaylandDisplayHandle::new(display); + Ok(rwh_06::RawDisplayHandle::Wayland(display_handle)) + } else { + if let Ok(xlib) = x11_dl::xlib::Xlib::open() { + unsafe { + let display = (xlib.XOpenDisplay)(std::ptr::null()); + let screen = (xlib.XDefaultScreen)(display) as _; + let display = std::ptr::NonNull::new_unchecked(display as _); + let display_handle = rwh_06::XlibDisplayHandle::new(Some(display), screen); + Ok(rwh_06::RawDisplayHandle::Xlib(display_handle)) + } + } else { + Err(rwh_06::HandleError::Unavailable) + } } } diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index 7e1a3f8f1..b7f8e62c9 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -20,7 +20,6 @@ use cocoa::{ foundation::{NSAutoreleasePool, NSInteger, NSPoint, NSTimeInterval}, }; use crossbeam_channel::{self as channel, Receiver, Sender}; -use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle}; use scopeguard::defer; use crate::{ @@ -99,11 +98,19 @@ impl EventLoopWindowTarget { Some(RootMonitorHandle { inner: monitor }) } + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::AppKit(AppKitDisplayHandle::empty()) + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::AppKit(rwh_05::AppKitDisplayHandle::empty()) } + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::AppKit( + rwh_06::AppKitDisplayHandle::new(), + )) + } #[inline] pub fn cursor_position(&self) -> Result, ExternalError> { let point = util::cursor_position()?; diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 291200fd3..63370d041 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -13,10 +13,6 @@ use std::{ }, }; -use raw_window_handle::{ - AppKitDisplayHandle, AppKitWindowHandle, RawDisplayHandle, RawWindowHandle, -}; - use crate::{ dpi::{ LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size, Size::Logical, @@ -1364,17 +1360,46 @@ impl UnownedWindow { Some(RootMonitorHandle { inner: monitor }) } + #[cfg(feature = "rwh_04")] + #[inline] + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut window_handle = rwh_04::AppKitHandle::empty(); + window_handle.ns_window = self.ns_window(); + window_handle.ns_view = self.ns_view(); + rwh_04::RawWindowHandle::AppKit(window_handle) + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut window_handle = rwh_05::AppKitWindowHandle::empty(); + window_handle.ns_window = self.ns_window(); + window_handle.ns_view = self.ns_view(); + rwh_05::RawWindowHandle::AppKit(window_handle) + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::AppKit(rwh_05::AppKitDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] #[inline] - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut window_handle = AppKitWindowHandle::empty(); - window_handle.ns_window = *self.ns_window as *mut _; - window_handle.ns_view = *self.ns_view as *mut _; - RawWindowHandle::AppKit(window_handle) + pub fn raw_window_handle_rwh_06(&self) -> Result { + let window_handle = rwh_06::AppKitWindowHandle::new({ + let ptr = self.ns_view(); + std::ptr::NonNull::new(ptr).expect("Id should never be null") + }); + Ok(rwh_06::RawWindowHandle::AppKit(window_handle)) } + #[cfg(feature = "rwh_06")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::AppKit(AppKitDisplayHandle::empty()) + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::AppKit( + rwh_06::AppKitDisplayHandle::new(), + )) } #[inline] diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 98085d64c..1638793eb 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -8,7 +8,6 @@ mod runner; use crossbeam_channel::{self as channel, Receiver, Sender}; use parking_lot::Mutex; -use raw_window_handle::{RawDisplayHandle, WindowsDisplayHandle}; use std::{ cell::Cell, collections::VecDeque, @@ -311,8 +310,16 @@ impl EventLoopWindowTarget { monitor::from_point(x, y) } - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Windows(WindowsDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Windows(rwh_05::WindowsDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::Windows( + rwh_06::WindowsDisplayHandle::new(), + )) } pub fn set_device_event_filter(&self, filter: DeviceEventFilter) { diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 404aceedf..b6a77f041 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -6,9 +6,6 @@ use mem::MaybeUninit; use parking_lot::Mutex; -use raw_window_handle::{ - RawDisplayHandle, RawWindowHandle, Win32WindowHandle, WindowsDisplayHandle, -}; use std::{ cell::{Cell, RefCell}, ffi::OsStr, @@ -360,17 +357,51 @@ impl Window { util::get_instance_handle() } + #[cfg(feature = "rwh_04")] + #[inline] + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut window_handle = rwh_04::Win32Handle::empty(); + window_handle.hwnd = self.window.0 .0 as *mut _; + let hinstance = util::GetWindowLongPtrW(self.hwnd(), GWLP_HINSTANCE); + window_handle.hinstance = hinstance as *mut _; + rwh_04::RawWindowHandle::Win32(window_handle) + } + + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut window_handle = Win32WindowHandle::empty(); + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut window_handle = rwh_05::Win32WindowHandle::empty(); window_handle.hwnd = self.window.0 .0 as *mut _; - window_handle.hinstance = self.hinstance().0 as *mut _; - RawWindowHandle::Win32(window_handle) + let hinstance = util::GetWindowLongPtrW(self.hwnd(), GWLP_HINSTANCE); + window_handle.hinstance = hinstance as *mut _; + rwh_05::RawWindowHandle::Win32(window_handle) + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Windows(rwh_05::WindowsDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_window_handle_rwh_06(&self) -> Result { + let mut window_handle = rwh_06::Win32WindowHandle::new(unsafe { + // SAFETY: Handle will never be zero. + let window = self.window.0 .0; + std::num::NonZeroIsize::new_unchecked(window) + }); + let hinstance = util::GetWindowLongPtrW(self.hwnd(), GWLP_HINSTANCE); + window_handle.hinstance = std::num::NonZeroIsize::new(hinstance); + Ok(rwh_06::RawWindowHandle::Win32(window_handle)) } + #[cfg(feature = "rwh_06")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Windows(WindowsDisplayHandle::empty()) + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::Windows( + rwh_06::WindowsDisplayHandle::new(), + )) } #[inline] diff --git a/src/window.rs b/src/window.rs index eb84c57be..8a3b9677f 100644 --- a/src/window.rs +++ b/src/window.rs @@ -5,8 +5,6 @@ //! The `Window` struct and associated types. use std::fmt; -use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle}; - use crate::{ dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Pixel, PixelUnit, Position, Size}, error::{ExternalError, NotSupportedError, OsError}, @@ -1271,28 +1269,45 @@ impl Window { } } -// Safety: objc runtime calls are unsafe -unsafe impl HasRawWindowHandle for Window { - /// Returns a `raw_window_handle::RawWindowHandle` for the Window - /// - /// ## Platform-specific - /// - /// - **Android:** Only available after receiving the Resumed event and before Suspended. *If you* - /// *try to get the handle outside of that period, this function will panic*! - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - self.window.raw_window_handle() +#[cfg(feature = "rwh_04")] +unsafe impl rwh_04::HasRawWindowHandle for Window { + fn raw_window_handle(&self) -> rwh_04::RawWindowHandle { + self.window.raw_window_handle_rwh_04() } } -unsafe impl HasRawDisplayHandle for Window { - /// Returns a [`raw_window_handle::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() +#[cfg(feature = "rwh_05")] +unsafe impl rwh_05::HasRawWindowHandle for Window { + fn raw_window_handle(&self) -> rwh_05::RawWindowHandle { + self.window.raw_window_handle_rwh_05() + } +} + +#[cfg(feature = "rwh_05")] +unsafe impl rwh_05::HasRawDisplayHandle for Window { + fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { + self.window.raw_display_handle_rwh_05() } } + +#[cfg(feature = "rwh_06")] +impl rwh_06::HasWindowHandle for Window { + fn window_handle(&self) -> Result, rwh_06::HandleError> { + let raw = self.window.raw_window_handle_rwh_06()?; + // SAFETY: The window handle will never be deallocated while the window is alive. + Ok(unsafe { rwh_06::WindowHandle::borrow_raw(raw) }) + } +} + +#[cfg(feature = "rwh_06")] +impl rwh_06::HasDisplayHandle for Window { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = self.window.raw_display_handle_rwh_06()?; + // SAFETY: The window handle will never be deallocated while the window is alive. + Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw) }) + } +} + /// Describes the appearance of the mouse cursor. #[non_exhaustive] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]