mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
Use a bit less unsafe
on iOS (#2643)
* Use a bit less `unsafe` on iOS I did test this in XCode 11.3's "Debug View Heirarchy", the NSStringRust problem is no longer applicable (likely because Rust got better at emitting correct debug info). * Avoid using `id` on iOS
This commit is contained in:
parent
0f2fbe373b
commit
a82f66826b
|
@ -99,17 +99,17 @@ pub trait WindowExtIOS {
|
||||||
impl WindowExtIOS for Window {
|
impl WindowExtIOS for Window {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ui_window(&self) -> *mut c_void {
|
fn ui_window(&self) -> *mut c_void {
|
||||||
self.window.ui_window() as _
|
self.window.ui_window()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ui_view_controller(&self) -> *mut c_void {
|
fn ui_view_controller(&self) -> *mut c_void {
|
||||||
self.window.ui_view_controller() as _
|
self.window.ui_view_controller()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ui_view(&self) -> *mut c_void {
|
fn ui_view(&self) -> *mut c_void {
|
||||||
self.window.ui_view() as _
|
self.window.ui_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -15,11 +15,13 @@ use core_foundation::runloop::{
|
||||||
kCFRunLoopCommonModes, CFRunLoopAddTimer, CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate,
|
kCFRunLoopCommonModes, CFRunLoopAddTimer, CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate,
|
||||||
CFRunLoopTimerInvalidate, CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate,
|
CFRunLoopTimerInvalidate, CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate,
|
||||||
};
|
};
|
||||||
use objc2::foundation::{CGRect, CGSize, NSInteger};
|
use objc2::foundation::{CGRect, CGSize, NSInteger, NSProcessInfo};
|
||||||
use objc2::rc::{Id, Shared};
|
use objc2::rc::{Id, Shared};
|
||||||
use objc2::{class, msg_send, sel};
|
use objc2::runtime::Object;
|
||||||
|
use objc2::{msg_send, sel};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
|
use super::uikit::UIView;
|
||||||
use super::view::WinitUIWindow;
|
use super::view::WinitUIWindow;
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::LogicalSize,
|
dpi::LogicalSize,
|
||||||
|
@ -27,7 +29,7 @@ use crate::{
|
||||||
event_loop::ControlFlow,
|
event_loop::ControlFlow,
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
event_loop::{EventHandler, EventProxy, EventWrapper, Never},
|
event_loop::{EventHandler, EventProxy, EventWrapper, Never},
|
||||||
ffi::{id, NSOperatingSystemVersion},
|
ffi::NSOperatingSystemVersion,
|
||||||
},
|
},
|
||||||
window::WindowId as RootWindowId,
|
window::WindowId as RootWindowId,
|
||||||
};
|
};
|
||||||
|
@ -542,7 +544,7 @@ pub unsafe fn did_finish_launching() {
|
||||||
// completed. This may result in incorrect visual appearance.
|
// completed. This may result in incorrect visual appearance.
|
||||||
// ```
|
// ```
|
||||||
let screen = window.screen();
|
let screen = window.screen();
|
||||||
let _: () = msg_send![&window, setScreen: 0 as id];
|
let _: () = msg_send![&window, setScreen: ptr::null::<Object>()];
|
||||||
window.setScreen(&screen);
|
window.setScreen(&screen);
|
||||||
|
|
||||||
let controller = window.rootViewController();
|
let controller = window.rootViewController();
|
||||||
|
@ -830,14 +832,12 @@ fn handle_hidpi_proxy(
|
||||||
let logical_size = physical_size.to_logical(scale_factor);
|
let logical_size = physical_size.to_logical(scale_factor);
|
||||||
let size = CGSize::new(logical_size.width, logical_size.height);
|
let size = CGSize::new(logical_size.width, logical_size.height);
|
||||||
let new_frame: CGRect = CGRect::new(screen_frame.origin, size);
|
let new_frame: CGRect = CGRect::new(screen_frame.origin, size);
|
||||||
unsafe {
|
view.setFrame(new_frame);
|
||||||
let _: () = msg_send![view, setFrame: new_frame];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_view_and_screen_frame(window: &WinitUIWindow) -> (id, CGRect) {
|
fn get_view_and_screen_frame(window: &WinitUIWindow) -> (Id<UIView, Shared>, CGRect) {
|
||||||
let view_controller = window.rootViewController().unwrap();
|
let view_controller = window.rootViewController().unwrap();
|
||||||
let view: id = unsafe { msg_send![&view_controller, view] };
|
let view = view_controller.view().unwrap();
|
||||||
let bounds = window.bounds();
|
let bounds = window.bounds();
|
||||||
let screen = window.screen();
|
let screen = window.screen();
|
||||||
let screen_space = screen.coordinateSpace();
|
let screen_space = screen.coordinateSpace();
|
||||||
|
@ -971,9 +971,9 @@ impl NSOperatingSystemVersion {
|
||||||
pub fn os_capabilities() -> OSCapabilities {
|
pub fn os_capabilities() -> OSCapabilities {
|
||||||
static OS_CAPABILITIES: Lazy<OSCapabilities> = Lazy::new(|| {
|
static OS_CAPABILITIES: Lazy<OSCapabilities> = Lazy::new(|| {
|
||||||
let version: NSOperatingSystemVersion = unsafe {
|
let version: NSOperatingSystemVersion = unsafe {
|
||||||
let process_info: id = msg_send![class!(NSProcessInfo), processInfo];
|
let process_info = NSProcessInfo::process_info();
|
||||||
let atleast_ios_8: bool = msg_send![
|
let atleast_ios_8: bool = msg_send![
|
||||||
process_info,
|
&process_info,
|
||||||
respondsToSelector: sel!(operatingSystemVersion)
|
respondsToSelector: sel!(operatingSystemVersion)
|
||||||
];
|
];
|
||||||
// winit requires atleast iOS 8 because no one has put the time into supporting earlier os versions.
|
// winit requires atleast iOS 8 because no one has put the time into supporting earlier os versions.
|
||||||
|
@ -984,7 +984,7 @@ pub fn os_capabilities() -> OSCapabilities {
|
||||||
//
|
//
|
||||||
// The minimum required iOS version is likely to grow in the future.
|
// The minimum required iOS version is likely to grow in the future.
|
||||||
assert!(atleast_ios_8, "`winit` requires iOS version 8 or greater");
|
assert!(atleast_ios_8, "`winit` requires iOS version 8 or greater");
|
||||||
msg_send![process_info, operatingSystemVersion]
|
msg_send![&process_info, operatingSystemVersion]
|
||||||
};
|
};
|
||||||
version.into()
|
version.into()
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,13 +14,14 @@ use core_foundation::runloop::{
|
||||||
CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext, CFRunLoopSourceCreate,
|
CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext, CFRunLoopSourceCreate,
|
||||||
CFRunLoopSourceInvalidate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp,
|
CFRunLoopSourceInvalidate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp,
|
||||||
};
|
};
|
||||||
use objc2::foundation::MainThreadMarker;
|
use objc2::foundation::{MainThreadMarker, NSString};
|
||||||
use objc2::rc::{Id, Shared};
|
use objc2::rc::{Id, Shared};
|
||||||
use objc2::ClassType;
|
use objc2::ClassType;
|
||||||
use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle};
|
use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle};
|
||||||
|
|
||||||
use super::uikit::{UIApplication, UIDevice, UIScreen};
|
use super::uikit::{UIApplication, UIApplicationMain, UIDevice, UIScreen};
|
||||||
use super::view::WinitUIWindow;
|
use super::view::WinitUIWindow;
|
||||||
|
use super::{app_state, monitor, view, MonitorHandle};
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::LogicalSize,
|
dpi::LogicalSize,
|
||||||
event::Event,
|
event::Event,
|
||||||
|
@ -30,12 +31,6 @@ use crate::{
|
||||||
platform::ios::Idiom,
|
platform::ios::Idiom,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::platform_impl::platform::{
|
|
||||||
app_state,
|
|
||||||
ffi::{nil, NSStringRust, UIApplicationMain},
|
|
||||||
monitor, view, MonitorHandle,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum EventWrapper {
|
pub(crate) enum EventWrapper {
|
||||||
StaticEvent(Event<'static, Never>),
|
StaticEvent(Event<'static, Never>),
|
||||||
|
@ -132,8 +127,8 @@ impl<T: 'static> EventLoop<T> {
|
||||||
UIApplicationMain(
|
UIApplicationMain(
|
||||||
0,
|
0,
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
nil,
|
None,
|
||||||
NSStringRust::alloc(nil).init_str("WinitApplicationDelegate"),
|
Some(&NSString::from_str("WinitApplicationDelegate")),
|
||||||
);
|
);
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,12 @@
|
||||||
#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
|
#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
|
||||||
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::CString;
|
|
||||||
use std::os::raw::{c_char, c_int};
|
|
||||||
|
|
||||||
use objc2::encode::{Encode, Encoding};
|
use objc2::encode::{Encode, Encoding};
|
||||||
use objc2::foundation::{NSInteger, NSUInteger};
|
use objc2::foundation::{NSInteger, NSUInteger};
|
||||||
use objc2::runtime::Object;
|
|
||||||
use objc2::{class, msg_send};
|
|
||||||
|
|
||||||
use crate::platform::ios::{Idiom, ScreenEdge};
|
use crate::platform::ios::{Idiom, ScreenEdge};
|
||||||
|
|
||||||
pub type id = *mut Object;
|
|
||||||
pub const nil: id = 0 as id;
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct NSOperatingSystemVersion {
|
pub struct NSOperatingSystemVersion {
|
||||||
|
@ -98,46 +91,3 @@ impl From<UIRectEdge> for ScreenEdge {
|
||||||
ScreenEdge::from_bits(bits).expect("invalid `ScreenEdge`")
|
ScreenEdge::from_bits(bits).expect("invalid `ScreenEdge`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[link(name = "UIKit", kind = "framework")]
|
|
||||||
extern "C" {
|
|
||||||
pub fn UIApplicationMain(
|
|
||||||
argc: c_int,
|
|
||||||
argv: *const c_char,
|
|
||||||
principalClassName: id,
|
|
||||||
delegateClassName: id,
|
|
||||||
) -> c_int;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is named NSStringRust rather than NSString because the "Debug View Heirarchy" feature of
|
|
||||||
// Xcode requires a non-ambiguous reference to NSString for unclear reasons. This makes Xcode happy
|
|
||||||
// so please test if you change the name back to NSString.
|
|
||||||
pub trait NSStringRust: Sized {
|
|
||||||
unsafe fn alloc(_: Self) -> id {
|
|
||||||
msg_send![class!(NSString), alloc]
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn initWithUTF8String_(self, c_string: *const c_char) -> id;
|
|
||||||
unsafe fn stringByAppendingString_(self, other: id) -> id;
|
|
||||||
unsafe fn init_str(self, string: &str) -> Self;
|
|
||||||
unsafe fn UTF8String(self) -> *const c_char;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NSStringRust for id {
|
|
||||||
unsafe fn initWithUTF8String_(self, c_string: *const c_char) -> id {
|
|
||||||
msg_send![self, initWithUTF8String: c_string]
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn stringByAppendingString_(self, other: id) -> id {
|
|
||||||
msg_send![self, stringByAppendingString: other]
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn init_str(self, string: &str) -> id {
|
|
||||||
let cstring = CString::new(string).unwrap();
|
|
||||||
self.initWithUTF8String_(cstring.as_ptr())
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn UTF8String(self) -> *const c_char {
|
|
||||||
msg_send![self, UTF8String]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
|
use std::os::raw::{c_char, c_int};
|
||||||
|
|
||||||
|
use objc2::foundation::NSString;
|
||||||
|
|
||||||
mod application;
|
mod application;
|
||||||
mod coordinate_space;
|
mod coordinate_space;
|
||||||
mod device;
|
mod device;
|
||||||
|
@ -28,3 +32,13 @@ pub(crate) use self::trait_collection::{UIForceTouchCapability, UITraitCollectio
|
||||||
pub(crate) use self::view::{UIEdgeInsets, UIView};
|
pub(crate) use self::view::{UIEdgeInsets, UIView};
|
||||||
pub(crate) use self::view_controller::{UIInterfaceOrientationMask, UIViewController};
|
pub(crate) use self::view_controller::{UIInterfaceOrientationMask, UIViewController};
|
||||||
pub(crate) use self::window::UIWindow;
|
pub(crate) use self::window::UIWindow;
|
||||||
|
|
||||||
|
#[link(name = "UIKit", kind = "framework")]
|
||||||
|
extern "C" {
|
||||||
|
pub fn UIApplicationMain(
|
||||||
|
argc: c_int,
|
||||||
|
argv: *const c_char,
|
||||||
|
principalClassName: Option<&NSString>,
|
||||||
|
delegateClassName: Option<&NSString>,
|
||||||
|
) -> c_int;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
use objc2::encode::{Encode, Encoding};
|
||||||
use objc2::foundation::{NSObject, NSUInteger};
|
use objc2::foundation::{NSObject, NSUInteger};
|
||||||
use objc2::{extern_class, extern_methods, ClassType};
|
use objc2::rc::{Id, Shared};
|
||||||
|
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||||
|
|
||||||
use super::{UIResponder, UIView};
|
use super::{UIResponder, UIView};
|
||||||
|
|
||||||
|
@ -28,6 +29,10 @@ extern_methods!(
|
||||||
#[sel(setNeedsUpdateOfScreenEdgesDeferringSystemGestures)]
|
#[sel(setNeedsUpdateOfScreenEdgesDeferringSystemGestures)]
|
||||||
pub fn setNeedsUpdateOfScreenEdgesDeferringSystemGestures(&self);
|
pub fn setNeedsUpdateOfScreenEdgesDeferringSystemGestures(&self);
|
||||||
|
|
||||||
|
pub fn view(&self) -> Option<Id<UIView, Shared>> {
|
||||||
|
unsafe { msg_send_id![self, view] }
|
||||||
|
}
|
||||||
|
|
||||||
#[sel(setView:)]
|
#[sel(setView:)]
|
||||||
pub fn setView(&self, view: Option<&UIView>);
|
pub fn setView(&self, view: Option<&UIView>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::{
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
app_state,
|
app_state,
|
||||||
event_loop::{EventProxy, EventWrapper},
|
event_loop::{EventProxy, EventWrapper},
|
||||||
ffi::{id, UIRectEdge, UIUserInterfaceIdiom},
|
ffi::{UIRectEdge, UIUserInterfaceIdiom},
|
||||||
window::PlatformSpecificWindowBuilderAttributes,
|
window::PlatformSpecificWindowBuilderAttributes,
|
||||||
DeviceId, Fullscreen,
|
DeviceId, Fullscreen,
|
||||||
},
|
},
|
||||||
|
@ -487,7 +487,7 @@ declare_class!(
|
||||||
// UIApplicationDelegate protocol
|
// UIApplicationDelegate protocol
|
||||||
unsafe impl WinitApplicationDelegate {
|
unsafe impl WinitApplicationDelegate {
|
||||||
#[sel(application:didFinishLaunchingWithOptions:)]
|
#[sel(application:didFinishLaunchingWithOptions:)]
|
||||||
fn did_finish_launching(&self, _application: &UIApplication, _: id) -> bool {
|
fn did_finish_launching(&self, _application: &UIApplication, _: *mut NSObject) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
app_state::did_finish_launching();
|
app_state::did_finish_launching();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
|
ffi::c_void,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ use crate::{
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
app_state,
|
app_state,
|
||||||
event_loop::{EventProxy, EventWrapper},
|
event_loop::{EventProxy, EventWrapper},
|
||||||
ffi::{id, UIRectEdge},
|
ffi::UIRectEdge,
|
||||||
monitor, EventLoopWindowTarget, Fullscreen, MonitorHandle,
|
monitor, EventLoopWindowTarget, Fullscreen, MonitorHandle,
|
||||||
},
|
},
|
||||||
window::{
|
window::{
|
||||||
|
@ -503,14 +504,14 @@ impl Window {
|
||||||
|
|
||||||
// WindowExtIOS
|
// WindowExtIOS
|
||||||
impl Inner {
|
impl Inner {
|
||||||
pub fn ui_window(&self) -> id {
|
pub fn ui_window(&self) -> *mut c_void {
|
||||||
Id::as_ptr(&self.window) as id
|
Id::as_ptr(&self.window) as *mut c_void
|
||||||
}
|
}
|
||||||
pub fn ui_view_controller(&self) -> id {
|
pub fn ui_view_controller(&self) -> *mut c_void {
|
||||||
Id::as_ptr(&self.view_controller) as id
|
Id::as_ptr(&self.view_controller) as *mut c_void
|
||||||
}
|
}
|
||||||
pub fn ui_view(&self) -> id {
|
pub fn ui_view(&self) -> *mut c_void {
|
||||||
Id::as_ptr(&self.view) as id
|
Id::as_ptr(&self.view) as *mut c_void
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_scale_factor(&self, scale_factor: f64) {
|
pub fn set_scale_factor(&self, scale_factor: f64) {
|
||||||
|
@ -613,7 +614,7 @@ impl Inner {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct WindowId {
|
pub struct WindowId {
|
||||||
window: id,
|
window: *mut WinitUIWindow,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowId {
|
impl WindowId {
|
||||||
|
@ -649,20 +650,6 @@ impl From<&Object> for WindowId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&mut Object> for WindowId {
|
|
||||||
fn from(window: &mut Object) -> WindowId {
|
|
||||||
WindowId {
|
|
||||||
window: window as _,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<id> for WindowId {
|
|
||||||
fn from(window: id) -> WindowId {
|
|
||||||
WindowId { window }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct PlatformSpecificWindowBuilderAttributes {
|
pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
pub scale_factor: Option<f64>,
|
pub scale_factor: Option<f64>,
|
||||||
|
|
Loading…
Reference in a new issue