Skip to main content

Crate webkit2gtk_nvidia_quirk

Crate webkit2gtk_nvidia_quirk 

Source
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 TypeWorkaroundEnvironment Variable
X11Disable DMABUF rendererWEBKIT_DISABLE_DMABUF_RENDERER=1
Wayland (Hyprland)Disable DMABUF rendererWEBKIT_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:

  1. If the primary/boot GPU (via boot_display or boot_vga attributes) has vendor ID 0x10de
  2. If any enumerated GPU’s device/driver symlink (e.g. /sys/class/drm/card0/device/driver) resolves to a driver named nvidia

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 note
  • debug / 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-wayland2 state, 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 needed
  • DisableWebkitDmabufRenderer: 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§

ApplyWorkaroundOptions
Builder struct for configuring which workarounds to force-apply.

Enums§

WorkaroundKind
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 true when the running compositor is known to use a tiling layout.
is_wayland_session
Returns true when the application is running in a Wayland session.
is_x11_session
Returns true when 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_SYNC environment variable.
set_webkit_disable_dmabuf_renderer
Sets the WEBKIT_DISABLE_DMABUF_RENDERER environment variable.