Skip to content

Commit

Permalink
Make winit work with objc2
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Sep 1, 2022
1 parent 091f026 commit da5fa93
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 207 deletions.
4 changes: 2 additions & 2 deletions src/platform_impl/ios/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::{
time::Instant,
};

use objc::runtime::{BOOL, YES};
use objc::runtime::{Object, BOOL, YES};
use once_cell::sync::Lazy;

use crate::{
Expand Down Expand Up @@ -582,7 +582,7 @@ pub unsafe fn did_finish_launching() {
let _: () = msg_send![window, setScreen: screen];
let _: () = msg_send![screen, release];
let controller: id = msg_send![window, rootViewController];
let _: () = msg_send![window, setRootViewController:ptr::null::<()>()];
let _: () = msg_send![window, setRootViewController:ptr::null::<Object>()];
let _: () = msg_send![window, setRootViewController: controller];
let _: () = msg_send![window, makeKeyAndVisible];
}
Expand Down
72 changes: 49 additions & 23 deletions src/platform_impl/ios/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,28 @@ pub struct NSOperatingSystemVersion {
pub patch: NSInteger,
}

unsafe impl Encode for NSOperatingSystemVersion {
const ENCODING: Encoding = Encoding::Struct(
"NSOperatingSystemVersion",
&[
NSInteger::ENCODING,
NSInteger::ENCODING,
NSInteger::ENCODING,
],
);
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct CGPoint {
pub x: CGFloat,
pub y: CGFloat,
}

unsafe impl Encode for CGPoint {
const ENCODING: Encoding = Encoding::Struct("CGPoint", &[CGFloat::ENCODING, CGFloat::ENCODING]);
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct CGSize {
Expand All @@ -51,6 +66,10 @@ impl CGSize {
}
}

unsafe impl Encode for CGSize {
const ENCODING: Encoding = Encoding::Struct("CGSize", &[CGFloat::ENCODING, CGFloat::ENCODING]);
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct CGRect {
Expand All @@ -65,18 +84,9 @@ impl CGRect {
}

unsafe impl Encode for CGRect {
fn encode() -> Encoding {
unsafe {
if cfg!(target_pointer_width = "32") {
Encoding::from_str("{CGRect={CGPoint=ff}{CGSize=ff}}")
} else if cfg!(target_pointer_width = "64") {
Encoding::from_str("{CGRect={CGPoint=dd}{CGSize=dd}}")
} else {
unimplemented!()
}
}
}
const ENCODING: Encoding = Encoding::Struct("CGRect", &[CGPoint::ENCODING, CGSize::ENCODING]);
}

#[derive(Debug)]
#[allow(dead_code)]
#[repr(isize)]
Expand All @@ -88,6 +98,10 @@ pub enum UITouchPhase {
Cancelled,
}

unsafe impl Encode for UITouchPhase {
const ENCODING: Encoding = NSInteger::ENCODING;
}

#[derive(Debug, PartialEq, Eq)]
#[allow(dead_code)]
#[repr(isize)]
Expand All @@ -97,6 +111,10 @@ pub enum UIForceTouchCapability {
Available,
}

unsafe impl Encode for UIForceTouchCapability {
const ENCODING: Encoding = NSInteger::ENCODING;
}

#[derive(Debug, PartialEq, Eq)]
#[allow(dead_code)]
#[repr(isize)]
Expand All @@ -106,6 +124,10 @@ pub enum UITouchType {
Pencil,
}

unsafe impl Encode for UITouchType {
const ENCODING: Encoding = NSInteger::ENCODING;
}

#[repr(C)]
#[derive(Debug, Clone)]
pub struct UIEdgeInsets {
Expand All @@ -115,14 +137,24 @@ pub struct UIEdgeInsets {
pub right: CGFloat,
}

unsafe impl Encode for UIEdgeInsets {
const ENCODING: Encoding = Encoding::Struct(
"UIEdgeInsets",
&[
CGFloat::ENCODING,
CGFloat::ENCODING,
CGFloat::ENCODING,
CGFloat::ENCODING,
],
);
}

#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct UIUserInterfaceIdiom(NSInteger);

unsafe impl Encode for UIUserInterfaceIdiom {
fn encode() -> Encoding {
NSInteger::encode()
}
const ENCODING: Encoding = NSInteger::ENCODING;
}

impl UIUserInterfaceIdiom {
Expand Down Expand Up @@ -162,9 +194,7 @@ impl From<UIUserInterfaceIdiom> for Idiom {
pub struct UIInterfaceOrientationMask(NSUInteger);

unsafe impl Encode for UIInterfaceOrientationMask {
fn encode() -> Encoding {
NSUInteger::encode()
}
const ENCODING: Encoding = NSUInteger::ENCODING;
}

impl UIInterfaceOrientationMask {
Expand Down Expand Up @@ -213,9 +243,7 @@ impl UIInterfaceOrientationMask {
pub struct UIRectEdge(NSUInteger);

unsafe impl Encode for UIRectEdge {
fn encode() -> Encoding {
NSUInteger::encode()
}
const ENCODING: Encoding = NSUInteger::ENCODING;
}

impl From<ScreenEdge> for UIRectEdge {
Expand All @@ -241,9 +269,7 @@ impl From<UIRectEdge> for ScreenEdge {
pub struct UIScreenOverscanCompensation(NSInteger);

unsafe impl Encode for UIScreenOverscanCompensation {
fn encode() -> Encoding {
NSInteger::encode()
}
const ENCODING: Encoding = NSInteger::ENCODING;
}

#[allow(dead_code)]
Expand Down
47 changes: 21 additions & 26 deletions src/platform_impl/ios/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ macro_rules! add_property {
}
$decl.add_method(
sel!($setter_name:),
setter as extern "C" fn(&mut Object, Sel, $t),
setter as extern "C" fn(_, _, _),
);
$decl.add_method(
sel!($getter_name),
$getter_name as extern "C" fn(&Object, Sel) -> $t,
$getter_name as extern "C" fn(_, _) -> _,
);
}
};
Expand Down Expand Up @@ -156,11 +156,12 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
untrusted_scale_factor: CGFloat,
) {
unsafe {
let superclass: &'static Class = msg_send![object, superclass];
let superclass: &'static Class = msg_send![&*object, superclass];
let _: () = msg_send![
super(object, superclass),
super(&mut *object, superclass),
setContentScaleFactor: untrusted_scale_factor
];
let object = &*object; // Immutable for rest of method

let window: id = msg_send![object, window];
// `window` is null when `setContentScaleFactor` is invoked prior to `[UIWindow
Expand Down Expand Up @@ -283,34 +284,28 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
let mut decl = ClassDecl::new(&format!("WinitUIView{}", ID), root_view_class)
.expect("Failed to declare class `WinitUIView`");
ID += 1;
decl.add_method(
sel!(drawRect:),
draw_rect as extern "C" fn(&Object, Sel, CGRect),
);
decl.add_method(
sel!(layoutSubviews),
layout_subviews as extern "C" fn(&Object, Sel),
);
decl.add_method(sel!(drawRect:), draw_rect as extern "C" fn(_, _, _));
decl.add_method(sel!(layoutSubviews), layout_subviews as extern "C" fn(_, _));
decl.add_method(
sel!(setContentScaleFactor:),
set_content_scale_factor as extern "C" fn(&mut Object, Sel, CGFloat),
set_content_scale_factor as extern "C" fn(_, _, _),
);

decl.add_method(
sel!(touchesBegan:withEvent:),
handle_touches as extern "C" fn(this: &Object, _: Sel, _: id, _: id),
handle_touches as extern "C" fn(_, _, _, _),
);
decl.add_method(
sel!(touchesMoved:withEvent:),
handle_touches as extern "C" fn(this: &Object, _: Sel, _: id, _: id),
handle_touches as extern "C" fn(_, _, _, _),
);
decl.add_method(
sel!(touchesEnded:withEvent:),
handle_touches as extern "C" fn(this: &Object, _: Sel, _: id, _: id),
handle_touches as extern "C" fn(_, _, _, _),
);
decl.add_method(
sel!(touchesCancelled:withEvent:),
handle_touches as extern "C" fn(this: &Object, _: Sel, _: id, _: id),
handle_touches as extern "C" fn(_, _, _, _),
);

decl.register()
Expand All @@ -333,7 +328,7 @@ unsafe fn get_view_controller_class() -> &'static Class {
.expect("Failed to declare class `WinitUIViewController`");
decl.add_method(
sel!(shouldAutorotate),
should_autorotate as extern "C" fn(&Object, Sel) -> BOOL,
should_autorotate as extern "C" fn(_, _) -> _,
);
add_property! {
decl,
Expand Down Expand Up @@ -416,11 +411,11 @@ unsafe fn get_window_class() -> &'static Class {
.expect("Failed to declare class `WinitUIWindow`");
decl.add_method(
sel!(becomeKeyWindow),
become_key_window as extern "C" fn(&Object, Sel),
become_key_window as extern "C" fn(_, _),
);
decl.add_method(
sel!(resignKeyWindow),
resign_key_window as extern "C" fn(&Object, Sel),
resign_key_window as extern "C" fn(_, _),
);

CLASS = Some(decl.register());
Expand Down Expand Up @@ -594,29 +589,29 @@ pub fn create_delegate_class() {
unsafe {
decl.add_method(
sel!(application:didFinishLaunchingWithOptions:),
did_finish_launching as extern "C" fn(&mut Object, Sel, id, id) -> BOOL,
did_finish_launching as extern "C" fn(_, _, _, _) -> _,
);

decl.add_method(
sel!(applicationDidBecomeActive:),
did_become_active as extern "C" fn(&Object, Sel, id),
did_become_active as extern "C" fn(_, _, _),
);
decl.add_method(
sel!(applicationWillResignActive:),
will_resign_active as extern "C" fn(&Object, Sel, id),
will_resign_active as extern "C" fn(_, _, _),
);
decl.add_method(
sel!(applicationWillEnterForeground:),
will_enter_foreground as extern "C" fn(&Object, Sel, id),
will_enter_foreground as extern "C" fn(_, _, _),
);
decl.add_method(
sel!(applicationDidEnterBackground:),
did_enter_background as extern "C" fn(&Object, Sel, id),
did_enter_background as extern "C" fn(_, _, _),
);

decl.add_method(
sel!(applicationWillTerminate:),
will_terminate as extern "C" fn(&Object, Sel, id),
will_terminate as extern "C" fn(_, _, _),
);

decl.register();
Expand Down
5 changes: 1 addition & 4 deletions src/platform_impl/macos/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ pub static APP_CLASS: Lazy<AppClass> = Lazy::new(|| unsafe {
let superclass = class!(NSApplication);
let mut decl = ClassDecl::new("WinitApp", superclass).unwrap();

decl.add_method(
sel!(sendEvent:),
send_event as extern "C" fn(&Object, Sel, id),
);
decl.add_method(sel!(sendEvent:), send_event as extern "C" fn(_, _, _));

AppClass(decl.register())
});
Expand Down
8 changes: 4 additions & 4 deletions src/platform_impl/macos/app_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ pub static APP_DELEGATE_CLASS: Lazy<AppDelegateClass> = Lazy::new(|| unsafe {
let superclass = class!(NSResponder);
let mut decl = ClassDecl::new("WinitAppDelegate", superclass).unwrap();

decl.add_class_method(sel!(new), new as extern "C" fn(&Class, Sel) -> id);
decl.add_method(sel!(dealloc), dealloc as extern "C" fn(&Object, Sel));
decl.add_class_method(sel!(new), new as extern "C" fn(_, _) -> _);
decl.add_method(sel!(dealloc), dealloc as extern "C" fn(_, _));

decl.add_method(
sel!(applicationDidFinishLaunching:),
did_finish_launching as extern "C" fn(&Object, Sel, id),
did_finish_launching as extern "C" fn(_, _, _),
);
decl.add_method(
sel!(applicationWillTerminate:),
will_terminate as extern "C" fn(&Object, Sel, id),
will_terminate as extern "C" fn(_, _, _),
);

decl.add_ivar::<*mut c_void>(AUX_DELEGATE_STATE_NAME);
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/macos/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ impl AppState {
unsafe {
let app: id = NSApp();

autoreleasepool(|| {
autoreleasepool(|_| {
let _: () = msg_send![app, stop: nil];
// To stop event loop immediately, we need to post some event here.
post_dummy_event(app);
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/macos/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ impl<T> EventLoop<T> {
aux_state.activation_policy = attributes.activation_policy;
aux_state.default_menu = attributes.default_menu;

autoreleasepool(|| {
autoreleasepool(|_| {
let _: () = msg_send![app, setDelegate:*delegate];
});

Expand Down Expand Up @@ -209,7 +209,7 @@ impl<T> EventLoop<T> {

self._callback = Some(Rc::clone(&callback));

let exit_code = autoreleasepool(|| unsafe {
let exit_code = autoreleasepool(|_| unsafe {
let app = NSApp();
assert_ne!(app, nil);

Expand Down
25 changes: 0 additions & 25 deletions src/platform_impl/macos/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,6 @@ use core_graphics::{

pub const NSNotFound: NSInteger = NSInteger::max_value();

#[repr(C)]
pub struct NSRange {
pub location: NSUInteger,
pub length: NSUInteger,
}

impl NSRange {
#[inline]
pub fn new(location: NSUInteger, length: NSUInteger) -> NSRange {
NSRange { location, length }
}
}

unsafe impl objc::Encode for NSRange {
fn encode() -> objc::Encoding {
let encoding = format!(
// TODO: Verify that this is correct
"{{NSRange={}{}}}",
NSUInteger::encode().as_str(),
NSUInteger::encode().as_str(),
);
unsafe { objc::Encoding::from_str(&encoding) }
}
}

pub trait NSMutableAttributedString: Sized {
unsafe fn alloc(_: Self) -> id {
msg_send![class!(NSMutableAttributedString), alloc]
Expand Down
Loading

0 comments on commit da5fa93

Please sign in to comment.