From 82efc673e50c7d42f5e06d7130f33c2819f190d9 Mon Sep 17 00:00:00 2001 From: Jeff Tsang <36611384+JeffTsang@users.noreply.github.com> Date: Sat, 18 Oct 2025 12:13:51 +0800 Subject: [PATCH 1/3] Add handler for web content process termination on macOS and iOS --- .changes/web-content-process-termination.md | 7 +++++ crates/tauri-runtime-wry/src/lib.rs | 7 +++++ crates/tauri-runtime/src/webview.rs | 8 +++++ crates/tauri/src/webview/mod.rs | 35 +++++++++++++++++++++ crates/tauri/src/webview/webview_window.rs | 16 ++++++++++ 5 files changed, 73 insertions(+) create mode 100644 .changes/web-content-process-termination.md diff --git a/.changes/web-content-process-termination.md b/.changes/web-content-process-termination.md new file mode 100644 index 000000000000..458573482b59 --- /dev/null +++ b/.changes/web-content-process-termination.md @@ -0,0 +1,7 @@ +--- +"tauri": minor:feat +"tauri-runtime": minor:feat +"tauri-runtime-wry": minor:feat +--- + +Add handler for web content process termination on macOS and iOS. diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 1aac9f1aa7e6..87d6d38b612c 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -4891,6 +4891,13 @@ You may have it installed on another user account, but it is not available for t webview_builder = webview_builder.with_allow_link_preview(webview_attributes.allow_link_preview); + + if let Some(on_web_content_process_terminate_handler) = + pending.on_web_content_process_terminate_handler + { + webview_builder = webview_builder + .with_on_web_content_process_terminate_handler(on_web_content_process_terminate_handler); + } } #[cfg(target_os = "ios")] diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs index f9c904ef9643..b1446f5b77af 100644 --- a/crates/tauri-runtime/src/webview.rs +++ b/crates/tauri-runtime/src/webview.rs @@ -41,6 +41,9 @@ type DocumentTitleChangedHandler = dyn Fn(String) + Send + 'static; type DownloadHandler = dyn Fn(DownloadEvent) -> bool + Send + Sync; +#[cfg(any(target_os = "macos", target_os = "ios"))] +type OnWebContentProcessTerminateHandler = dyn Fn() + Send; + #[cfg(target_os = "ios")] type InputAccessoryViewBuilderFn = dyn Fn(&objc2_ui_kit::UIView) -> Option> + Send @@ -224,6 +227,9 @@ pub struct PendingWebview> { pub on_page_load_handler: Option>, pub download_handler: Option>, + + #[cfg(any(target_os = "macos", target_os = "ios"))] + pub on_web_content_process_terminate_handler: Option>, } impl> PendingWebview { @@ -250,6 +256,8 @@ impl> PendingWebview { web_resource_request_handler: None, on_page_load_handler: None, download_handler: None, + #[cfg(any(target_os = "macos", target_os = "ios"))] + on_web_content_process_terminate_handler: None, }) } } diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs index c185e7c62124..201165dd0ff8 100644 --- a/crates/tauri/src/webview/mod.rs +++ b/crates/tauri/src/webview/mod.rs @@ -65,6 +65,8 @@ pub(crate) type UriSchemeProtocolHandler = pub(crate) type OnPageLoad = dyn Fn(Webview, PageLoadPayload<'_>) + Send + Sync + 'static; pub(crate) type OnDocumentTitleChanged = dyn Fn(Webview, String) + Send + 'static; pub(crate) type DownloadHandler = dyn Fn(Webview, DownloadEvent<'_>) -> bool + Send + Sync; +#[cfg(any(target_os = "macos", target_os = "ios"))] +pub(crate) type OnWebContentProcessTerminateHandler = dyn Fn(Webview) + Send; #[derive(Clone, Serialize)] pub(crate) struct CreatedEvent { @@ -278,6 +280,9 @@ unstable_struct!( pub(crate) on_page_load_handler: Option>>, pub(crate) document_title_changed_handler: Option>>, pub(crate) download_handler: Option>>, + #[cfg(any(target_os = "macos", target_os = "ios"))] + pub(crate) on_web_content_process_terminate_handler: + Option>>, } ); @@ -356,6 +361,8 @@ async fn create_window(app: tauri::AppHandle) { on_page_load_handler: None, document_title_changed_handler: None, download_handler: None, + #[cfg(any(target_os = "macos", target_os = "ios"))] + on_web_content_process_terminate_handler: None, } } @@ -435,6 +442,8 @@ async fn create_window(app: tauri::AppHandle) { on_page_load_handler: None, document_title_changed_handler: None, download_handler: None, + #[cfg(any(target_os = "macos", target_os = "ios"))] + on_web_content_process_terminate_handler: None, } } @@ -697,6 +706,17 @@ tauri::Builder::default() self } + #[cfg(any(target_os = "macos", target_os = "ios"))] + pub fn on_web_content_process_terminate) + Send + 'static>( + mut self, + f: F, + ) -> Self { + self + .on_web_content_process_terminate_handler + .replace(Box::new(f)); + self + } + pub(crate) fn into_pending_webview>( mut self, manager: &M, @@ -776,6 +796,21 @@ tauri::Builder::default() } })); + #[cfg(any(target_os = "macos", target_os = "ios"))] + if let Some(on_web_content_process_terminate_handler) = + self.on_web_content_process_terminate_handler.take() + { + let label = pending.label.clone(); + let manager = manager.manager_owned(); + pending + .on_web_content_process_terminate_handler + .replace(Box::new(move || { + if let Some(w) = manager.get_webview(&label) { + on_web_content_process_terminate_handler(w); + } + })); + } + manager .manager() .webview diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index f4a48c168319..084b0fca0f2c 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -441,6 +441,22 @@ tauri::Builder::default() self } + /// Defines a closure to be executed when the web content process terminates. + /// + /// ## Platform-specific + /// + /// - **Linux / Windows / Android:** Unsupported. + #[cfg(any(target_os = "macos", target_os = "ios"))] + pub fn on_web_content_process_terminate) + Send + 'static>( + mut self, + f: F, + ) -> Self { + self.webview_builder = self + .webview_builder + .on_web_content_process_terminate(move |webview| f(webview)); + self + } + /// Creates a new window. pub fn build(self) -> crate::Result> { let (window, webview) = self.window_builder.with_webview(self.webview_builder)?; From f39aeb694167cfb35a206fea9f2936af6430c38a Mon Sep 17 00:00:00 2001 From: Jeff Tsang <36611384+JeffTsang@users.noreply.github.com> Date: Sat, 18 Oct 2025 13:49:56 +0800 Subject: [PATCH 2/3] Remove redundant closure --- crates/tauri/src/webview/webview_window.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index 084b0fca0f2c..b81abca6f5aa 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -451,9 +451,7 @@ tauri::Builder::default() mut self, f: F, ) -> Self { - self.webview_builder = self - .webview_builder - .on_web_content_process_terminate(move |webview| f(webview)); + self.webview_builder = self.webview_builder.on_web_content_process_terminate(f); self } From 2954c838a005de67c4bb9b7054ae1fadd38dba6a Mon Sep 17 00:00:00 2001 From: Jeff Tsang <36611384+JeffTsang@users.noreply.github.com> Date: Sat, 18 Oct 2025 13:53:20 +0800 Subject: [PATCH 3/3] Add documentation --- crates/tauri/src/webview/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs index 201165dd0ff8..34447fd83e7f 100644 --- a/crates/tauri/src/webview/mod.rs +++ b/crates/tauri/src/webview/mod.rs @@ -706,6 +706,11 @@ tauri::Builder::default() self } + /// Defines a closure to be executed when the web content process terminates. + /// + /// ## Platform-specific + /// + /// - **Linux / Windows / Android:** Unsupported. #[cfg(any(target_os = "macos", target_os = "ios"))] pub fn on_web_content_process_terminate) + Send + 'static>( mut self,