Skip to content

Commit

Permalink
Use objc2
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Jan 21, 2025
1 parent 68f0f99 commit 1f416fd
Show file tree
Hide file tree
Showing 29 changed files with 1,039 additions and 1,102 deletions.
5 changes: 5 additions & 0 deletions .changes/objc2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
tao: patch
---

Use `objc2`.
35 changes: 33 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,41 @@ ndk-context = "0.1"
tao-macros = { version = "0.1.0", path = "./tao-macros" }

[target."cfg(any(target_os = \"ios\", target_os = \"macos\"))".dependencies]
objc = "0.2"
objc2 = "0.5"

[target."cfg(target_os = \"macos\")".dependencies]
cocoa = "0.26"
objc2-foundation = { version = "0.2", default-features = false, features = [
"std",
"NSArray",
"NSAttributedString",
"NSAutoreleasePool",
"NSDate",
"NSDictionary",
"NSEnumerator",
"NSGeometry",
"NSObjCRuntime",
"NSRange",
"NSString",
"NSThread",
"NSURL",
] }
objc2-app-kit = { version = "0.2", default-features = false, features = [
"std",
"NSApplication",
"NSButton",
"NSColor",
"NSControl",
"NSEvent",
"NSGraphics",
"NSImage",
"NSOpenGLView",
"NSPasteboard",
"NSResponder",
"NSRunningApplication",
"NSScreen",
"NSView",
"NSWindow",
] }
core-foundation = "0.10"
core-graphics = "0.24"
dispatch = "0.2"
Expand Down
3 changes: 1 addition & 2 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
//! describes what happens in what order.
//!
//! [event_loop_run]: crate::event_loop::EventLoop::run
use std::path::PathBuf;
use std::time::Instant;
use std::{path::PathBuf, time::Instant};

use crate::{
dpi::{PhysicalPosition, PhysicalSize},
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ extern crate serde;
#[macro_use]
extern crate bitflags;
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[macro_use]
extern crate objc;
#[macro_use(class, msg_send, sel)]
extern crate objc2;

pub use dpi;

Expand Down
38 changes: 20 additions & 18 deletions src/platform/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,10 @@ impl MonitorHandleExtMacOS for MonitorHandle {
}

fn ns_screen(&self) -> Option<*mut c_void> {
self.inner.ns_screen().map(|s| s as *mut c_void)
self
.inner
.ns_screen()
.map(|s| objc2::rc::Retained::into_raw(s) as *mut c_void)
}
}

Expand All @@ -388,36 +391,35 @@ pub trait EventLoopWindowTargetExtMacOS {

impl<T> EventLoopWindowTargetExtMacOS for EventLoopWindowTarget<T> {
fn hide_application(&self) {
let cls = objc::runtime::Class::get("NSApplication").unwrap();
let app: cocoa::base::id = unsafe { msg_send![cls, sharedApplication] };
unsafe { msg_send![app, hide: 0] }
// TODO: Safety.
let mtm = unsafe { objc2_foundation::MainThreadMarker::new_unchecked() };
objc2_app_kit::NSApplication::sharedApplication(mtm).hide(None)
}

fn show_application(&self) {
let cls = objc::runtime::Class::get("NSApplication").unwrap();
let app: cocoa::base::id = unsafe { msg_send![cls, sharedApplication] };
unsafe { msg_send![app, unhide: 0] }
// TODO: Safety.
let mtm = unsafe { objc2_foundation::MainThreadMarker::new_unchecked() };
unsafe { objc2_app_kit::NSApplication::sharedApplication(mtm).unhide(None) }
}

fn hide_other_applications(&self) {
let cls = objc::runtime::Class::get("NSApplication").unwrap();
let app: cocoa::base::id = unsafe { msg_send![cls, sharedApplication] };
unsafe { msg_send![app, hideOtherApplications: 0] }
// TODO: Safety.
let mtm = unsafe { objc2_foundation::MainThreadMarker::new_unchecked() };
objc2_app_kit::NSApplication::sharedApplication(mtm).hideOtherApplications(None)
}

fn set_activation_policy_at_runtime(&self, activation_policy: ActivationPolicy) {
use cocoa::appkit;

let cls = objc::runtime::Class::get("NSApplication").unwrap();
let app: cocoa::base::id = unsafe { msg_send![cls, sharedApplication] };
use objc2_app_kit::NSApplicationActivationPolicy;

let ns_activation_policy = match activation_policy {
ActivationPolicy::Regular => appkit::NSApplicationActivationPolicyRegular,
ActivationPolicy::Accessory => appkit::NSApplicationActivationPolicyAccessory,
ActivationPolicy::Prohibited => appkit::NSApplicationActivationPolicyProhibited,
ActivationPolicy::Regular => NSApplicationActivationPolicy::Regular,
ActivationPolicy::Accessory => NSApplicationActivationPolicy::Accessory,
ActivationPolicy::Prohibited => NSApplicationActivationPolicy::Prohibited,
};

unsafe { msg_send![app, setActivationPolicy: ns_activation_policy] }
// TODO: Safety.
let mtm = unsafe { objc2_foundation::MainThreadMarker::new_unchecked() };
objc2_app_kit::NSApplication::sharedApplication(mtm).setActivationPolicy(ns_activation_policy);
}

fn set_badge_label(&self, label: Option<String>) {
Expand Down
18 changes: 6 additions & 12 deletions src/platform_impl/ios/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::{
time::Instant,
};

use objc::runtime::{BOOL, YES};
use objc2::runtime::AnyObject;

use crate::{
dpi::LogicalSize,
Expand Down Expand Up @@ -475,10 +475,7 @@ impl AppState {
// retains window
pub unsafe fn set_key_window(window: id) {
bug_assert!(
{
let is_window: BOOL = msg_send![window, isKindOfClass: class!(UIWindow)];
is_window == YES
},
msg_send![window, isKindOfClass: class!(UIWindow)],
"set_key_window called with an incorrect type"
);
let mut this = AppState::get_mut();
Expand All @@ -505,10 +502,7 @@ pub unsafe fn set_key_window(window: id) {
// retains window
pub unsafe fn queue_gl_or_metal_redraw(window: id) {
bug_assert!(
{
let is_window: BOOL = msg_send![window, isKindOfClass: class!(UIWindow)];
is_window == YES
},
msg_send![window, isKindOfClass: class!(UIWindow)],
"set_key_window called with an incorrect type"
);
let mut this = AppState::get_mut();
Expand Down Expand Up @@ -582,7 +576,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::<AnyObject>()];
let () = msg_send![window, setRootViewController: controller];
let () = msg_send![window, makeKeyAndVisible];
}
Expand Down Expand Up @@ -1019,7 +1013,7 @@ pub fn os_capabilities() -> OSCapabilities {
static ref OS_CAPABILITIES: OSCapabilities = {
let version: NSOperatingSystemVersion = unsafe {
let process_info: id = msg_send![class!(NSProcessInfo), processInfo];
let atleast_ios_8: BOOL = msg_send![
let atleast_ios_8: bool = msg_send![
process_info,
respondsToSelector: sel!(operatingSystemVersion)
];
Expand All @@ -1031,7 +1025,7 @@ pub fn os_capabilities() -> OSCapabilities {
//
// The minimum required iOS version is likely to grow in the future.
assert!(
atleast_ios_8 == YES,
atleast_ios_8,
"`tao` requires iOS version 8 or greater"
);
msg_send![process_info, operatingSystemVersion]
Expand Down
10 changes: 6 additions & 4 deletions src/platform_impl/ios/badge.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use objc::runtime::{Class, Object};
use objc::{msg_send, sel, sel_impl};
use objc2::{
msg_send,
runtime::{AnyClass, AnyObject},
};

pub fn set_badge_count(count: i32) {
unsafe {
let ui_application = Class::get("UIApplication").expect("Failed to get UIApplication class");
let app: *mut Object = msg_send![ui_application, sharedApplication];
let ui_application = AnyClass::get("UIApplication").expect("Failed to get UIApplication class");
let app: *mut AnyObject = msg_send![ui_application, sharedApplication];
let _: () = msg_send![app, setApplicationIconBadgeNumber:count];
}
}
2 changes: 1 addition & 1 deletion src/platform_impl/ios/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl<T: 'static> EventLoop<T> {
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{
unsafe {
let application: *mut c_void = msg_send![class!(UIApplication), sharedApplication];
let application: id = msg_send![class!(UIApplication), sharedApplication];
assert_eq!(
application,
ptr::null_mut(),
Expand Down
Loading

0 comments on commit 1f416fd

Please sign in to comment.