Expand description
§webkit2gtk-nvidia-quirk
A crate that provides session-aware workarounds for WebKitGTK rendering issues on Linux systems with the proprietary NVIDIA driver.
§Problem
When running WebKitGTK-based applications (such as Tauri apps) on Linux with the proprietary NVIDIA driver, rendering issues occur that vary by session type:
- X11: The DMABUF renderer causes blank windows
- Wayland (Hyprland): The DMABUF renderer violates the compositor’s acquire-point rule (a protocol error that kills the client) and its NVIDIA EGL/GBM render path SIGSEVs during rendering
- Wayland (other): The application may not start unless NVIDIA explicit sync is disabled
Related upstream issues:
§Solution
This crate detects the proprietary NVIDIA driver and the session type (X11/Wayland), then applies the appropriate workaround:
| Session Type | Workaround | Environment Variable |
|---|---|---|
| X11 | Disable DMABUF renderer | WEBKIT_DISABLE_DMABUF_RENDERER=1 |
| Wayland (Hyprland) | Disable DMABUF renderer | WEBKIT_DISABLE_DMABUF_RENDERER=1 |
Wayland (other, egl-wayland2) | none | - |
| Wayland (other) | Disable NVIDIA explicit sync | __NV_DISABLE_EXPLICIT_SYNC=1 |
The session type is taken from GDK_BACKEND first (the backend GDK/WebKitGTK
actually selects, a comma-separated list where the first recognized entry of
x11/wayland wins; unrecognized entries such as broadway are ignored),
then XDG_SESSION_TYPE, then WAYLAND_DISPLAY/DISPLAY.
§Wayland
WebKitGTK’s DMA-BUF renderer enables the Wayland explicit sync protocol on
the window surface but does not always set an acquire point before
committing. Compositors differ in how strictly they enforce this: Hyprland
answers with a protocol error that kills the connection (Gdk-Message: Error 71 (Protocol error) dispatching to Wayland display, WebKitGTK bug
#280210), while others
such as niri tolerate the missing acquire point. The DMA-BUF renderer is
therefore disabled on Hyprland, which also avoids a separate NVIDIA EGL/GBM
SIGSEGV that occurs during rendering there. On compositors that tolerate the
missing acquire point, the dma-buf based egl-wayland2 library (NVIDIA
driver 560 or newer) is treated as working and the workaround is skipped,
since disabling explicit sync would degrade rendering performance; on those
compositors without egl-wayland2, NVIDIA explicit sync is disabled.
Detecting egl-wayland2 mirrors the EGL loader logic: the external platform
JSON manifests in /etc/egl/egl_external_platform.d and
/usr/share/egl/egl_external_platform.d (or the directories/files given via
__EGL_EXTERNAL_PLATFORM_CONFIG_DIRS/__EGL_EXTERNAL_PLATFORM_CONFIG_FILENAMES)
are checked in load order against /proc/driver/nvidia/version. Inside a
Flatpak sandbox neither /proc nor the host /etc//usr directories are
visible, so egl-wayland2 is reported as not active and the workaround is
applied - safe, but not perf-optimal for sandboxed apps on a 560+ driver.
§Detection Method
The crate detects the NVIDIA driver by:
- If the primary/boot GPU (via
boot_displayorboot_vgaattributes) has vendor ID 0x10de - If any enumerated GPU’s
device/driversymlink (e.g./sys/class/drm/card0/device/driver) resolves to a driver namednvidia
GPU detection uses sysfs exclusively (/sys/class/drm/). This provides a simpler and
more reliable detection mechanism with no external runtime dependencies.
This specifically targets the proprietary NVIDIA driver, not the open-source nouveau driver.
§Sandboxed environments (Flatpak)
GPU and NVIDIA-driver detection reads are scoped to /sys/class/drm, which is one of the
sysfs subtrees Flatpak shares read-only with sandboxed apps by default (/sys/block,
/sys/bus, /sys/class, /sys/dev, /sys/devices). Earlier versions checked
/sys/module/nvidia directly, which is not part of that default allowlist and would
always be reported as missing inside a Flatpak sandbox, silently disabling the workaround.
Deriving driver detection from the device/driver symlink avoids that problem.
Session type detection also has a sandbox-aware fallback (see below).
§Usage
use webkit2gtk_nvidia_quirk::{ApplyWorkaroundOptions, apply_workaround_with_options};
let disable_dmabuf = std::env::args().any(|arg| arg == "--disable-dmabuf-renderer");
let disable_nv_sync = std::env::args().any(|arg| arg == "--disable-nv-explicit-sync");
let options = ApplyWorkaroundOptions::default()
.force_disable_dmabuf(disable_dmabuf)
.force_disable_nv_explicit_sync(disable_nv_sync);
apply_workaround_with_options(options);§API
§is_primary_gpu_nvidia() -> bool
Checks whether the primary GPU is an NVIDIA GPU.
Returns true if the primary GPU (boot_display or boot_vga attribute) has vendor ID 0x10de (NVIDIA),
Returns false otherwise. This function does not check kernel module loading.
§needs_workaround() -> WorkaroundKind
Determines which workaround should be applied based on NVIDIA detection and session type.
Returns WorkaroundKind::None if no workaround is needed, WorkaroundKind::DisableWebkitDmabufRenderer
for X11 sessions, or WorkaroundKind::DisableNvExplicitSync for Wayland sessions.
§set_webkit_disable_dmabuf_renderer(verbose: bool)
Sets the WEBKIT_DISABLE_DMABUF_RENDERER environment variable. Use this for X11 sessions.
The verbose argument controls whether a diagnostic note is printed to stderr
(the WEBKIT2GTK_NVIDIA_QUIRK_VERBOSE environment variable also enables it at the
Note level, and additionally prints a detection summary at the Debug level).
§nv_disable_explicit_sync(verbose: bool)
Sets the __NV_DISABLE_EXPLICIT_SYNC environment variable. Use this for Wayland sessions.
The verbose argument controls whether a diagnostic note is printed to stderr
(the WEBKIT2GTK_NVIDIA_QUIRK_VERBOSE environment variable also enables it at the
Note level, and additionally prints a detection summary at the Debug level).
§WEBKIT2GTK_NVIDIA_QUIRK_VERBOSE (environment variable)
Controls diagnostic output to stderr and is independent of the verbose
builder/bool arguments:
- unset /
0/false/off-> no output 1/true/yes/on-> print the per-workaround diagnostic notedebug/trace/verbose/2-> print the note and a detection summary (session type, primary-GPU NVIDIA, whether the NVIDIA driver is loaded, detected compositor, Hyprland,egl-wayland2state, the chosen workaround, and which workaround environment variables are set)
The debug detection trace is intentionally env-var controlled only; the builder API cannot enable it.
§apply_workaround_with_options(options: ApplyWorkaroundOptions)
Convenience function that applies workarounds based on the provided options.
If any force options are set, it applies those directly. Otherwise, it calls
needs_workaround to detect which workaround is needed.
This is the recommended way to apply workarounds from CLI arguments.
§WorkaroundKind
Enum representing the type of workaround to apply:
None: No workaround neededDisableWebkitDmabufRenderer: Disable the DMABUF renderer (for X11)DisableNvExplicitSync: Disable NVIDIA explicit sync (for Wayland)
§ApplyWorkaroundOptions
Builder struct for configuring which workarounds to force-apply. Use the builder pattern to set options:
use webkit2gtk_nvidia_quirk::{ApplyWorkaroundOptions, apply_workaround_with_options};
let options = ApplyWorkaroundOptions::default()
.force_disable_dmabuf(true);
apply_workaround_with_options(options);§Platform Support
This crate is Linux-only and provides no functionality on other platforms.
Structs§
- Apply
Workaround Options - Builder struct for configuring which workarounds to force-apply.
Enums§
- Workaround
Kind - Represents the type of workaround to apply for NVIDIA WebKitGTK issues.
Functions§
- apply_
workaround_ with_ options - Applies workarounds based on the provided options.
- is_
primary_ gpu_ nvidia - Checks if the primary GPU is an NVIDIA GPU.
- is_
tiling_ compositor - Returns
truewhen the running compositor is known to use a tiling layout. - is_
wayland_ session - Returns
truewhen the application is running in a Wayland session. - is_
x11_ session - Returns
truewhen the application is running in an X11 session. - needs_
workaround - Checks if a workaround should be applied.
- nv_
disable_ explicit_ sync - Sets the
__NV_DISABLE_EXPLICIT_SYNCenvironment variable. - set_
webkit_ disable_ dmabuf_ renderer - Sets the
WEBKIT_DISABLE_DMABUF_RENDERERenvironment variable.