Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: disable background throttling #1445

Merged
Merged
5 changes: 5 additions & 0 deletions .changes/disable-background-throttling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'wry': 'minor:enhance'
FabianLars marked this conversation as resolved.
Show resolved Hide resolved
---

Add an option to disable background throttling (currently for WebKit only).
36 changes: 36 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,21 @@ 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<Rect>,

/// 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. Workarounds like a pending WebLock transaction might suffice.
/// - **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,
bastiankistner marked this conversation as resolved.
Show resolved Hide resolved
}

impl<'a> Default for WebViewAttributes<'a> {
Expand Down Expand Up @@ -614,6 +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,
}
}
}
Expand Down Expand Up @@ -1181,6 +1197,26 @@ 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. Workarounds like a pending WebLock transaction might suffice.
/// - **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 {
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:
Expand Down
22 changes: 20 additions & 2 deletions src/wkwebview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -347,6 +347,24 @@ 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+
#[cfg(any(target_os = "ios", target_os = "macos"))]
{
let is_supported_os = (cfg!(target_os = "ios") && os_major_version >= 17)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could replace is_supported_os with custom_data_store_available from above since that has the same version requirement but i'm not sure if that's good for visibility 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do so, but indeed, that could leave the impression that it has something to do with the custom data store.

|| (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")]
{
if is_child {
Expand Down
Loading