fix(linux): X11NativeWebView exports GDK_BACKEND=x11 by jonpryor · Pull Request #23635 · unoplatform/uno · GitHub
Skip to content

fix(linux): X11NativeWebView exports GDK_BACKEND=x11#23635

Open
jonpryor wants to merge 1 commit into
masterfrom
dev/jonpryor/jonp-Linux-WebView2-export-GDK_BACKEND
Open

fix(linux): X11NativeWebView exports GDK_BACKEND=x11#23635
jonpryor wants to merge 1 commit into
masterfrom
dev/jonpryor/jonp-Linux-WebView2-export-GDK_BACKEND

Conversation

@jonpryor

@jonpryor jonpryor commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Fixes: #23159

Context: dotnet/runtime#4538 (comment)
Context:

Use of WebView2 on Linux Wayland requires that the GDK_BACKEND environment variable be set, lest Bad Things Happen™.

On the ignorable side, the bad things are simply messages written to stdout. For example, build and run SamplesApp.Skia.Generic:

dotnet build -c Release -f net10.0 src/SamplesApp/SamplesApp.Skia.Generic/SamplesApp.Skia.Generic.csproj
LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libfreetype.so.6.20.1 \
  dotnet src/SamplesApp/SamplesApp.Skia.Generic/bin/Release/net10.0/SamplesApp.Skia.Generic.dll

(The $LD_PRELOAD is needed to avoid a different problem, which should get fixed by updating SkiaSharp; see #23598.)

Once SamplesApp.Skia.Generic has launched:

  1. Click the "checkbox list" icon on the top-left to show the RuntimeTests panel.
  2. In the "Enter test filter here" textbox, enter When_ExecuteScriptAsync.
  3. Click the ▶️ Run button

Console output will contain messages such as:

(SamplesApp.Skia.Generic:25303): Gdk-CRITICAL **: 09:20:32.946: gdk_x11_window_get_xid: assertion 'GDK_IS_X11_WINDOW (window)' failed
…
fail: Uno.UI.WebView.Skia.X11.X11NativeWebView[0]
      SetScrollingEnabled is not supported on the X11 target.
…
warn: Uno.WinUI.Runtime.Skia.X11.X11ApplicationHost[0]
      X11 protocol error — ErrorCode: 3, RequestCode: X_UnmapWindow, MinorCode: 0, ResourceId: 0x0, Serial: 428

However, the tests pass and the app doesn't crash.

Enter #23159: if we build Uno.Gallery for Native AOT and hit the WebView2 logic, we see the same Gdk-CRITICAL message, and also these messages:

fail: Uno.WinUI.Runtime.Skia.X11.X11NativeOverlappedPresenter[0]
      Couldn't get OverlappedPresenterState: _NET_WM_STATE does not exist on the window. Make sure you use an EWMH-compliant WM.
fail: Uno.WinUI.Runtime.Skia.X11.X11NativeOverlappedPresenter[0]
      Couldn't get OverlappedPresenterState: _NET_WM_STATE does not exist on the window. Make sure you use an EWMH-compliant WM.

followed by a hard crash:

(Uno.Gallery:8586): Gdk-CRITICAL **: 14:46:16.851: gdk_x11_window_get_xid: assertion 'GDK_IS_X11_WINDOW (window)' failed
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  3 (X_GetWindowAttributes)
  Resource id in failed request:  0x0
  Serial number of failed request:  103
  Current serial number in output stream:  104

The workaround for this, as documented in
doc/articles/controls/WebView.md, is to export the GDK_BACKEND environment variable to x11:

export GDK_BACKEND=x11
dotnet …

This works, but requires reading documentation (who does that?!).

The ideal fix would be to have X11NativeWebProvider export the environment variable during app startup. The problem is that the "obvious" way to do this:

Environment.SetEnvironmentVariable("GDK_BACKEND", "x11");

does not work

we will not support the case where a user wants to modify the
environment from managed code and expects to see those changes
reflected in a native library they PInvoke to, or vice versa.

Since we need native code in libgdk* et al to see the GDK_BACKEND environment variable, we can't use
Environment.SetEnvironmentVariable() to do so.

Instead, P/Invoke into setenv(3). This allows us to set the GDK_BACKEND environment variable on the native side, allowing libdk* et al to see the value we set and behave accordingly.

With this fix in place, SamplesApp.Skia.Generic.dll no longer produces the Gdk-CRITICAL or X11 protocol error messages.

GitHub Issue: closes #

PR Type:

What changed? 🚀

PR Checklist ✅

Fixes: #23159

Context: dotnet/runtime#4538 (comment)
Context: https://github.com/unoplatform/uno/blob/ffbb0c0ed47679ede7c67effaa979e7a9934ed33/doc/articles/controls/WebView.md?plain=1#L198-L206

Use of WebView2 on Linux Wayland requires that the `GDK_BACKEND`
environment variable be set, lest Bad Things Happen™.

On the ignorable side, the bad things are simply messages written
to stdout.  For example, build and run SamplesApp.Skia.Generic:

	dotnet build -c Release -f net10.0 src/SamplesApp/SamplesApp.Skia.Generic/SamplesApp.Skia.Generic.csproj
	LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libfreetype.so.6.20.1 \
	  dotnet src/SamplesApp/SamplesApp.Skia.Generic/bin/Release/net10.0/SamplesApp.Skia.Generic.dll

(The $LD_PRELOAD is needed to avoid [a *different* problem][0], which
should get fixed by updating SkiaSharp; see #23598.)

Once SamplesApp.Skia.Generic has launched:

 1. Click the "checkbox list" icon on the top-left to show the
    RuntimeTests panel.
 2. In the "Enter test filter here" textbox, enter
    `When_ExecuteScriptAsync`.
 3. Click the ▶️ Run button

Console output will contain messages such as:

	(SamplesApp.Skia.Generic:25303): Gdk-CRITICAL **: 09:20:32.946: gdk_x11_window_get_xid: assertion 'GDK_IS_X11_WINDOW (window)' failed
	…
	fail: Uno.UI.WebView.Skia.X11.X11NativeWebView[0]
	      SetScrollingEnabled is not supported on the X11 target.
	…
	warn: Uno.WinUI.Runtime.Skia.X11.X11ApplicationHost[0]
	      X11 protocol error — ErrorCode: 3, RequestCode: X_UnmapWindow, MinorCode: 0, ResourceId: 0x0, Serial: 428

However, the tests *pass* and the app *doesn't crash*.

Enter #23159: if we build Uno.Gallery for *Native AOT* and hit the
WebView2 logic, we see the same `Gdk-CRITICAL` message, *and also*
these messages:

	fail: Uno.WinUI.Runtime.Skia.X11.X11NativeOverlappedPresenter[0]
	      Couldn't get OverlappedPresenterState: _NET_WM_STATE does not exist on the window. Make sure you use an EWMH-compliant WM.
	fail: Uno.WinUI.Runtime.Skia.X11.X11NativeOverlappedPresenter[0]
	      Couldn't get OverlappedPresenterState: _NET_WM_STATE does not exist on the window. Make sure you use an EWMH-compliant WM.

followed by a *hard crash*:

	(Uno.Gallery:8586): Gdk-CRITICAL **: 14:46:16.851: gdk_x11_window_get_xid: assertion 'GDK_IS_X11_WINDOW (window)' failed
	X Error of failed request:  BadWindow (invalid Window parameter)
	  Major opcode of failed request:  3 (X_GetWindowAttributes)
	  Resource id in failed request:  0x0
	  Serial number of failed request:  103
	  Current serial number in output stream:  104

The workaround for this, as documented in
`doc/articles/controls/WebView.md`, is to export the `GDK_BACKEND`
environment variable to `x11`:

	export GDK_BACKEND=x11
	dotnet …

This works, but requires reading documentation (who does that?!).

The ideal fix would be to have `X11NativeWebProvider` export the
environment variable during app startup.  The problem is that the
"obvious" way to do this:

	Environment.SetEnvironmentVariable("GDK_BACKEND", "x11");

[*does not work*][1]

> we will not support the case where a user wants to modify the
> environment from managed code and expects to see those changes
> reflected in a native library they PInvoke to, or vice versa.

Since we *need* native code in `libgdk*` et al to see the
`GDK_BACKEND` environment variable, we can't use
`Environment.SetEnvironmentVariable()` to do so.

Instead, P/Invoke into **setenv**(3).  This allows us to set the
`GDK_BACKEND` environment variable on the native side, allowing
`libdk*` et al to see the value we set and behave accordingly.

With this fix in place, `SamplesApp.Skia.Generic.dll` no longer
produces the `Gdk-CRITICAL` or X11 protocol error messages.

[0]: #20532 (comment)
[1]: dotnet/runtime#4538 (comment)
Copilot AI review requested due to automatic review settings July 3, 2026 14:06

Copilot AI 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.

Pull request overview

This PR addresses Linux (Skia/X11) crashes and GDK/X11 errors when using WebView2 under Wayland by ensuring GDK_BACKEND is set to x11 from the native side (via setenv(3)) before GTK/WebKit initialization, aligning with the documented workaround for issue #23159.

Changes:

  • Add a libc P/Invoke for setenv(3) in X11NativeWebView.
  • Invoke setenv("GDK_BACKEND", "x11", overwrite: 0) early in the X11NativeWebView static constructor and log errno on failure.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@unodevops

Copy link
Copy Markdown
Contributor

🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-23635/wasm-skia-net9/index.html

@unodevops

Copy link
Copy Markdown
Contributor

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.

[X11] WebView2 crash on Linux

5 participants