Skip to content

Commit

Permalink
feat: disable background throttling (#1445)
Browse files Browse the repository at this point in the history
* feat: disable background throttling

webkit only for now

* chore: changes file

* fix: add version check for background throttling

* fix: comments

* Update disable-background-throttling.md

* feat: use policy enum for background throttling

* chore: do not use an option for throttling policy

---------

Co-authored-by: Fabian-Lars <[email protected]>
  • Loading branch information
bastiankistner and FabianLars authored Jan 8, 2025
1 parent cbbcccc commit 26abf63
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 3 deletions.
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': 'patch:enhance'
---

Add an option to change the default background throttling policy (currently for WebKit only).
47 changes: 47 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 background_throttling: Option<BackgroundThrottlingPolicy>,
}

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(),
}),
background_throttling: None,
}
}
}
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_background_throttling(self, policy: BackgroundThrottlingPolicy) -> Self {
self.and_then(|mut b| {
b.attrs.background_throttling = Some(policy);
Ok(b)
})
}

/// Consume the builder and create the [`WebView`] from a type that implements [`HasWindowHandle`].
///
/// # Platform-specific:
Expand Down Expand Up @@ -2021,6 +2057,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::*;
Expand Down
34 changes: 31 additions & 3 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 All @@ -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;

Expand Down Expand Up @@ -350,6 +352,32 @@ impl InnerWebView {
webview
};

// 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 {
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"),
);
}
}
}
}

#[cfg(target_os = "macos")]
{
if is_child {
Expand Down

0 comments on commit 26abf63

Please sign in to comment.