Skip to content

Commit

Permalink
refactor(macos): migrate to objc2 (#1316)
Browse files Browse the repository at this point in the history
* migrate drag & drop

* refactor: migrate to `dpi` crate (#1202)

* refactor: migrate to `dpi` crate

closes #1172

* macOS

* linux

* fix doctests

* imports

* more doctests

* fix android and ios

* Update examples/winit.rs

Co-authored-by: Jason Tsai <[email protected]>

* Update src/webview2/mod.rs

---------

Co-authored-by: Jason Tsai <[email protected]>

* fix(windows): avoid double-free the controller (#1206)

* fix(linux): Disable deprecated applicationCache web api. (#1207)

fixes tauri-apps/tauri#9300
ref WebKit/WebKit#23382

* fix(wkwebview): menu shortcuts (#1208)

* fix(wkwebview): menu shortcuts

* Update wkwebview.md

* Apply Version Updates From Current Changes (#1203)

Co-authored-by: amrbashir <[email protected]>

* migrate to `objc2`

* fix(macos): response body being double freed

* fix(macos): eval callback NSStrgin convertion error

* chore: remove objc dependency

* refactor(macos): migrate WebViewDelegate

* refactor(macos): migrate proxy to objc2

* refactor(macos): migrate document title change observer to objc2

* refactor(macos): move drag&drop handler to delegate

* refactor(macos): move ipc_handler into WryWebViewDelegate

* refactor(macos): migrate download handler

* fix(macos): prevent unsafe async custom protocol panic

* chore: target os import

* refactor(ios): migrate to objc2

* refactor(macos): migrate WebViewUIDelegate to objc2

* refactor(macos): migrate WryWebViewParent to objc2

* refactor(macos): move custom class to individual files

* chore: fix clippy

* refector: use reference for task. use objc2::exception::catch.

* fix(dnd): use msg_send super and impl NSDraggingDestination

* chore: call msg_send super

* fix: wrap Box<dyn FnMut(..)> with RefCell

* chore(deps): update rust crate tao to 0.29 (#1343)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* refactor: use bitflags way to handle mask bit manipulation

* WIP: refactor(ios): add wkwebview for ios

* Update Cargo.toml

Co-authored-by: Mads Marquart <[email protected]>

* fix: remove `.copy()` from RcBlock

* add change file

* lint

* fmt

---------

Co-authored-by: Amr Bashir <[email protected]>
Co-authored-by: Fabian-Lars <[email protected]>
Co-authored-by: thewh1teagle <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: amrbashir <[email protected]>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Mads Marquart <[email protected]>
Co-authored-by: Lucas Nogueira <[email protected]>
  • Loading branch information
9 people authored Oct 11, 2024
1 parent 8cc2a7f commit 0abc221
Show file tree
Hide file tree
Showing 23 changed files with 2,452 additions and 1,412 deletions.
5 changes: 5 additions & 0 deletions .changes/objc2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": minor
---

Migrate to obj2.
124 changes: 95 additions & 29 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
workspace = { }
workspace = {}

[package]
name = "wry"
Expand All @@ -10,53 +10,55 @@ description = "Cross-platform WebView rendering library"
readme = "README.md"
repository = "https://github.com/tauri-apps/wry"
documentation = "https://docs.rs/wry"
categories = [ "gui" ]
exclude = [ "/.changes", "/.github", "/audits", "/wry-logo.svg" ]
categories = ["gui"]
exclude = ["/.changes", "/.github", "/audits", "/wry-logo.svg"]

[package.metadata.docs.rs]
no-default-features = true
features = [ "drag-drop", "protocol", "os-webview" ]
features = ["drag-drop", "protocol", "os-webview"]
targets = [
"x86_64-unknown-linux-gnu",
"x86_64-pc-windows-msvc",
"x86_64-apple-darwin"
"x86_64-apple-darwin",
]
rustc-args = [ "--cfg", "docsrs" ]
rustdoc-args = [ "--cfg", "docsrs" ]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]

[features]
default = [ "drag-drop", "objc-exception", "protocol", "os-webview" ]
serde = [ "dpi/serde" ]
objc-exception = [ "objc/exception" ]
drag-drop = [ ]
protocol = [ ]
devtools = [ ]
transparent = [ ]
fullscreen = [ ]
linux-body = [ "webkit2gtk/v2_40", "os-webview" ]
mac-proxy = [ ]
default = ["drag-drop", "objc-exception", "protocol", "os-webview"]
serde = ["dpi/serde"]
objc-exception = ["objc2/catch-all"]
drag-drop = []
protocol = []
devtools = []
transparent = []
fullscreen = []
linux-body = ["webkit2gtk/v2_40", "os-webview"]
mac-proxy = []
os-webview = [
"javascriptcore-rs",
"webkit2gtk",
"webkit2gtk-sys",
"dep:gtk",
"soup3",
"x11-dl",
"gdkx11"
"gdkx11",
]
tracing = [ "dep:tracing" ]
tracing = ["dep:tracing"]

[dependencies]
tracing = { version = "0.1", optional = true }
once_cell = "1"
thiserror = "1.0"
http = "1.1"
raw-window-handle = { version = "0.6", features = [ "std" ] }
raw-window-handle = { version = "0.6", features = ["std"] }
dpi = "0.1"

[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
javascriptcore-rs = { version = "=1.1.2", features = [ "v2_28" ], optional = true }
webkit2gtk = { version = "=2.0.1", features = [ "v2_38" ], optional = true }
javascriptcore-rs = { version = "=1.1.2", features = [
"v2_28",
], optional = true }
webkit2gtk = { version = "=2.0.1", features = ["v2_38"], optional = true }
webkit2gtk-sys = { version = "=2.0.1", optional = true }
gtk = { version = "0.18", optional = true }
soup3 = { version = "0.5", optional = true }
Expand Down Expand Up @@ -87,15 +89,79 @@ features = [
"Win32_Globalization",
"Win32_UI_HiDpi",
"Win32_UI_Input",
"Win32_UI_Input_KeyboardAndMouse"
"Win32_UI_Input_KeyboardAndMouse",
]

[target."cfg(any(target_os = \"ios\", target_os = \"macos\"))".dependencies]
block = "0.1"
cocoa = "0.26"
core-graphics = "0.24"
objc = "0.2"
objc_id = "0.1"
block2 = "0.5"
objc2 = "0.5"
objc2-web-kit = { version = "0.2.0", features = [
"objc2-app-kit",
"block2",
"WKWebView",
"WKWebViewConfiguration",
"WKWebsiteDataStore",
"WKDownload",
"WKDownloadDelegate",
"WKNavigation",
"WKNavigationDelegate",
"WKUserContentController",
"WKURLSchemeHandler",
"WKPreferences",
"WKURLSchemeTask",
"WKScriptMessageHandler",
"WKUIDelegate",
"WKOpenPanelParameters",
"WKFrameInfo",
"WKSecurityOrigin",
"WKScriptMessage",
"WKNavigationAction",
"WKWebpagePreferences",
"WKNavigationResponse",
"WKUserScript",
] }
objc2-foundation = { version = "0.2.0", features = [
"NSURLRequest",
"NSURL",
"NSString",
"NSKeyValueCoding",
"NSStream",
"NSDictionary",
"NSObject",
"NSData",
"NSKeyValueObserving",
"NSThread",
"NSJSONSerialization",
"NSDate",
"NSBundle",
"NSProcessInfo",
"NSValue",
"NSRange",
] }

[target."cfg(target_os = \"ios\")".dependencies]
objc2-ui-kit = { version = "0.2.2", features = [
"UIResponder",
"UIScrollView",
"UIView",
"UIWindow",
"UIApplication",
"UIEvent",
] }

[target."cfg(target_os = \"macos\")".dependencies]
objc2-app-kit = { version = "0.2.0", features = [
"NSApplication",
"NSEvent",
"NSWindow",
"NSView",
"NSPasteboard",
"NSPanel",
"NSResponder",
"NSOpenPanel",
"NSSavePanel",
"NSMenu",
] }

[target."cfg(target_os = \"android\")".dependencies]
crossbeam-channel = "0.5"
Expand All @@ -119,4 +185,4 @@ percent-encoding = "2.3"

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = [ "cfg(linux)", "cfg(gtk)" ]
check-cfg = ["cfg(linux)", "cfg(gtk)"]
4 changes: 2 additions & 2 deletions examples/reparent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use tao::{
use wry::WebViewBuilder;

#[cfg(target_os = "macos")]
use {tao::platform::macos::WindowExtMacOS, wry::WebViewExtMacOS};
use {objc2_app_kit::NSWindow, tao::platform::macos::WindowExtMacOS, wry::WebViewExtMacOS};
#[cfg(target_os = "windows")]
use {tao::platform::windows::WindowExtWindows, wry::WebViewExtWindows};

Expand Down Expand Up @@ -91,7 +91,7 @@ fn main() -> wry::Result<()> {

#[cfg(target_os = "macos")]
webview
.reparent(new_parent.ns_window() as cocoa::base::id)
.reparent(new_parent.ns_window() as *mut NSWindow)
.unwrap();
#[cfg(not(any(
target_os = "windows",
Expand Down
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub enum Error {
#[cfg(target_os = "android")]
#[error(transparent)]
CrossBeamRecvError(#[from] crossbeam_channel::RecvError),
#[error("not on the main thread")]
NotMainThread,
#[error("Custom protocol task is invalid.")]
CustomProtocolTaskInvalid,
#[error("Failed to register URL scheme: {0}, could be due to invalid URL scheme or the scheme is already registered.")]
Expand Down
64 changes: 29 additions & 35 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@
#![allow(clippy::type_complexity)]
#![cfg_attr(docsrs, feature(doc_cfg))]

#[cfg(any(target_os = "macos", target_os = "ios"))]
#[macro_use]
extern crate objc;
// #[cfg(any(target_os = "macos", target_os = "ios"))]
// #[macro_use]
// extern crate objc;

mod error;
mod proxy;
Expand Down Expand Up @@ -222,12 +222,18 @@ use raw_window_handle::HasWindowHandle;
#[cfg(gtk)]
use webkitgtk::*;

#[cfg(any(target_os = "macos", target_os = "ios"))]
use objc2::rc::Retained;
#[cfg(target_os = "macos")]
use objc2_app_kit::NSWindow;
#[cfg(any(target_os = "macos", target_os = "ios"))]
use objc2_web_kit::WKUserContentController;
#[cfg(any(target_os = "macos", target_os = "ios"))]
pub(crate) mod wkwebview;
#[cfg(any(target_os = "macos", target_os = "ios"))]
use wkwebview::*;
#[cfg(any(target_os = "macos", target_os = "ios"))]
pub use wkwebview::{PrintMargin, PrintOptions};
pub use wkwebview::{PrintMargin, PrintOptions, WryWebView};

#[cfg(target_os = "windows")]
pub(crate) mod webview2;
Expand Down Expand Up @@ -416,7 +422,7 @@ pub struct WebViewAttributes<'a> {
/// second is a mutable `PathBuf` reference that (possibly) represents where the file will be downloaded to. The latter
/// parameter can be used to set the download location by assigning a new path to it, the assigned path _must_ be
/// absolute. The closure returns a `bool` to allow or deny the download.
pub download_started_handler: Option<Box<dyn FnMut(String, &mut PathBuf) -> bool>>,
pub download_started_handler: Option<Box<dyn FnMut(String, &mut PathBuf) -> bool + 'static>>,

/// A download completion handler to manage downloads that have finished.
///
Expand Down Expand Up @@ -1146,20 +1152,11 @@ impl<'a> WebViewBuilder<'a> {
}

#[cfg(any(target_os = "macos", target_os = "ios",))]
#[derive(Clone)]
#[derive(Clone, Default)]
pub(crate) struct PlatformSpecificWebViewAttributes {
data_store_identifier: Option<[u8; 16]>,
}

#[cfg(any(target_os = "macos", target_os = "ios",))]
impl Default for PlatformSpecificWebViewAttributes {
fn default() -> Self {
Self {
data_store_identifier: None,
}
}
}

#[cfg(any(target_os = "macos", target_os = "ios",))]
pub trait WebViewBuilderExtDarwin {
/// Initialize the WebView with a custom data store identifier.
Expand Down Expand Up @@ -1767,35 +1764,32 @@ impl WebViewExtUnix for WebView {
#[cfg(target_os = "macos")]
pub trait WebViewExtMacOS {
/// Returns WKWebView handle
fn webview(&self) -> cocoa::base::id;
fn webview(&self) -> Retained<WryWebView>;
/// Returns WKWebView manager [(userContentController)](https://developer.apple.com/documentation/webkit/wkscriptmessagehandler/1396222-usercontentcontroller) handle
fn manager(&self) -> cocoa::base::id;
fn manager(&self) -> Retained<WKUserContentController>;
/// Returns NSWindow associated with the WKWebView webview
fn ns_window(&self) -> cocoa::base::id;
fn ns_window(&self) -> Retained<NSWindow>;
/// Attaches this webview to the given NSWindow and removes it from the current one.
fn reparent(&self, window: cocoa::base::id) -> Result<()>;
fn reparent(&self, window: *mut NSWindow) -> Result<()>;
// Prints with extra options
fn print_with_options(&self, options: &PrintOptions) -> Result<()>;
}

#[cfg(target_os = "macos")]
impl WebViewExtMacOS for WebView {
fn webview(&self) -> cocoa::base::id {
self.webview.webview
fn webview(&self) -> Retained<WryWebView> {
self.webview.webview.clone()
}

fn manager(&self) -> cocoa::base::id {
self.webview.manager
fn manager(&self) -> Retained<WKUserContentController> {
self.webview.manager.clone()
}

fn ns_window(&self) -> cocoa::base::id {
unsafe {
let ns_window: cocoa::base::id = msg_send![self.webview.webview, window];
ns_window
}
fn ns_window(&self) -> Retained<NSWindow> {
self.webview.webview.window().unwrap().clone()
}

fn reparent(&self, window: cocoa::base::id) -> Result<()> {
fn reparent(&self, window: *mut NSWindow) -> Result<()> {
self.webview.reparent(window)
}

Expand All @@ -1808,19 +1802,19 @@ impl WebViewExtMacOS for WebView {
#[cfg(target_os = "ios")]
pub trait WebViewExtIOS {
/// Returns WKWebView handle
fn webview(&self) -> cocoa::base::id;
fn webview(&self) -> Retained<WryWebView>;
/// Returns WKWebView manager [(userContentController)](https://developer.apple.com/documentation/webkit/wkscriptmessagehandler/1396222-usercontentcontroller) handle
fn manager(&self) -> cocoa::base::id;
fn manager(&self) -> Retained<WKUserContentController>;
}

#[cfg(target_os = "ios")]
impl WebViewExtIOS for WebView {
fn webview(&self) -> cocoa::base::id {
self.webview.webview
fn webview(&self) -> Retained<WryWebView> {
self.webview.webview.clone()
}

fn manager(&self) -> cocoa::base::id {
self.webview.manager
fn manager(&self) -> Retained<WKUserContentController> {
self.webview.manager.clone()
}
}

Expand Down
Loading

0 comments on commit 0abc221

Please sign in to comment.