Skip to content

Fix(macos/ios): Add handler for web content process termination (fix #14371)#14523

Merged
FabianLars merged 31 commits into
tauri-apps:devfrom
JeffTsang:fix/web-content-process-termination
Apr 14, 2026
Merged

Fix(macos/ios): Add handler for web content process termination (fix #14371)#14523
FabianLars merged 31 commits into
tauri-apps:devfrom
JeffTsang:fix/web-content-process-termination

Conversation

@JeffTsang

Copy link
Copy Markdown
Contributor

Fixes #14371 and depends on tauri-apps/wry#1624

On iOS, the webview can become blank and unresponsive when resuming from the background. This can be fixed by handling the termination of the web content process. This PR adds a handler for web content process termination.

@JeffTsang JeffTsang requested a review from a team as a code owner November 23, 2025 09:11
@github-actions

github-actions Bot commented Nov 23, 2025

Copy link
Copy Markdown
Contributor

Package Changes Through e8991c2

There are 9 changes which include tauri-macos-sign with patch, tauri-build with patch, tauri with minor, tauri-runtime with minor, tauri-runtime-wry with minor, tauri-bundler with minor, tauri-cli with minor, @tauri-apps/cli with minor, tauri-utils with minor

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
tauri-utils 2.8.3 2.9.0
tauri-macos-sign 2.3.3 2.3.4
tauri-bundler 2.8.1 2.9.0
tauri-runtime 2.10.1 2.11.0
tauri-runtime-wry 2.10.1 2.11.0
tauri-codegen 2.5.5 2.5.6
tauri-macros 2.5.5 2.5.6
tauri-plugin 2.5.4 2.5.5
tauri-build 2.5.6 2.5.7
tauri 2.10.3 2.11.0
@tauri-apps/cli 2.10.1 2.11.0
tauri-cli 2.10.1 2.11.0

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector

@JeffTsang

Copy link
Copy Markdown
Contributor Author

@FabianLars Now that wry has been updated, would it be possible to take a look at this PR?

@zakxxi

zakxxi commented Feb 20, 2026

Copy link
Copy Markdown

Hey 👋 Just wanted to check in on the status of this PR. I'm building a mobile app with SvelteKit + Tauri and experiencing this exact issue on iOS › the webview goes sometime blank after resuming from background. This fix would be really helpful. Is there anything blocking the review? Thanks for the work on this!

@JeffTsang

Copy link
Copy Markdown
Contributor Author

Unfortunately, it looks like this PR won't be reviewed any time soon unless someone can bring this to the Tauri team's attention.

In the meantime, you can patch wry and add your own code to the web_content_process_did_terminate function in src/wkwebview/navigation.rs

You may also need to run the following code on your webview when your app enters the foreground:

document.body.style.display='none';
document.body.offsetHeight;
document.body.style.display='';

///
/// - **Linux / Windows / Android:** Unsupported.
#[cfg(any(target_os = "macos", target_os = "ios"))]
pub fn on_web_content_process_terminate<F: Fn(Webview<R>) + Send + 'static>(

@velocitysystems velocitysystems Mar 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: webViewWebContentProcessDidTerminate is the name of the underlying WebKit API. I see that on_web_content_process_terminate is the naming used in WRY, but ideally this should follow the same naming as WebKit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

When I was naming the function for wry, I opted for the shorter name because it meant the same thing. I would have kept the original name if there was a webViewWebContentProcessWillTerminate event.

@JeffTsang

Copy link
Copy Markdown
Contributor Author

@velocitysystems I've added a default handler for iOS. It reloads the webview since tauri-runtime-wry doesn't have access to get_app_url.

@JeffTsang

Copy link
Copy Markdown
Contributor Author

@velocitysystems I've moved the default handler so that I can use navigate with a verified url. This should be a more reliable fix than reloading.

@velocitysystems velocitysystems left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @JeffTsang. I've left further comments and feedback on your PR.

  • There are no unit tests for the handler wiring logic.
  • There is no logging during the lifecycle

Also - I'm still concerned about the reload() vs navigate() with URL reconstruction.

The default handler reconstructs the current URL, validates it against the app's base URL, and navigates to it (falling back to /index.html). This feels unnecessary — when webViewWebContentProcessDidTerminate
fires, WKWebView is in a well-defined state: the content process is gone, but the navigation state (URL history, current URL) is preserved in the UI process. reload() handles this correctly in one call.

The navigate() approach also has downsides:

  • If the user was on /settings/profile, the /index.html fallback loses their place
  • The string prefix check (starts_with(app_url.as_str())) is a fragile way to validate URL origin
  • Two unwrap() calls in a crash-recovery callback risk panicking the app — worse than the blank screen

Thoughts @FabianLars?

@FabianLars

Copy link
Copy Markdown
Member

Can all the commits be collapsed into a single fix: ... commit? Rather than merging the dev branch multiple times, it may be better to rebase in the future which avoids merge commits.

Please don't unless required for something. I hate force pushing since it makes it really hard to follow the thought process etc.

This is likely a a minor:feat not a patch:bug since this is an additive change

with the newly exposed api you're right

I'm still concerned about the reload() vs navigate() with URL reconstruction.

How about a very conservative approach? For the initial PR only reload the page. If the app dev wants to they can now add a handler that works for their app as they know best where to navigate to. Then we can investigate some more whether we can do something with navigation or even app restarts. This way we would at least unblock this PR.

Reading through the capacitor discussion, I do not reallyyy share your concerns about losing app state etc on navigation as it seems like reloading/navigation may not even be enough to restore functionality?

@JeffTsang

Copy link
Copy Markdown
Contributor Author

I've reverted to reloading in the default handler.

@velocitysystems

Copy link
Copy Markdown
Contributor

Per-webview customization adds more complexity for a questionable use case. You would need to have multiple webviews and want to handle web content process termination differently for each webview. In any case, you can technically already achieve this by looking at the webview label in the builder hook.

This is actually important to consider; since multi-window support will soon be added to Tauri.

On a separate note, how does the AI tool policy from #15002 apply in this context? I'm spending so much time fielding questions and suggestions generated by AI and the copied PR (#15162) is clearly generated by AI. It's kind of annoying and dragging this PR out.

Peer review and collaboration are what make open-source software successful. I understand your frustration — you’ve been working on this PR for over five months, and most of the activity has only picked up in the last three weeks. We’d really like to keep this discussion constructive and work together to get it across the finish line.

@JeffTsang

Copy link
Copy Markdown
Contributor Author

Regarding per-webview customization, it's advantageous to have all your event handling logic in one place, especially since it's likely to have similar or shared code. You just have to label the webviews appropriately and adjust how you handle the event based on the webview label. Of course, this assumes you even need to handle the event differently for each webview.

Regarding collaboration, human to human collaboration can be useful and is to be expected in open source. The problem is human to robot collaboration. It's not uncommon for AI to make incorrect assumptions that compound and lead to (often overengineered) nonsense that ends up wasting everyone's time. Other times, AI makes generic suggestions that don't take the overall picture into account.

AI-written responses (such as #15162 (comment)) do not sound like normal humans, so you spend a bit of extra time thinking about what it's actually trying to say.

If someone must use AI, AI should only be used in the preliminary stages, perhaps for brainstorming. Everything that the AI suggests should then be thoroughly scrutinized by a human who can then arrive at a final conclusion through original critical thinking. Obviously, the human should type the final response without the use of AI.

Regarding the timeline of this PR, that's another issue entirely. The first PR (#14325) actually dates back to October 2025, but it was accidentally closed in November 2025. I don't know why it took so long for such a serious issue to be picked up, but I was ready to patch wry for as long as I used Tauri.

@JeffTsang

Copy link
Copy Markdown
Contributor Author

If there are no other objections, it would be great if this could be moved forward.

@velocitysystems

velocitysystems commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

I'm going to defer to @FabianLars at this point. I just have two remaining concerns:

  1. .lock().unwrap() in the recovery callback. Can this be improved and/or made more resilient?
  2. Silent failures with no logging makes debugging difficult

The lack of test coverage makes me a little uneasy but I know that will be addressed in the future. However I would love to see this PR move forward like @JeffTsang as this is a high-priority fix for us.

@JeffTsang

Copy link
Copy Markdown
Contributor Author
  1. Unwrapping the result of a mutex lock is standard and intentional, so I wouldn't be concerned with that.
  2. I've added logging to the default handler.

Adding tests would be good, but it would first require a significant refactor of prepare_pending_webview in tauri and create_webview in tauri-runtime-wry. This would involve extracting functions, deciding where to place those functions, and deciding what to name those functions. These decisions should be made by the Tauri team.

@JeffTsang JeffTsang requested a review from FabianLars April 10, 2026 06:03
@FabianLars

Copy link
Copy Markdown
Member

I don't know why it took so long for such a serious issue to be picked up, but I was ready to patch wry for as long as I used Tauri.

Simple, the last few months we were very short on maintainers and/or time, it's not like we prioritized many other issues/PRs, we didn't have time for anything really.

In that spirit i don't want to drag this out any further as well. I'm not 100% sold on having the handler in the runtime crate at this point but we'd probablyyy move it there at some point when we inevitable rework how tauri's runtime crates work (for better cef, servo, etc support).
This pr is imo now good enough and we can iterate over it later if needed (since it's a crash handler we'll need some real world results anyway).

Apologies for the long delays, bad feedback loop, and weird moods again and thanks for working through it.

@FabianLars FabianLars merged commit 1063c48 into tauri-apps:dev Apr 14, 2026
19 checks passed
@FabianLars FabianLars added this to the 2.11 milestone Apr 14, 2026
@wangran-creator

Copy link
Copy Markdown

Hello, Mr FabianLars . Is this merge will be build into new tauri version ? when us developers can use it.
Thank you for your contribution!

@FabianLars

Copy link
Copy Markdown
Member

Will be part of 2.11 which is scheduled for end of this week or early next week.

@wangran-creator

Copy link
Copy Markdown

Hi Mr. FabianLars
Our Team is waiting for 2.11 due to web content process termination. we want to know when we can use 2.11 >.<
Waiting for your reply...
Thank you very much!

@FabianLars

Copy link
Copy Markdown
Member

it will be delayed a bit due to unforeseen absences, sorry.

btw, in case you didn't know - you can use unpublished tauri versions: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-dependencies-from-git-repositories

@wangran-creator

Copy link
Copy Markdown

Thank you very much. Which version can I use to avoid web content process termination?

@petersamokhin

Copy link
Copy Markdown
Contributor

I confirm this fixes a very critical issue that I thought was too magical to fix in a stable way.
You can reproduce it with pkill -9 -f 'com.apple.WebKit.WebContent': before this fix, the window just stays empty, but with this fix it reloads properly. Great job and thanks a lot @JeffTsang @FabianLars!

tlongwell-block added a commit to block/buzz that referenced this pull request May 15, 2026
…ep on macOS

macOS aggressively suspends/terminates WKWebView's WebContent process during
long screen-lock/sleep. Until tauri-runtime-wry 2.11.0, there was no default
handler for this, so on resume the Tauri window remained alive but the webview
rendered blank with no JS context — only an app restart recovered it.

tauri-runtime-wry 2.11.x ships a default macOS/iOS handler that calls
webview.reload() on web content process termination (via the new wry
webViewWebContentProcessDidTerminate hook). We inherit this automatically by
bumping the runtime.

Bumps (via cargo update -p tauri --precise 2.11.1 in desktop/src-tauri):
- tauri              2.10.3 -> 2.11.1
- tauri-runtime      2.10.1 -> 2.11.1
- tauri-runtime-wry  2.10.1 -> 2.11.1
- wry                0.54.4 -> 0.55.1
- tao                0.34.8 -> 0.35.2
- tauri-build        2.5.6  -> 2.6.1
- tauri-utils        2.8.3  -> 2.9.1
- @tauri-apps/api    ~2.10  -> ~2.11
- @tauri-apps/cli    ~2.10  -> ~2.11

Verified:
- cargo check / clippy --no-deps / fmt --check on desktop/src-tauri: clean
- pnpm typecheck / lint / build on desktop/: clean

Refs: tauri-apps/tauri#10662, tauri-apps/tauri#14523, tauri-apps/wry#1619
Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
tlongwell-block added a commit to block/buzz that referenced this pull request May 15, 2026
…ep on macOS

macOS aggressively suspends/terminates WKWebView's WebContent process during
long screen-lock/sleep. Until tauri-runtime-wry 2.11.0, there was no default
handler for this, so on resume the Tauri window remained alive but the webview
rendered blank with no JS context — only an app restart recovered it.

tauri-runtime-wry 2.11.x ships a default macOS/iOS handler that calls
webview.reload() on web content process termination (via the new wry
webViewWebContentProcessDidTerminate hook). We inherit this automatically by
bumping the runtime.

Bumps (via cargo update -p tauri --precise 2.11.1 in desktop/src-tauri):
- tauri              2.10.3 -> 2.11.1
- tauri-runtime      2.10.1 -> 2.11.1
- tauri-runtime-wry  2.10.1 -> 2.11.1
- wry                0.54.4 -> 0.55.1
- tao                0.34.8 -> 0.35.2
- tauri-build        2.5.6  -> 2.6.1
- tauri-utils        2.8.3  -> 2.9.1
- @tauri-apps/api    ~2.10  -> ~2.11
- @tauri-apps/cli    ~2.10  -> ~2.11

CI install stability:
- add pnpm fetch retry/timeout settings for transient Artifactory socket timeouts

Verified:
- cargo check / clippy --no-deps / fmt --check on desktop/src-tauri: clean
- pnpm typecheck / lint / build on desktop/: clean

Refs: tauri-apps/tauri#10662, tauri-apps/tauri#14523, tauri-apps/wry#1619
Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
tlongwell-block added a commit to block/buzz that referenced this pull request May 15, 2026
…ep on macOS

macOS aggressively suspends/terminates WKWebView's WebContent process during
long screen-lock/sleep. Until tauri-runtime-wry 2.11.0, there was no default
handler for this, so on resume the Tauri window remained alive but the webview
rendered blank with no JS context — only an app restart recovered it.

tauri-runtime-wry 2.11.x ships a default macOS/iOS handler that calls
webview.reload() on web content process termination (via the new wry
webViewWebContentProcessDidTerminate hook). We inherit this automatically by
bumping the runtime.

Bumps (via cargo update -p tauri --precise 2.11.1 in desktop/src-tauri):
- tauri              2.10.3 -> 2.11.1
- tauri-runtime      2.10.1 -> 2.11.1
- tauri-runtime-wry  2.10.1 -> 2.11.1
- wry                0.54.4 -> 0.55.1
- tao                0.34.8 -> 0.35.2
- tauri-build        2.5.6  -> 2.6.1
- tauri-utils        2.8.3  -> 2.9.1
- @tauri-apps/api    ~2.10  -> ~2.11
- @tauri-apps/cli    ~2.10  -> ~2.11

Verified:
- cargo check / clippy --no-deps / fmt --check on desktop/src-tauri: clean
- pnpm typecheck / lint / build on desktop/: clean

Refs: tauri-apps/tauri#10662, tauri-apps/tauri#14523, tauri-apps/wry#1619
Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
@gzlboy

gzlboy commented May 17, 2026

Copy link
Copy Markdown

I'm encountering the same issue on iOS. This is a very serious bug, and I hope this PR can be implemented as soon as possible.

@velocitysystems

Copy link
Copy Markdown
Contributor

@gzlboy This is already merged and available in 2.11.0.

@gzlboy

gzlboy commented May 18, 2026

Copy link
Copy Markdown

Thank you so much for your reply. I have tested it on the tauri(2.11.2) and it is fixed!

@gzlboy This is already merged and available in 2.11.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] iOS webview becomes blank and unresponsive when resuming from the background [bug] TAURI UI NOT WORKING PROPERLY AFTER SYSTEM AWAKE FROM SLEEP.

7 participants