Skip to content

Expose NativeWebView.ProcessTerminated when the web content process is gone - #103

Merged
maxkatz6 merged 2 commits into
AvaloniaUI:mainfrom
ZK-Andy:process-terminated-event
Oct 27, 2026
Merged

maxkatz6 merged 2 commits into
AvaloniaUI:mainfrom
ZK-Andy:process-terminated-event

Conversation

@ZK-Andy

@ZK-Andy ZK-Andy commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Closes #102

Adds a unified NativeWebView.ProcessTerminated event (and the same event on NativeWebDialog) that dispatches when the web content process backing the webview is gone, following the design agreed in #102: strictly "termination", never recoverable conditions such as unresponsiveness, with a nullable string carrying the platform detail for diagnostics.

API

public sealed class WebViewProcessTerminatedEventArgs : EventArgs
{
    /// Platform-specific detail about the web content process termination, or null if the platform doesn't provide one.
    public string? Reason { get; init; }
}

public event EventHandler<WebViewProcessTerminatedEventArgs>? ProcessTerminated;

Internally the event lives on a new IWebViewAdapterWithProcessTermination capability interface (similarly to #59), implemented by the WebView2, WebKitGTK, WPE WebKit and macOS/iOS (WKWebView) adapters. WebKitGTK and WPE WebKit share the termination-reason mapping.

Platform mapping

adapter source raised when Reason
Windows (WebView2) ICoreWebView2.ProcessFailed BrowserProcessExited, RenderProcessExited kind name (e.g. "RenderProcessExited")
macOS / iOS (WKWebView) webViewWebContentProcessDidTerminate: web content process death null (WKWebView reports no reason)
Linux (WebKitGTK) web-process-terminated Crashed / ExceededMemoryLimit / TerminatedByApi reason name
Linux (WPE WebKit) web-process-terminated Crashed / ExceededMemoryLimit / TerminatedByApi reason name

Deliberately not raised: WebView2 RenderProcessUnresponsive and GpuProcessExited (WebView2 recovers automatically from both), FrameRenderProcessExited (frame-only: the top-level document keeps running and only the affected subframes are replaced with error pages), utility/sandbox/PPAPI process exits (web content keeps running), and unspecified process kinds. Headless, Browser, WebView1 and Android adapters don't raise the event.

Testing

ProcessTerminatedTests covers the WebView2 kind filtering and reason mapping through a fake ICoreWebView2ProcessFailedEventArgs (including that frame-only exits do not raise), the shared WebKitGTK/WPE reason-name mapping, the WPE capability interface, and a headless test that the public event can be subscribed before adapter creation without breaking headless platforms. The full suite on Linux net10.0 is green (121 tests, 119 passed, 2 pre-existing skips).

Platform verification status: WebView2 wiring follows the documented ProcessFailed semantics (interop GUIDs and enum values verified against WebView2.h from the official SDK package); WebKitGTK and WPE use the web-process-terminated signal registered on the shared glib WebKitWebView; WPE has no runtime verification here because libWPEWebKit is not installed. WKWebView delegate wiring compiles for the macOS target but has no macOS runtime verification in this PR — the delegate method signature follows the WKNavigationDelegate protocol declaration.

// WebView2 recovers automatically from the rest (unresponsive, GPU process, etc.).
if (kind is COREWEBVIEW2_PROCESS_FAILED_KIND.COREWEBVIEW2_PROCESS_FAILED_KIND_BROWSER_PROCESS_EXITED
or COREWEBVIEW2_PROCESS_FAILED_KIND.COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_EXITED
or COREWEBVIEW2_PROCESS_FAILED_KIND.COREWEBVIEW2_PROCESS_FAILED_KIND_FRAME_RENDER_PROCESS_EXITED)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

FRAME_RENDER_PROCESS_EXITED seems to refer to nested iframe/frames. Not sure if we should report it as a root failure. Better to skip it for this event.

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.

Fixed in 373ea51: FRAME_RENDER_PROCESS_EXITED is no longer reported, and that case moved into the negative tests. Per the ProcessFailedKind docs the exit is frame-only — the top-level document keeps running and only the affected subframes fall back to error pages — so reporting it as a web content termination would tell hosts to recreate a live webview. Main-frame renderer crashes still arrive as RenderProcessExited, so no root failure is lost. I also dropped the LauncherProcessErrorFailed mention from the description, which does not exist in the enum.

Comment on lines +17 to +18
internal abstract class GtkWebViewAdapter : IWebViewAdapterWithFocus, IGtkWebViewPlatformHandle, IWebViewWithPrintWithOptions,
IWebViewAdapterWithProcessTermination

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The same web-process-terminated should exist in WPE linux backend. Can it be added there too?

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.

Wired up in 373ea51. WPE is first in LinuxDefaultOrder, so without this the event would never fire on the default Linux backend. web-process-terminated is registered on the shared glib WebKitWebView (Since 2.20), so the WPE adapter now raises the event from the same signal and reuses the shared reason mapping (WebKitWebProcessTermination). The handler follows the existing WPE convention and runs on the UI thread via the GLib pump. No runtime verification here since libWPEWebKit is not installed; the capability interface and mapping are covered by tests.

- WebView2: stop raising ProcessTerminated for FRAME_RENDER_PROCESS_EXITED.
  A frame-only render exit leaves the top-level document running and only
  replaces the affected subframes with error pages, so reporting it as a
  web content termination was a false positive. Main-frame renderer crashes
  still surface as RENDER_PROCESS_EXITED.
- WPE WebKit: implement IWebViewAdapterWithProcessTermination and raise the
  event from the shared glib web-process-terminated signal, matching the
  WebKitGTK adapter.
- Extract the WebKitGTK/WPE termination-reason mapping into one helper.
- Update the capability documentation and the ProcessTerminated tests.
@maxkatz6

Copy link
Copy Markdown
Member

Thank you

@maxkatz6
maxkatz6 merged commit 61084b3 into AvaloniaUI:main Oct 27, 2026
1 check passed
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.

Expose web content process failure events (crash / unresponsive) from NativeWebView

2 participants