Skip to content

Commit bc4804d

Browse files
madsmtmlucasfernog
andauthored
feat: Migrate to objc2 (#10924)
* Migrate from objc/cocoa to objc2 * Update crates/tauri-runtime-wry/src/webview.rs --------- Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.app>
1 parent 63264a2 commit bc4804d

12 files changed

Lines changed: 114 additions & 79 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri": minor:breaking
3+
"tauri-runtime-wry": minor:breaking
4+
---
5+
6+
Change the pointer type of `PlatformWebview`'s `inner`, `controller`, `ns_window` and `view_controller` to `c_void`, to avoid publically depending on `objc`.

.changes/use-objc2.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri": patch:enhance
3+
"tauri-runtime-wry": patch:enhance
4+
---
5+
6+
Use `objc2` internally and in examples, leading to better memory safety.

Cargo.lock

Lines changed: 20 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tauri-runtime-wry/Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,14 @@ gtk = { version = "0.18", features = ["v3_24"] }
4545
webkit2gtk = { version = "=2.0", features = ["v2_40"] }
4646
percent-encoding = "2.1"
4747

48-
[target."cfg(any(target_os = \"ios\", target_os = \"macos\"))".dependencies]
49-
cocoa = "0.26"
48+
[target.'cfg(target_os = "macos")'.dependencies]
49+
objc2 = "0.5.2"
50+
objc2-foundation = { version = "0.2.2", features = [] }
51+
objc2-app-kit = { version = "0.2.2", features = [
52+
"NSResponder",
53+
"NSView",
54+
"NSWindow",
55+
] }
5056

5157
[target."cfg(target_os = \"android\")".dependencies]
5258
jni = "0.21"

crates/tauri-runtime-wry/src/lib.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2820,9 +2820,8 @@ fn handle_user_message<T: UserEvent>(
28202820

28212821
#[cfg(target_os = "macos")]
28222822
{
2823-
use cocoa::{appkit::NSWindow, base::id};
2824-
let ns_window: id = window.ns_window() as _;
2825-
unsafe { ns_window.center() };
2823+
let ns_window: &objc2_app_kit::NSWindow = unsafe { &*window.ns_window().cast() };
2824+
ns_window.center();
28262825
}
28272826
}
28282827
WindowMessage::RequestUserAttention(request_type) => {
@@ -3239,9 +3238,9 @@ fn handle_user_message<T: UserEvent>(
32393238
{
32403239
use wry::WebViewExtMacOS;
32413240
f(Webview {
3242-
webview: webview.webview(),
3243-
manager: webview.manager(),
3244-
ns_window: webview.ns_window(),
3241+
webview: webview.webview().cast(),
3242+
manager: webview.manager().cast(),
3243+
ns_window: webview.ns_window().cast(),
32453244
});
32463245
}
32473246
#[cfg(target_os = "ios")]
@@ -3250,9 +3249,9 @@ fn handle_user_message<T: UserEvent>(
32503249
use wry::WebViewExtIOS;
32513250

32523251
f(Webview {
3253-
webview: webview.inner.webview(),
3254-
manager: webview.inner.manager(),
3255-
view_controller: window.ui_view_controller() as cocoa::base::id,
3252+
webview: webview.inner.webview().cast(),
3253+
manager: webview.inner.manager().cast(),
3254+
view_controller: window.ui_view_controller().cast(),
32563255
});
32573256
}
32583257
#[cfg(windows)]
@@ -4259,7 +4258,8 @@ fn inner_size(
42594258
if !has_children && !webviews.is_empty() {
42604259
use wry::WebViewExtMacOS;
42614260
let webview = webviews.first().unwrap();
4262-
let view_frame = unsafe { cocoa::appkit::NSView::frame(webview.webview()) };
4261+
let view: &objc2_app_kit::NSView = unsafe { &*webview.webview().cast() };
4262+
let view_frame = view.frame();
42634263
let logical: TaoLogicalSize<f64> = (view_frame.size.width, view_frame.size.height).into();
42644264
return logical.to_physical(window.scale_factor());
42654265
}

crates/tauri-runtime-wry/src/webview.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,17 @@ mod imp {
1313
pub type Webview = webkit2gtk::WebView;
1414
}
1515

16-
#[cfg(target_os = "macos")]
16+
#[cfg(target_vendor = "apple")]
1717
mod imp {
18-
use cocoa::base::id;
18+
use std::ffi::c_void;
1919

2020
pub struct Webview {
21-
pub webview: id,
22-
pub manager: id,
23-
pub ns_window: id,
24-
}
25-
}
26-
27-
#[cfg(target_os = "ios")]
28-
mod imp {
29-
use cocoa::base::id;
30-
31-
pub struct Webview {
32-
pub webview: id,
33-
pub manager: id,
34-
pub view_controller: id,
21+
pub webview: *mut c_void,
22+
pub manager: *mut c_void,
23+
#[cfg(target_os = "macos")]
24+
pub ns_window: *mut c_void,
25+
#[cfg(target_os = "ios")]
26+
pub view_controller: *mut c_void,
3527
}
3628
}
3729

crates/tauri/Cargo.toml

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,19 @@ tray-icon = { version = "0.17", default-features = false, features = [
101101
gtk = { version = "0.18", features = ["v3_24"] }
102102
webkit2gtk = { version = "=2.0.1", features = ["v2_40"] }
103103

104-
[target."cfg(target_os = \"macos\")".dependencies]
104+
# macOS
105+
[target.'cfg(target_os = "macos")'.dependencies]
105106
embed_plist = "1.2"
106107
plist = "1"
107-
cocoa = "0.26"
108-
objc = "0.2"
108+
objc2 = "0.5.2"
109+
objc2-foundation = { version = "0.2.2", features = ["NSData", "NSThread"] }
110+
objc2-app-kit = { version = "0.2.2", features = [
111+
"NSApplication",
112+
"NSColor",
113+
"NSResponder",
114+
"NSView",
115+
"NSWindow",
116+
] }
109117
window-vibrancy = "0.5"
110118

111119
[target."cfg(windows)".dependencies]
@@ -119,10 +127,9 @@ features = ["Win32_Foundation"]
119127
[target."cfg(target_os = \"android\")".dependencies]
120128
jni = "0.21"
121129

122-
[target."cfg(target_os = \"ios\")".dependencies]
130+
# UIKit, i.e. iOS/tvOS/watchOS/visionOS
131+
[target.'cfg(all(target_vendor = "apple", not(target_os = "macos")))'.dependencies]
123132
libc = "0.2"
124-
objc = "0.2"
125-
cocoa = "0.26"
126133
swift-rs = "1.0.7"
127134

128135
[build-dependencies]
@@ -143,6 +150,14 @@ tokio = { version = "1", features = ["full"] }
143150
cargo_toml = "0.17"
144151
http-range = "0.1.5"
145152

153+
# macOS
154+
[target.'cfg(target_os = "macos")'.dev-dependencies]
155+
objc2-web-kit = { version = "0.2.2", features = [
156+
"objc2-app-kit",
157+
"WKWebView",
158+
"WKUserContentController",
159+
] }
160+
146161
[features]
147162
default = ["wry", "compression", "objc-exception", "common-controls-v6"]
148163
unstable = ["tauri-runtime-wry/unstable"]

crates/tauri/src/app.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,22 +2053,18 @@ fn on_event_loop_event<R: Runtime>(
20532053
RuntimeRunEvent::Ready => {
20542054
// set the app icon in development
20552055
#[cfg(all(dev, target_os = "macos"))]
2056-
unsafe {
2057-
use cocoa::{
2058-
appkit::NSImage,
2059-
base::{id, nil},
2060-
foundation::NSData,
2061-
};
2062-
use objc::*;
2056+
{
2057+
use objc2::ClassType;
2058+
use objc2_app_kit::{NSApplication, NSImage};
2059+
use objc2_foundation::{MainThreadMarker, NSData};
2060+
20632061
if let Some(icon) = app_handle.manager.app_icon.clone() {
2064-
let ns_app: id = msg_send![class!(NSApplication), sharedApplication];
2065-
let data = NSData::dataWithBytes_length_(
2066-
nil,
2067-
icon.as_ptr() as *const std::os::raw::c_void,
2068-
icon.len() as u64,
2069-
);
2070-
let app_icon = NSImage::initWithData_(NSImage::alloc(nil), data);
2071-
let _: () = msg_send![ns_app, setApplicationIconImage: app_icon];
2062+
// TODO: Enable this check.
2063+
let mtm = unsafe { MainThreadMarker::new_unchecked() };
2064+
let app = NSApplication::sharedApplication(mtm);
2065+
let data = NSData::with_bytes(&icon);
2066+
let app_icon = NSImage::initWithData(NSImage::alloc(), &data).expect("creating icon");
2067+
unsafe { app.setApplicationIconImage(Some(&app_icon)) };
20722068
}
20732069
}
20742070
RunEvent::Ready

crates/tauri/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,6 @@ macro_rules! ios_plugin_binding {
6262
tauri::swift_rs::swift!(fn $fn_name() -> *const ::std::ffi::c_void);
6363
}
6464
}
65-
#[cfg(target_os = "ios")]
66-
#[doc(hidden)]
67-
pub use cocoa;
6865
#[cfg(target_os = "macos")]
6966
#[doc(hidden)]
7067
pub use embed_plist;

crates/tauri/src/webview/mod.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl PlatformWebview {
179179
/// [WKWebView]: https://developer.apple.com/documentation/webkit/wkwebview
180180
#[cfg(any(target_os = "macos", target_os = "ios"))]
181181
#[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
182-
pub fn inner(&self) -> cocoa::base::id {
182+
pub fn inner(&self) -> *mut std::ffi::c_void {
183183
self.0.webview
184184
}
185185

@@ -188,7 +188,7 @@ impl PlatformWebview {
188188
/// [controller]: https://developer.apple.com/documentation/webkit/wkusercontentcontroller
189189
#[cfg(any(target_os = "macos", target_os = "ios"))]
190190
#[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
191-
pub fn controller(&self) -> cocoa::base::id {
191+
pub fn controller(&self) -> *mut std::ffi::c_void {
192192
self.0.manager
193193
}
194194

@@ -197,7 +197,7 @@ impl PlatformWebview {
197197
/// [NSWindow]: https://developer.apple.com/documentation/appkit/nswindow
198198
#[cfg(target_os = "macos")]
199199
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
200-
pub fn ns_window(&self) -> cocoa::base::id {
200+
pub fn ns_window(&self) -> *mut std::ffi::c_void {
201201
self.0.ns_window
202202
}
203203

@@ -206,7 +206,7 @@ impl PlatformWebview {
206206
/// [UIViewController]: https://developer.apple.com/documentation/uikit/uiviewcontroller
207207
#[cfg(target_os = "ios")]
208208
#[cfg_attr(docsrs, doc(cfg(target_os = "ios")))]
209-
pub fn view_controller(&self) -> cocoa::base::id {
209+
pub fn view_controller(&self) -> *mut std::ffi::c_void {
210210
self.0.view_controller
211211
}
212212

@@ -1000,9 +1000,6 @@ impl<R: Runtime> Webview<R> {
10001000
feature = "unstable",
10011001
doc = r####"
10021002
```rust,no_run
1003-
#[cfg(target_os = "macos")]
1004-
#[macro_use]
1005-
extern crate objc;
10061003
use tauri::Manager;
10071004
10081005
fn main() {
@@ -1026,10 +1023,14 @@ fn main() {
10261023
10271024
#[cfg(target_os = "macos")]
10281025
unsafe {
1029-
let () = msg_send![webview.inner(), setPageZoom: 4.];
1030-
let () = msg_send![webview.controller(), removeAllUserScripts];
1031-
let bg_color: cocoa::base::id = msg_send![class!(NSColor), colorWithDeviceRed:0.5 green:0.2 blue:0.4 alpha:1.];
1032-
let () = msg_send![webview.ns_window(), setBackgroundColor: bg_color];
1026+
let view: &objc2_web_kit::WKWebView = &*webview.inner().cast();
1027+
let controller: &objc2_web_kit::WKUserContentController = &*webview.controller().cast();
1028+
let window: &objc2_app_kit::NSWindow = &*webview.ns_window().cast();
1029+
1030+
view.setPageZoom(4.);
1031+
controller.removeAllUserScripts();
1032+
let bg_color = objc2_app_kit::NSColor::colorWithDeviceRed_green_blue_alpha(0.5, 0.2, 0.4, 1.);
1033+
window.setBackgroundColor(Some(&bg_color));
10331034
}
10341035
10351036
#[cfg(target_os = "android")]

0 commit comments

Comments
 (0)