diff --git a/client/ui/CLAUDE.md b/client/ui/CLAUDE.md index fe927c1d7..d7f9101b2 100644 --- a/client/ui/CLAUDE.md +++ b/client/ui/CLAUDE.md @@ -9,7 +9,7 @@ This is the Wails v3 desktop UI for NetBird. Go services live in `services/`; th ### Go (top-level package `main`) - `main.go` — app entry. Builds the shared gRPC `Conn`, constructs services, registers them with Wails, creates the main webview window, then starts (in order) the Linux SNI watcher → tray → `peers.Watch` → `app.Run`. CLI flags: `--daemon-addr`, `--log-file` (repeatable; first user-provided value drops the seeded `console` default), `--log-level` (`trace|debug|info|warn|error`, default `info`). - `tray.go` — `Tray` struct + menu. Subscribes to `EventStatus`, `EventSystem`, `EventUpdateAvailable`, `EventUpdateProgress`. Owns per-status icon/dot, Profiles submenu, Connect/Disconnect swap, About → Update, session-expired toast. -- `tray_linux.go` — `init()` sets `WEBKIT_DISABLE_DMABUF_RENDERER=1` to avoid the blank-white window on VMs / minimal WMs. +- `tray_linux.go` — `init()` sets `WEBKIT_DISABLE_DMABUF_RENDERER=1` (blank-white window on VMs / minimal WMs) and `WEBKIT_DISABLE_COMPOSITING_MODE=1` (Intel/Mesa SIGSEGV in `g_application_run` via unimplemented DRM-format-modifier paths — DMABUF-disable alone doesn't cover the GL compositor). Both are skipped if the user already set the var. Also `WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1` when unprivileged userns are blocked. - `tray_watcher_linux.go`, `xembed_host_linux.go`, `xembed_tray_linux.{c,h}` — in-process SNI watcher + XEmbed bridge for minimal WMs. See `LINUX-TRAY.md`. - `signal_unix.go` / `signal_windows.go` — `listenForShowSignal`. Unix uses SIGUSR1; Windows uses a named event `Global\NetBirdQuickActionsTriggerEvent`. Mirrors the legacy Fyne UI's external-trigger contract so the installer / CLI keep working. - `grpc.go` — lazy, mutex-protected gRPC `Conn` shared by every service. `DaemonAddr()`: `unix:///var/run/netbird.sock` on Linux/macOS, `tcp://127.0.0.1:41731` on Windows. diff --git a/client/ui/tray_linux.go b/client/ui/tray_linux.go index f732cbc9c..042b40e1b 100644 --- a/client/ui/tray_linux.go +++ b/client/ui/tray_linux.go @@ -10,6 +10,7 @@ import ( // init runs before Wails' own init(), so the env vars are set in time. func init() { disableDMABUFRenderer() + disableCompositingMode() disableWebKitSandboxIfNeeded() } @@ -26,6 +27,23 @@ func disableDMABUFRenderer() { _ = os.Setenv("WEBKIT_DISABLE_DMABUF_RENDERER", "1") } +// disableCompositingMode turns off WebKitGTK's accelerated (GL) compositing +// path. Disabling the DMA-BUF renderer alone is not enough on some Intel +// setups: WebKitGTK 2.52 still drives the GPU through the GL compositor, and +// Mesa's anv/i965 hits unimplemented DRM-format-modifier code paths +// ("FINISHME: support YUV colorspace with DRM format modifiers" / +// "...multi-planar formats...") that crash with a SIGSEGV inside +// g_application_run before the first frame paints. Forcing compositing off +// makes WebKit render on the CPU, which is fine for a small UI like this and +// sidesteps the broken modifier path. The user can re-enable it by setting +// WEBKIT_DISABLE_COMPOSITING_MODE themselves (e.g. to "0"). +func disableCompositingMode() { + if os.Getenv("WEBKIT_DISABLE_COMPOSITING_MODE") != "" { + return + } + _ = os.Setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1") +} + // disableWebKitSandboxIfNeeded works around WebKitGTK crashing at startup when // its bubblewrap (bwrap) sandbox can't create an unprivileged user namespace — // "bwrap: setting up uid map: Permission denied" followed by "Failed to fully