Repository navigation
fix(gui): pin Ozone to X11 on Linux so Electron 42 stops segfaulting on Wayland (#190) - #194
Merged
Merged
Conversation
…on Wayland (#190) Electron 42 resolves its Ozone backend before the main script runs, picks Wayland on a Wayland session (Ubuntu 26.04) and segfaults creating its first window. Measured on that host: app.commandLine.appendSwitch('ozone-platform', 'x11'), ELECTRON_OZONE_PLATFORM_HINT=x11 and --ozone-platform-hint=x11 all still crash; only --ozone-platform=x11 on the real command line works. So the pin is applied by whatever starts Electron, in two layers: - Launchers we own pass it up front (scripts/launch-flags.mjs): the new dev/preview runner scripts/run-electron-vite.mjs forwards it after electron-vite's `--` separator (and keeps a backend the caller chose there), the smoke test launches with it, and the AppImage's desktop entry carries it through appImage.executableArgs together with the --no-sandbox default that setting executableArgs would otherwise drop. - For any other launcher (a bare `electron out/main/index.js`, the unpacked binary, an AppImage started from a terminal, whose AppRun only forwards its own arguments) the main process relaunches itself once with the pin (src/main/x11-relaunch.ts). It never relaunches when the caller passed any --ozone-platform… switch or ELECTRON_OZONE_PLATFORM_HINT, and inside an AppImage it relaunches $APPIMAGE, since the mount goes away with the first process. The runner and the smoke test also strip ELECTRON_RUN_AS_NODE, which editor-hosted shells export and which turns the Electron binary into plain Node. docs/GUI.md gains a Troubleshooting section for both. Verified on Ubuntu 26.04 Wayland: pnpm dev, pnpm smoke (from a VS Code shell), a bare electron launch, dist/linux-unpacked/flavian and the AppImage (extract-and-run mode, no FUSE here) all reach a live window; the two bare launches relaunch once with the pin. gui lint, typecheck and 72 unit tests pass. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #190. Part of #186.
What was actually wrong
Electron 42 resolves its Ozone (display) backend before the main script runs: with no flags on a Wayland session,
app.commandLine.getSwitchValue('ozone-platform')already readswaylandinsidemain, and the process segfaults creating its firstBrowserWindow(afterready). Measured on Ubuntu 26.04:app.commandLine.appendSwitch('ozone-platform', 'x11')in main (the fix the issue proposed)ELECTRON_OZONE_PLATFORM_HINT=x11--ozone-platform-hint=x11ozone-platform=wayland)--ozone-platform=x11on the command lineSo the pin has to come from whatever starts Electron.
The fix, two layers
packages/gui/scripts/launch-flags.mjs, one shared rule):dev,previewandstartnow go throughscripts/run-electron-vite.mjs, which forwards--ozone-platform=x11after electron-vite's--separator on Linux, keeps a backend the caller chose there, and forwards termination signals to its child.tests/smoke/smoke.mjslaunches with it, so CI under Xvfb and a local Wayland session start the app the same way.appImage.executableArgs, together with the--no-sandboxdefault that settingexecutableArgswould otherwise drop (pinned by a packaging test).ELECTRON_RUN_AS_NODE, which editor-hosted shells (VS Code) export and which turns the Electron binary into plain Node.src/main/x11-relaunch.ts): when Electron has already chosen Wayland on Linux and the caller passed no--ozone-platform…switch and noELECTRON_OZONE_PLATFORM_HINT, the app relaunches itself once with the pin. Inside an AppImage it relaunches$APPIMAGE, because the mount disappears with the first process. This covers a bareelectron out/main/index.js,dist/linux-unpacked/flavianand an AppImage started from a terminal (itsAppRunonly forwards the arguments it was given, so the desktop entry's pin does not apply there).docs/GUI.mdgains a Troubleshooting section covering both problems and the native-Wayland opt-out.Verification (Ubuntu 26.04, Wayland, from a VS Code shell with
ELECTRON_RUN_AS_NODE=1set)pnpm --filter @flavian/gui smoke: passes, no manual flags.pnpm --filter @flavian/gui dev: window opens, still running after 30 s.electron out/main/index.js: relaunches once; the surviving process iselectron --ozone-platform=x11 out/main/index.js.dist/linux-unpacked/flavian: relaunches once; survivorflavian --ozone-platform=x11.Flavian-2.1.2.AppImagefrom a terminal (extract-and-run mode, this host has no FUSE): relaunches through$APPIMAGE; survivorflavian --ozone-platform=x11. The same AppImage before this change died with exit 139.Exec=AppRun --no-sandbox --ozone-platform=x11 %U.🤖 Generated with Claude Code