feat(mobile): multi-window support#14484
Conversation
Package Changes Through 865dcedThere are 9 changes which include tauri-macos-sign with patch, tauri-build with patch, tauri with minor, tauri-bundler with patch, tauri-cli with patch, @tauri-apps/cli with patch, tauri-runtime-wry with minor, tauri-runtime with minor, tauri-utils with minor Planned Package VersionsThe following package releases are the planned based on the context of changes in this pull request.
Add another change file through the GitHub UI by following this link. Read about change files or the docs at github.com/jbolda/covector |
|
here's an example: https://github.com/lucasfernog/tauri-mobile-multi-window-example |
velocitysystems
left a comment
There was a problem hiding this comment.
We're very excited about this feature @lucasfernog. I've left comments on #1154 and #1633. Here are some additional general questions:
Platforms & Compatibility
- How will this affect Tauri's minimum supported versions?(i.e. Requires iOS 13+ and Android 12L)
- What is the fallback behavior for unsupported platforms?
- Which features of the Window API are available vs not available on mobile?
Performance & Resource Management
- How do we intend to handle app lifecycle events? e.g. sleep/resume
- How can we optimize multi-window support so as not to affect battery life?
|
|
||
| #[cfg(feature = "unstable")] | ||
| #[command(root = "crate")] | ||
| pub async fn create_webview<R: Runtime>( |
There was a problem hiding this comment.
While we may not wish to enforce this (since it is device-specific) there is a theoretical limit to the number of web-views which can be created based on the available memory.
If the app begins to use too much memory the OS may mark it for termination particularly if it doesn't respond to memory warnings and attempt to free memory.
There was a problem hiding this comment.
right, that's not something we're worried - otherwise we would need to implement such check for all platforms
|
|
||
| #[cfg(feature = "unstable")] | ||
| #[command(root = "crate")] | ||
| pub async fn create_webview<R: Runtime>( |
There was a problem hiding this comment.
WebViews are full browser engines that continue consuming significant CPU, GPU, and battery resources (15-25% per hour) even when the app is backgrounded, unless explicitly paused through lifecycle event handlers (onPause/onResume on Android or scene lifecycle hooks on iOS).
This can reduce background drain to 1-3% per hour—a critical requirement for app store approval and acceptable user experience.
There was a problem hiding this comment.
for Android the system pauses the activity automatically when it moves to the background.. I would expect iOS to do the same
There was a problem hiding this comment.
@lucasfernog Unlike iOS I don't believe Android automatically pauses the WebView's internal threads or JS timers when the Activity's onPause(..) is called. The Android WebView has explicit methods onPause(..) and pauseTimer(..).
See this SO discussion for further discussion.
There was a problem hiding this comment.
I've implemented that but it didn't help much tauri-apps/wry@0904dc9 (#1633)
i think pauseTimer is something that each user should decide if they want to call or not - they can do so in their TauriActivity subclass.
| } | ||
|
|
||
| #[cfg(desktop)] | ||
| mod desktop_commands { |
There was a problem hiding this comment.
Apps can't currently detect if multi-window is available. Should we add an API like this? e.g.
Typescript
if (await app.supportsMultiWindow()) {
// Create new window
} else {
// Ignore
}Rust
pub fn supports_multi_window() -> bool {
#[cfg(target_os = "iOS")]
{
ios_version() >= 13.0
}
#[cfg(target_os = "android")]
{
android_api_level() >= 32 // Android 12L
}
#[cfg(desktop)]
{
true
}
}
The current implementation doesn't support embedding Tauri/Wry views within native view hierarchies like tabs, bottom sheets, or navigation stacks. That would require a different architectural approach at the TAO and WRY layers. This PR enables multiple independent full-screen windows, each with their own webview. It's worth noting that Tauri's mobile architecture is webview-centric more broadly — there's currently no supported way to embed native UI components alongside the webview. Plugins can access native platform APIs (Swift/Kotlin), but not modify the view hierarchy. There's some discussion around this in #10993. |
mobile multi-window: tauri-apps/tauri#14484 file association: tauri-apps/tauri#14486
Co-authored-by: FabianLars <30730186+FabianLars@users.noreply.github.com>
Co-authored-by: FabianLars <30730186+FabianLars@users.noreply.github.com>
| import java.lang.reflect.InvocationTargetException | ||
|
|
||
| class PluginManager(val activity: AppCompatActivity) { | ||
| object PluginManager { |
There was a problem hiding this comment.
@lucasfernog this seems to cause #15506, do we have a reason for the change from class to object here?
Just a note that since we have android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" in the template manifest, the activity should not normally get recreated, but this is still a problem
Leverages scenes on iOS and Activity embedding on Android.
All window APIs are now exposed on mobile too. Some of them are still ignored though (like setting a title).
iOS
Android
needs tauri-apps/tao#1154 and tauri-apps/wry#1633