diff --git a/.changes/web-content-process-termination.md b/.changes/web-content-process-termination.md new file mode 100644 index 000000000..4e298a07a --- /dev/null +++ b/.changes/web-content-process-termination.md @@ -0,0 +1,5 @@ +--- +"wry": minor +--- + +Add handler for web content process termination. diff --git a/src/lib.rs b/src/lib.rs index 77a54ccd8..2b2706ec7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1462,6 +1462,7 @@ pub(crate) struct PlatformSpecificWebViewAttributes { data_store_identifier: Option<[u8; 16]>, traffic_light_inset: Option, allow_link_preview: bool, + on_web_content_process_terminate_handler: Option>, #[cfg(target_os = "ios")] input_accessory_view_builder: Option>, #[cfg(target_os = "ios")] @@ -1478,6 +1479,7 @@ impl Default for PlatformSpecificWebViewAttributes { traffic_light_inset: None, // platform default for this is true allow_link_preview: true, + on_web_content_process_terminate_handler: None, #[cfg(target_os = "ios")] input_accessory_view_builder: None, #[cfg(target_os = "ios")] @@ -1509,6 +1511,8 @@ pub trait WebViewBuilderExtDarwin { /// /// See https://developer.apple.com/documentation/webkit/wkwebview/allowslinkpreview fn with_allow_link_preview(self, allow_link_preview: bool) -> Self; + /// Set a handler closure to respond to web content process termination. Available on macOS and iOS only. + fn with_on_web_content_process_terminate_handler(self, handler: impl Fn() + 'static) -> Self; } #[cfg(any(target_os = "macos", target_os = "ios"))] @@ -1527,6 +1531,13 @@ impl WebViewBuilderExtDarwin for WebViewBuilder<'_> { self.platform_specific.allow_link_preview = allow_link_preview; self } + + fn with_on_web_content_process_terminate_handler(mut self, handler: impl Fn() + 'static) -> Self { + self + .platform_specific + .on_web_content_process_terminate_handler = Some(Box::new(handler)); + self + } } #[cfg(target_os = "macos")] diff --git a/src/wkwebview/class/wry_navigation_delegate.rs b/src/wkwebview/class/wry_navigation_delegate.rs index 5919949b6..3325fafc8 100644 --- a/src/wkwebview/class/wry_navigation_delegate.rs +++ b/src/wkwebview/class/wry_navigation_delegate.rs @@ -22,6 +22,7 @@ use crate::{ download::{navigation_download_action, navigation_download_response}, navigation::{ did_commit_navigation, did_finish_navigation, navigation_policy, navigation_policy_response, + web_content_process_did_terminate, }, }, PageLoadEvent, WryWebView, @@ -35,6 +36,7 @@ pub struct WryNavigationDelegateIvars { pub navigation_policy_function: Box bool>, pub download_delegate: Option>, pub on_page_load_handler: Option>, + pub on_web_content_process_terminate_handler: Option>, } define_class!( @@ -96,6 +98,11 @@ define_class!( ) { navigation_download_response(self, webview, response, download); } + + #[unsafe(method(webViewWebContentProcessDidTerminate:))] + fn web_content_process_did_terminate(&self, webview: &WKWebView) { + web_content_process_did_terminate(self, webview); + } } ); @@ -108,6 +115,7 @@ impl WryNavigationDelegate { navigation_handler: Option bool>>, download_delegate: Option>, on_page_load_handler: Option>, + on_web_content_process_terminate_handler: Option>, mtm: MainThreadMarker, ) -> Retained { let navigation_policy_function = Box::new(move |url: String| -> bool { @@ -125,6 +133,16 @@ impl WryNavigationDelegate { None }; + let on_web_content_process_terminate_handler = + if let Some(handler) = on_web_content_process_terminate_handler { + let custom_handler = Box::new(move || { + handler(); + }) as Box; + Some(custom_handler) + } else { + None + }; + let delegate = mtm .alloc::() .set_ivars(WryNavigationDelegateIvars { @@ -133,6 +151,7 @@ impl WryNavigationDelegate { has_download_handler, download_delegate, on_page_load_handler, + on_web_content_process_terminate_handler, }); unsafe { msg_send![super(delegate), init] } diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index 0bbf6711a..7ca2e14a0 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -542,6 +542,7 @@ impl InnerWebView { attributes.navigation_handler, download_delegate.clone(), attributes.on_page_load_handler, + pl_attrs.on_web_content_process_terminate_handler, mtm, ); diff --git a/src/wkwebview/navigation.rs b/src/wkwebview/navigation.rs index 358353697..9dfeebb1a 100644 --- a/src/wkwebview/navigation.rs +++ b/src/wkwebview/navigation.rs @@ -102,3 +102,14 @@ pub(crate) fn navigation_policy_response( (*handler).call((WKNavigationResponsePolicy::Allow,)); } } + +pub(crate) fn web_content_process_did_terminate( + this: &WryNavigationDelegate, + _webview: &WKWebView, +) { + if let Some(on_web_content_process_terminate) = + &this.ivars().on_web_content_process_terminate_handler + { + on_web_content_process_terminate(); + } +}