From ec1c18d7d85c01a25213a2ddd460451042ea77bc Mon Sep 17 00:00:00 2001 From: Bastian Kistner Date: Fri, 3 Jan 2025 23:18:21 +0100 Subject: [PATCH 1/7] feat: disable background throttling webkit only for now --- src/lib.rs | 30 ++++++++++++++++++++++++++++++ src/wkwebview/mod.rs | 16 ++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index abce41501..706410c19 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -574,6 +574,18 @@ pub struct WebViewAttributes<'a> { /// This is only effective if the webview was created by [`WebView::new_as_child`] or [`WebViewBuilder::new_as_child`] /// or on Linux, if was created by [`WebViewExtUnix::new_gtk`] or [`WebViewBuilderExtUnix::new_gtk`] with [`gtk::Fixed`]. pub bounds: Option, + + /// Whether background throttling should be disabled. + /// + /// By default, browsers throttle timers and even unload the whole tab (view) to free resources after roughly 5 minutes when + /// a view became minimized or hidden. This will permanently suspend all tasks until the documents visibility state + /// changes back from hidden to visible by bringing the view back to the foreground. + /// + /// ## Platform-specific + /// + /// - **Linux / Windows / Android**: Unsupported yet. But workarounds like a pending WebLock transaction might suffice. + /// see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 + pub disable_background_throttling: bool, } impl<'a> Default for WebViewAttributes<'a> { @@ -614,6 +626,7 @@ impl<'a> Default for WebViewAttributes<'a> { position: dpi::LogicalPosition::new(0, 0).into(), size: dpi::LogicalSize::new(200, 200).into(), }), + disable_background_throttling: false, } } } @@ -1181,6 +1194,23 @@ impl<'a> WebViewBuilder<'a> { }) } + /// Set whether background throttling should be disabled. + /// + /// By default, browsers throttle timers and even unload the whole tab (view) to free resources after roughly 5 minutes when + /// a view became minimized or hidden. This will permanently suspend all tasks until the documents visibility state + /// changes back from hidden to visible by bringing the view back to the foreground. + /// + /// ## Platform-specific + /// + /// - **Linux / Windows / Android**: Unsupported yet. But workarounds like a pending WebLock transaction might suffice. + /// see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 + pub fn with_disable_background_throttling(self, disable: bool) -> Self { + self.and_then(|mut b| { + b.attrs.disable_background_throttling = disable; + Ok(b) + }) + } + /// Consume the builder and create the [`WebView`] from a type that implements [`HasWindowHandle`]. /// /// # Platform-specific: diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index afa4f0aeb..21867cba5 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -63,8 +63,8 @@ use crate::wkwebview::ios::WKWebView::WKWebView; use objc2_web_kit::WKWebView; use objc2_web_kit::{ - WKAudiovisualMediaTypes, WKURLSchemeHandler, WKUserContentController, WKUserScript, - WKUserScriptInjectionTime, WKWebViewConfiguration, WKWebsiteDataStore, + WKAudiovisualMediaTypes, WKInactiveSchedulingPolicy, WKURLSchemeHandler, WKUserContentController, + WKUserScript, WKUserScriptInjectionTime, WKWebViewConfiguration, WKWebsiteDataStore, }; use once_cell::sync::Lazy; use raw_window_handle::{HasWindowHandle, RawWindowHandle}; @@ -347,6 +347,18 @@ impl InnerWebView { webview }; + // disable background throttling if attributes.disable_background_throttling is true + // which works for iOS 17.0+,iPadOS 17.0+,Mac Catalyst 17.0+, macOS 14.0+, visionOS 1.0+ + if attributes.disable_background_throttling { + // Set inactive scheduling policy to None enum value (2) + _preference.setValue_forKey( + Some(&NSNumber::numberWithInt( + WKInactiveSchedulingPolicy::None.0.try_into().unwrap(), + )), + ns_string!("inactiveSchedulingPolicy"), + ); + } + #[cfg(target_os = "macos")] { if is_child { From d468637f79abe8ff0d173763710739b2dce39c4b Mon Sep 17 00:00:00 2001 From: Bastian Kistner Date: Sat, 4 Jan 2025 00:36:29 +0100 Subject: [PATCH 2/7] chore: changes file --- .changes/disable-background-throttling.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/disable-background-throttling.md diff --git a/.changes/disable-background-throttling.md b/.changes/disable-background-throttling.md new file mode 100644 index 000000000..eb88d20b5 --- /dev/null +++ b/.changes/disable-background-throttling.md @@ -0,0 +1,5 @@ +--- +"wry": minor +--- + +Add an option to disable background throttling (currently for WebKit only). \ No newline at end of file From 96279eb988a77582989d8ddd00b94b41c13b38ce Mon Sep 17 00:00:00 2001 From: Bastian Kistner Date: Tue, 7 Jan 2025 12:40:09 +0100 Subject: [PATCH 3/7] fix: add version check for background throttling --- .changes/disable-background-throttling.md | 4 ++-- src/lib.rs | 8 ++++++-- src/wkwebview/mod.rs | 22 ++++++++++++++-------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.changes/disable-background-throttling.md b/.changes/disable-background-throttling.md index eb88d20b5..df1d5acb4 100644 --- a/.changes/disable-background-throttling.md +++ b/.changes/disable-background-throttling.md @@ -1,5 +1,5 @@ --- -"wry": minor +'wry': 'minor:enhance' --- -Add an option to disable background throttling (currently for WebKit only). \ No newline at end of file +Add an option to disable background throttling (currently for WebKit only). diff --git a/src/lib.rs b/src/lib.rs index 706410c19..4add91258 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -583,7 +583,9 @@ pub struct WebViewAttributes<'a> { /// /// ## Platform-specific /// - /// - **Linux / Windows / Android**: Unsupported yet. But workarounds like a pending WebLock transaction might suffice. + /// - **Linux / Windows / Android**: Unsupported. Workarounds like a pending WebLock transaction might suffice. + /// - **iOS / macOS**: Supported since version 17.0+. + /// /// see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 pub disable_background_throttling: bool, } @@ -1202,7 +1204,9 @@ impl<'a> WebViewBuilder<'a> { /// /// ## Platform-specific /// - /// - **Linux / Windows / Android**: Unsupported yet. But workarounds like a pending WebLock transaction might suffice. + /// - **Linux / Windows / Android**: Unsupported. Workarounds like a pending WebLock transaction might suffice. + /// - **iOS / macOS**: Supported since version 17.0+. + /// /// see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 pub fn with_disable_background_throttling(self, disable: bool) -> Self { self.and_then(|mut b| { diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index 21867cba5..0a6562be5 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -349,14 +349,20 @@ impl InnerWebView { // disable background throttling if attributes.disable_background_throttling is true // which works for iOS 17.0+,iPadOS 17.0+,Mac Catalyst 17.0+, macOS 14.0+, visionOS 1.0+ - if attributes.disable_background_throttling { - // Set inactive scheduling policy to None enum value (2) - _preference.setValue_forKey( - Some(&NSNumber::numberWithInt( - WKInactiveSchedulingPolicy::None.0.try_into().unwrap(), - )), - ns_string!("inactiveSchedulingPolicy"), - ); + #[cfg(any(target_os = "ios", target_os = "macos"))] + { + let is_supported_os = (cfg!(target_os = "ios") && os_major_version >= 17) + || (cfg!(target_os = "macos") && os_major_version >= 14); + + if is_supported_os && attributes.disable_background_throttling { + // Set inactive scheduling policy to None enum value (2) + _preference.setValue_forKey( + Some(&NSNumber::numberWithInt( + WKInactiveSchedulingPolicy::None.0.try_into().unwrap(), + )), + ns_string!("inactiveSchedulingPolicy"), + ); + } } #[cfg(target_os = "macos")] From 5867dcc1b660ff443f0390207f23c21d002eacaa Mon Sep 17 00:00:00 2001 From: Bastian Kistner Date: Tue, 7 Jan 2025 16:34:52 +0100 Subject: [PATCH 4/7] fix: comments --- src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4add91258..5707e78a0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -584,7 +584,8 @@ pub struct WebViewAttributes<'a> { /// ## Platform-specific /// /// - **Linux / Windows / Android**: Unsupported. Workarounds like a pending WebLock transaction might suffice. - /// - **iOS / macOS**: Supported since version 17.0+. + /// - **iOS**: Supported since version 17.0+. + /// - **macOS**: Supported since version 14.0+. /// /// see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 pub disable_background_throttling: bool, @@ -1205,7 +1206,8 @@ impl<'a> WebViewBuilder<'a> { /// ## Platform-specific /// /// - **Linux / Windows / Android**: Unsupported. Workarounds like a pending WebLock transaction might suffice. - /// - **iOS / macOS**: Supported since version 17.0+. + /// - **iOS**: Supported since version 17.0+. + /// - **macOS**: Supported since version 14.0+. /// /// see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 pub fn with_disable_background_throttling(self, disable: bool) -> Self { From 80061a0fcf5840bbb6ed7209a9e4fdc2240e4436 Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Tue, 7 Jan 2025 20:36:27 +0100 Subject: [PATCH 5/7] Update disable-background-throttling.md --- .changes/disable-background-throttling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/disable-background-throttling.md b/.changes/disable-background-throttling.md index df1d5acb4..e50e038d2 100644 --- a/.changes/disable-background-throttling.md +++ b/.changes/disable-background-throttling.md @@ -1,5 +1,5 @@ --- -'wry': 'minor:enhance' +'wry': 'patch:enhance' --- Add an option to disable background throttling (currently for WebKit only). From 0df25dfd46fd01dc009edcbd8b739231dcf118fb Mon Sep 17 00:00:00 2001 From: Bastian Kistner Date: Wed, 8 Jan 2025 12:01:02 +0100 Subject: [PATCH 6/7] feat: use policy enum for background throttling --- .changes/disable-background-throttling.md | 2 +- src/lib.rs | 19 +++++++++++--- src/wkwebview/mod.rs | 30 +++++++++++++++-------- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/.changes/disable-background-throttling.md b/.changes/disable-background-throttling.md index df1d5acb4..c4b209839 100644 --- a/.changes/disable-background-throttling.md +++ b/.changes/disable-background-throttling.md @@ -2,4 +2,4 @@ 'wry': 'minor:enhance' --- -Add an option to disable background throttling (currently for WebKit only). +Add an option to change the default background throttling policy (currently for WebKit only). diff --git a/src/lib.rs b/src/lib.rs index 5707e78a0..ba22ddbec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -588,7 +588,7 @@ pub struct WebViewAttributes<'a> { /// - **macOS**: Supported since version 14.0+. /// /// see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 - pub disable_background_throttling: bool, + pub background_throttling: Option, } impl<'a> Default for WebViewAttributes<'a> { @@ -629,7 +629,7 @@ impl<'a> Default for WebViewAttributes<'a> { position: dpi::LogicalPosition::new(0, 0).into(), size: dpi::LogicalSize::new(200, 200).into(), }), - disable_background_throttling: false, + background_throttling: None, } } } @@ -1210,9 +1210,9 @@ impl<'a> WebViewBuilder<'a> { /// - **macOS**: Supported since version 14.0+. /// /// see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 - pub fn with_disable_background_throttling(self, disable: bool) -> Self { + pub fn with_background_throttling(self, policy: Option) -> Self { self.and_then(|mut b| { - b.attrs.disable_background_throttling = disable; + b.attrs.background_throttling = policy; Ok(b) }) } @@ -2033,6 +2033,17 @@ pub enum PageLoadEvent { Finished, } +/// Background throttling policy +#[derive(Debug, Clone)] +pub enum BackgroundThrottlingPolicy { + /// A policy where background throttling is disabled + Disabled, + /// A policy where a web view that’s not in a window fully suspends tasks. + Suspend, + /// A policy where a web view that’s not in a window limits processing, but does not fully suspend tasks. + Throttle, +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index 0a6562be5..32ad5df70 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -88,7 +88,9 @@ use crate::{ }, }; -use crate::{Error, Rect, RequestAsyncResponder, Result, WebViewAttributes, RGBA}; +use crate::{ + BackgroundThrottlingPolicy, Error, Rect, RequestAsyncResponder, Result, WebViewAttributes, RGBA, +}; use http::Request; @@ -347,21 +349,29 @@ impl InnerWebView { webview }; - // disable background throttling if attributes.disable_background_throttling is true + // change background throttling policy if attributes.background_throttling is set // which works for iOS 17.0+,iPadOS 17.0+,Mac Catalyst 17.0+, macOS 14.0+, visionOS 1.0+ #[cfg(any(target_os = "ios", target_os = "macos"))] { let is_supported_os = (cfg!(target_os = "ios") && os_major_version >= 17) || (cfg!(target_os = "macos") && os_major_version >= 14); - if is_supported_os && attributes.disable_background_throttling { - // Set inactive scheduling policy to None enum value (2) - _preference.setValue_forKey( - Some(&NSNumber::numberWithInt( - WKInactiveSchedulingPolicy::None.0.try_into().unwrap(), - )), - ns_string!("inactiveSchedulingPolicy"), - ); + if is_supported_os { + if let Some(policy) = attributes.background_throttling { + let policy_value = match policy { + BackgroundThrottlingPolicy::Disabled => WKInactiveSchedulingPolicy::None.0, + BackgroundThrottlingPolicy::Suspend => WKInactiveSchedulingPolicy::Suspend.0, + BackgroundThrottlingPolicy::Throttle => WKInactiveSchedulingPolicy::Throttle.0, + }; + + // Convert and set the value + if let Ok(policy_number) = policy_value.try_into() { + _preference.setValue_forKey( + Some(&NSNumber::numberWithInt(policy_number)), + ns_string!("inactiveSchedulingPolicy"), + ); + } + } } } From 70574bedf86dcb7de044c2e3e7a76cf93226de9f Mon Sep 17 00:00:00 2001 From: Bastian Kistner Date: Wed, 8 Jan 2025 12:43:20 +0100 Subject: [PATCH 7/7] chore: do not use an option for throttling policy --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ba22ddbec..268e0d34d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1210,9 +1210,9 @@ impl<'a> WebViewBuilder<'a> { /// - **macOS**: Supported since version 14.0+. /// /// see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 - pub fn with_background_throttling(self, policy: Option) -> Self { + pub fn with_background_throttling(self, policy: BackgroundThrottlingPolicy) -> Self { self.and_then(|mut b| { - b.attrs.background_throttling = policy; + b.attrs.background_throttling = Some(policy); Ok(b) }) }