From 0f10b9d0da721aff31ecb155aeca39cc804c4e51 Mon Sep 17 00:00:00 2001 From: Lam Wei Lun Date: Wed, 14 Oct 2026 21:56:56 +0800 Subject: [PATCH] Linux: apply the XWayland compositing fallback only where GTK picks X11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default path set WEBKIT_DISABLE_COMPOSITING_MODE whenever DISPLAY and WAYLAND_DISPLAY were both set, but a native Wayland app inherits both, so a build with EGL disabled accelerated compositing — and with it threaded scrolling — while running on Wayland, where the XWayland bug does not apply. The only default-path case that really runs through XWayland is the forced GDK_BACKEND=x11 used when wx lacks EGL, so set the variable there. The backend cannot be re-checked later: that branch exports GDK_BACKEND itself, so the force and a user's GDK_BACKEND=x11 opt-in, which deliberately keeps compositing, would be indistinguishable. Behaviour is unchanged for WebKitGTK >= 2.42, where the gate already skipped the variable, and for builds without EGL. A build with EGL on WebKitGTK < 2.42 in a Wayland session no longer loses compositing and threaded scrolling. The wxWidgets skill reference is updated to match. --- .../orca-wxwidgets/references/platforms.md | 6 ++-- .../references/webview-gl-aui-media.md | 25 ++++++++------- src/OrcaSlicer.cpp | 32 +++++++------------ 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/.claude/skills/orca-wxwidgets/references/platforms.md b/.claude/skills/orca-wxwidgets/references/platforms.md index 6ccdcc134b..0ec78aaa43 100644 --- a/.claude/skills/orca-wxwidgets/references/platforms.md +++ b/.claude/skills/orca-wxwidgets/references/platforms.md @@ -575,8 +575,10 @@ paths, when `/proc/driver/nvidia/version` exists and the linked WebKitGTK honour `WebView::SupportsForceSharedMemory()`), it sets `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` and `WEBKIT_FORCE_DMABUF_RENDERER=1` (non-replacing): the proprietary driver cannot back WebKit's hardware DMABUF renderer. On the default path it forces `GDK_BACKEND=x11` when wx lacks EGL and `WAYLAND_DISPLAY` -is set. It sets `WEBKIT_DISABLE_COMPOSITING_MODE=1` (non-replacing) only when both `DISPLAY` and -`WAYLAND_DISPLAY` are set and the linked WebKitGTK is older than 2.42, and calls `XInitThreads()` +is set, and sets `WEBKIT_DISABLE_COMPOSITING_MODE=1` (non-replacing) inside that branch when the linked +WebKitGTK is older than 2.42: a forced X11 backend in a Wayland session is the only default-path case +that runs through XWayland, which `DISPLAY` and `WAYLAND_DISPLAY` alone do not tell you (a native +Wayland app inherits both). It calls `XInitThreads()` only when `DISPLAY` is set. With neither variable set, the GUI refuses to start ("Neither DISPLAY nor WAYLAND_DISPLAY set"). The details and the WebKit rules (c12912e0df) are in `references/webview-gl-aui-media.md` §WebKitGTK on Linux sessions. diff --git a/.claude/skills/orca-wxwidgets/references/webview-gl-aui-media.md b/.claude/skills/orca-wxwidgets/references/webview-gl-aui-media.md index 5eeb003c67..e7ff4fadde 100644 --- a/.claude/skills/orca-wxwidgets/references/webview-gl-aui-media.md +++ b/.claude/skills/orca-wxwidgets/references/webview-gl-aui-media.md @@ -61,8 +61,8 @@ available; GTK2/WebKit1 is an opt-out configuration the GUI does not support. 11. A web host that re-themes in place handles `EVT_WEBVIEW_RECREATED` without `Skip()`; one that needs a reload lets it through. §[Orca wrapper](#orca-webview-wrapper-widgetswebview) 12. Keep `WebViewWebKit`'s destructor removing the `"wx"` handler. §[Orca wrapper](#orca-webview-wrapper-widgetswebview) -13. Do not widen `WEBKIT_DISABLE_COMPOSITING_MODE` beyond Orca's default-path XWayland case for - WebKitGTK older than 2.42, and never +13. Do not widen `WEBKIT_DISABLE_COMPOSITING_MODE` beyond the no-EGL default path where Orca forces + `GDK_BACKEND=x11`, for WebKitGTK older than 2.42, and never make a page's progress depend only on a C++→JS callback. §[WebKitGTK on Linux](#webkitgtk-on-linux-sessions) 14. GL attribute lists: legacy `int[]` lists end with `0` and spell out `WX_GL_RGBA` and `WX_GL_DOUBLEBUFFER`; `wxGLAttributes`/`wxGLContextAttrs` end with `EndList()`; MSAA is requested @@ -576,11 +576,12 @@ sets the NVIDIA DMABUF workaround and then branches on `GDK_BACKEND`: accelerated compositing instead of dropping it; `WEBKIT_FORCE_DMABUF_RENDERER` clears the Debian/Ubuntu/openSUSE `isNVIDIA()` early return, which otherwise returns before the FORCE_SHM check. - **Default path** (`GDK_BACKEND` unset or not starting with `x11`): if wx lacks EGL (`!wxHAS_EGL`) and - `WAYLAND_DISPLAY` is set, it forces `GDK_BACKEND=x11`; it sets `WEBKIT_DISABLE_COMPOSITING_MODE=1` - non-replacing **only** when the linked WebKitGTK predates 2.42 (`WebView::NeedsCompositingWorkaround()`) - **and** both `DISPLAY` and `WAYLAND_DISPLAY` are non-empty (a Wayland session with - XWayland available — the session, not the backend GTK will pick); `XInitThreads()` runs only when - `DISPLAY` is set. + `WAYLAND_DISPLAY` is set, it forces `GDK_BACKEND=x11`, and in that same branch it sets + `WEBKIT_DISABLE_COMPOSITING_MODE=1` non-replacing when the linked WebKitGTK predates 2.42 + (`WebView::NeedsCompositingWorkaround()`). That forced X11 backend in a Wayland session is the only + default-path case that really runs through XWayland; `DISPLAY` and `WAYLAND_DISPLAY` alone do not + identify it, because a native Wayland app inherits both. `XInitThreads()` runs only when `DISPLAY` is + set. - **`GDK_BACKEND=x11…` opt-in path**: sets `DRI_PRIME=1` (and the NVIDIA PRIME variables when `/proc/driver/nvidia/version` exists), calls `XInitThreads()`, and deliberately does **not** disable compositing, which keeps hardware acceleration for Device / Setup Wizard / login pages. @@ -613,8 +614,9 @@ Runtime backend detection elsewhere uses Orca's `is_running_on_wayland()` / `is_ ``` Cite: WebKit 2.52.6 `Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.cpp` (`rendererBufferTransportMode()`), Debian `disable-nvidia-dmabuf.patch`, WebKit bug 262607. -- **Rule:** Set `WEBKIT_DISABLE_COMPOSITING_MODE` only on the default path in Wayland sessions, - non-replacing (`setenv(..., false)`, so a value the user already exported wins), before GTK +- **Rule:** Set `WEBKIT_DISABLE_COMPOSITING_MODE` only on the default path, in the branch where wx + lacks EGL and Orca forces `GDK_BACKEND=x11`, non-replacing (`setenv(..., false)`, so a value the user + already exported wins), before GTK initialises; never unconditionally, and only for the WebKitGTK releases that need it (older than 2.42, `WebView::NeedsCompositingWorkaround()`). Keep JS-side fallbacks so a page never waits forever for a C++→JS call. @@ -626,8 +628,9 @@ Runtime backend detection elsewhere uses Orca's `is_running_on_wayland()` / `is_ // Wrong: unconditional, kills HW acceleration everywhere ::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", false); // Right (default path only): non-replacing, before GTK init, WebKitGTK < 2.42, - // Wayland session with XWayland - if (WebView::NeedsCompositingWorkaround() && display && *display && wayland && *wayland) + // and only in the branch that forces GDK_BACKEND=x11 (wx without EGL), the + // case that runs through XWayland + if (WebView::NeedsCompositingWorkaround() && wayland && *wayland) ::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /*replace*/ false); ``` Cite: c12912e0df (`src/OrcaSlicer.cpp`; `resources/web/guide/0/load.js` `OnInit` diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index 1f003b936d..c06d21b2e6 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -1154,9 +1154,10 @@ int CLI::run(int argc, char **argv) // opt-in path. The ~2020-era WebKit2GTK XWayland compositor bug it // worked around appears fixed in WebKit2GTK >= 2.42; leaving it // unset preserves WebKit hardware acceleration on Device / Setup - // Wizard / login / store. The default path applies it only on - // XWayland sessions and only when the linked WebKitGTK predates the - // fix (< 2.42), as a conservative fallback for older WebKit. + // Wizard / login / store. The default path applies it only where it + // forces GDK_BACKEND=x11 below (a build without EGL, so the app really + // runs through XWayland), and only when the linked WebKitGTK predates + // the fix (< 2.42), as a conservative fallback for older WebKit. // ------------------------------------------------------------------ { const char* gdk_backend = ::getenv("GDK_BACKEND"); @@ -1211,27 +1212,18 @@ int CLI::run(int argc, char **argv) if (wayland_env && *wayland_env) { BOOST_LOG_TRIVIAL(warning) << "Wayland detected but wxWidgets has no EGL support (wxHAS_EGL is OFF). Forcing X11 backend."; ::setenv("GDK_BACKEND", "x11", true); + + // GTK will use X11 in a Wayland session here, which is the + // one default-path case that really runs through XWayland. + // WebKit2GTK accelerated compositing could fail silently + // there on releases before 2.42, so force it off. Disabling + // it also turns off threaded scrolling, hence the gate. + if (WebView::NeedsCompositingWorkaround()) + ::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /* replace */ false); } } #endif - // WebKit2GTK accelerated compositing could fail under XWayland - // on WebKit releases before 2.42. Disable it only then, and only - // when both DISPLAY and WAYLAND_DISPLAY are set. Those two mean the - // session offers XWayland, not that GTK picked X11 for this - // process: a native Wayland app inherits both. The default path - // runs X11 here only in a build without EGL, which is what the - // forced GDK_BACKEND=x11 above produces. Disabling compositing also - // turns off threaded scrolling, so on newer WebKit it only costs - // performance. - { - const char* display_env_wk = ::getenv("DISPLAY"); - const char* wayland_env_wk = ::getenv("WAYLAND_DISPLAY"); - if (WebView::NeedsCompositingWorkaround() && display_env_wk && *display_env_wk && wayland_env_wk && *wayland_env_wk) { - ::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /* replace */ false); - } - } - // XInitThreads is needed before GStreamer may use Xlib. On // native Wayland without DISPLAY, GStreamer uses waylandsink // (no Xlib involved), so the call is skipped.