From a9b9f992865375352733cec82d9bcc8a7548264c Mon Sep 17 00:00:00 2001 From: Rage Lopez Date: Sat, 23 May 2026 19:49:11 -0500 Subject: [PATCH 1/2] feat(launcher): add Wayland GPU rendering profile --- CHANGELOG.md | 4 ++++ README.md | 4 ++-- launcher/start.sh.template | 24 +++++++++++++++++++----- tests/scripts_smoke.sh | 10 ++++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28d642b7..e94e5447 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). ### Added +- Launcher rendering mode `CODEX_LINUX_RENDERING_MODE=wayland-gpu`, which + forces native Wayland with GPU compositing enabled and skips forced renderer + accessibility by default for Wayland desktops where XWayland or software + rendering is unstable. - New opt-in Linux feature `read-aloud-mcp` that stages a standalone Rust Read Aloud MCP plugin with `doctor`, `read_aloud`, and `stop` tools. The MCP server reuses the Kokoro runner/model configuration from the Read Aloud UI feature diff --git a/README.md b/README.md index 04d83059..a52bf77b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Optional Linux-only additions live in `linux-features/`. Use them for integratio | Atomic desktops / other Linux distros | none | `.AppImage` | Local self-build only; no bundled auto-updater | | NixOS / Nix | flake | runnable directly | `nix run github:ilysenko/codex-desktop-linux` | -Anything systemd-based should work for the optional auto-updater service (`systemd --user`). The launcher targets Wayland with `XWayland` first (better Electron popup positioning); pure Wayland sessions fall through to `--ozone-platform-hint=auto`. X11 is fully supported. +Anything systemd-based should work for the optional auto-updater service (`systemd --user`). The launcher targets Wayland with `XWayland` first (better Electron popup positioning); pure Wayland sessions fall through to `--ozone-platform-hint=auto`. X11 is fully supported. If XWayland or software rendering is unstable on a Wayland desktop, `CODEX_LINUX_RENDERING_MODE=wayland-gpu` forces native Wayland while keeping GPU compositing enabled. ## What you get @@ -528,7 +528,7 @@ make clean-state | `CODEX_CLI_PATH` error | Reopen the app to retry the automatic CLI install flow, or install manually with `npm i -g @openai/codex` / `npm i -g --prefix ~/.local @openai/codex` | | `gh auth status` works in a terminal but fails inside Codex Desktop | The app shell may be using isolated XDG paths or missing keyring DBus access. See [GitHub CLI auth in app-launched shells](docs/github-cli-auth.md) | | Electron hangs while CLI is outdated | Re-run the launcher and check `~/.cache/codex-desktop/launcher.log` plus `~/.local/state/codex-update-manager/service.log`. Best-effort CLI preflight will warn if the automatic refresh fails | -| GPU / Vulkan / Wayland errors | Under Wayland with `DISPLAY` available, the launcher uses `--ozone-platform=x11` for window-positioning compatibility. Otherwise it uses `--ozone-platform-hint=auto`. The GPU sandbox is disabled by default, while GPU compositing stays enabled | +| GPU / Vulkan / Wayland errors | Under Wayland with `DISPLAY` available, the launcher uses `--ozone-platform=x11` for window-positioning compatibility. Otherwise it uses `--ozone-platform-hint=auto`. The GPU sandbox is disabled by default, while GPU compositing stays enabled. On desktops where XWayland or software rendering hangs, such as some COSMIC/NVIDIA sessions, try `CODEX_LINUX_RENDERING_MODE=wayland-gpu ./codex-app/start.sh` | | Window flickering | Try `CODEX_ELECTRON_DISABLE_GPU_COMPOSITING=1 ./codex-app/start.sh` to use the legacy compositing workaround. If flickering persists, try `./codex-app/start.sh --disable-gpu` to fully disable GPU acceleration | | Sandbox errors | The launcher already sets `--no-sandbox` | | Stale install / cached DMG | `make build-app-fresh` removes the existing install dir and cached DMG, then re-downloads | diff --git a/launcher/start.sh.template b/launcher/start.sh.template index b366da43..98e92ba6 100644 --- a/launcher/start.sh.template +++ b/launcher/start.sh.template @@ -218,12 +218,13 @@ Default launch keeps Electron GPU enabled and lets Electron choose the platform. Extra flags are passed directly to Electron. Environment: - CODEX_LINUX_RENDERING_MODE=auto|default|wslg - Auto-detect WSLg, keep generic Linux defaults, or force the WSLg profile + CODEX_LINUX_RENDERING_MODE=auto|default|wslg|wayland-gpu + Auto-detect WSLg, keep generic Linux defaults, force the WSLg profile, + or force native Wayland with GPU compositing enabled CODEX_ELECTRON_DISABLE_GPU_COMPOSITING=0|1 Set to 1 to add --disable-gpu-compositing for flicker workarounds CODEX_FORCE_RENDERER_ACCESSIBILITY=auto|0|1 - Override --force-renderer-accessibility; auto skips it under WSLg + Override --force-renderer-accessibility; auto skips it under WSLg and wayland-gpu CODEX_MULTI_LAUNCH=1 Treat normal launches like --new-instance CODEX_MULTI_LAUNCH_PORT_RANGE=START-END Port allocation range for --new-instance (default: CODEX_WEBVIEW_PORT through +4) @@ -1735,7 +1736,7 @@ is_wslg_session() { normalize_linux_rendering_mode() { case "${CODEX_LINUX_RENDERING_MODE:-auto}" in - auto|default|wslg) + auto|default|wslg|wayland-gpu) echo "${CODEX_LINUX_RENDERING_MODE:-auto}" ;; *) @@ -1797,6 +1798,13 @@ apply_electron_rendering_profile() { default) return 0 ;; + wayland-gpu) + if [ "$ELECTRON_PLATFORM_EXPLICIT" -eq 0 ] && [ "$ELECTRON_OZONE_SWITCH_IN_ARGS" -eq 0 ]; then + ELECTRON_OZONE_PLATFORM="wayland" + ELECTRON_OZONE_HINT="" + fi + return 0 + ;; esac [ "$ELECTRON_RENDERING_MODE" = "wslg" ] || return 0 @@ -1847,7 +1855,13 @@ should_force_renderer_accessibility() { esac fi - [ "$ELECTRON_RENDERING_MODE" != "wslg" ] + case "$ELECTRON_RENDERING_MODE" in + wslg|wayland-gpu) + return 1 + ;; + esac + + return 0 } set_electron_defaults() { diff --git a/tests/scripts_smoke.sh b/tests/scripts_smoke.sh index f8672e79..fe27ec0b 100755 --- a/tests/scripts_smoke.sh +++ b/tests/scripts_smoke.sh @@ -2088,6 +2088,15 @@ PY [[ "$output" == *"electron=<--ozone-platform=x11>"* ]] || fail "pass-through ozone platform must reach Electron: $output" [[ "$output" != *"<--ozone-platform-hint=auto>"* ]] || fail "launcher must not add ozone hint when pass-through supplies an ozone platform: $output" + output="$(env -i PATH="$PATH" HOME="$HOME" CODEX_LINUX_RENDERING_MODE=wayland-gpu "$launcher_probe" probe)" + [[ "$output" == *"mode=wayland-gpu"* && "$output" == *"ozone_platform=wayland"* && "$output" == *"gpu=1"* ]] || fail "wayland-gpu profile must force native Wayland with GPU enabled: $output" + [[ "$output" == *"comp=0"* && "$output" != *"<--disable-gpu-compositing>"* ]] || fail "wayland-gpu profile must keep GPU compositing enabled: $output" + [[ "$output" == *"<--ozone-platform=wayland>"* && "$output" == *"<--enable-features=WaylandWindowDecorations>"* ]] || fail "wayland-gpu profile must add Wayland launch args: $output" + [[ "$output" == *"renderer_accessibility=0"* && "$output" != *"<--force-renderer-accessibility>"* ]] || fail "wayland-gpu profile must skip renderer accessibility by default: $output" + + output="$(env -i PATH="$PATH" HOME="$HOME" CODEX_LINUX_RENDERING_MODE=wayland-gpu CODEX_FORCE_RENDERER_ACCESSIBILITY=1 "$launcher_probe" probe)" + [[ "$output" == *"renderer_accessibility=1"* && "$output" == *"<--force-renderer-accessibility>"* ]] || fail "CODEX_FORCE_RENDERER_ACCESSIBILITY=1 must force renderer accessibility under wayland-gpu: $output" + output="$(env -i PATH="$PATH" HOME="$HOME" CODEX_LINUX_RENDERING_MODE=wslg "$launcher_probe" probe)" [[ "$output" == *"mode=wslg"* && "$output" == *"comp=0"* && "$output" == *"gl_added=1"* ]] || fail "forced WSLg profile must keep GPU compositing enabled and add ANGLE: $output" [[ "$output" == *"<--ozone-platform=x11>"* && "$output" == *"electron=<--use-gl=angle>"* ]] || fail "forced WSLg profile must use X11 and ANGLE by default: $output" @@ -2142,6 +2151,7 @@ PY assert_contains "$REPO_DIR/launcher/start.sh.template" '--app-id="$CODEX_LINUX_APP_ID"' assert_contains "$REPO_DIR/scripts/lib/process-detection.sh" "CODEX_APP_ID" assert_contains "$REPO_DIR/launcher/start.sh.template" 'ELECTRON_OZONE_HINT="auto"' + assert_contains "$REPO_DIR/launcher/start.sh.template" "CODEX_LINUX_RENDERING_MODE=auto|default|wslg|wayland-gpu" assert_contains "$REPO_DIR/launcher/start.sh.template" '--ozone-platform-hint="$ELECTRON_OZONE_HINT"' assert_contains "$REPO_DIR/launcher/start.sh.template" "--disable-gpu-sandbox" assert_contains "$REPO_DIR/launcher/start.sh.template" "--force-renderer-accessibility" From c7e7e27abcea45922f63ae9d192d24185cc0b0b7 Mon Sep 17 00:00:00 2001 From: Rage Lopez Date: Sun, 24 May 2026 04:34:38 -0500 Subject: [PATCH 2/2] fix(launcher): preserve X11 accessibility fallback --- launcher/start.sh.template | 27 +++++++++++++++++++++++++-- tests/scripts_smoke.sh | 12 ++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/launcher/start.sh.template b/launcher/start.sh.template index 98e92ba6..8061e792 100644 --- a/launcher/start.sh.template +++ b/launcher/start.sh.template @@ -1762,7 +1762,11 @@ falsey_env_value() { scan_electron_rendering_arg() { case "$1" in - --ozone-platform|--ozone-platform=*|--ozone-platform-hint|--ozone-platform-hint=*) + --ozone-platform=*) + ELECTRON_OZONE_SWITCH_IN_ARGS=1 + ELECTRON_OZONE_PLATFORM_ARG="${1#--ozone-platform=}" + ;; + --ozone-platform|--ozone-platform-hint|--ozone-platform-hint=*) ELECTRON_OZONE_SWITCH_IN_ARGS=1 ;; --use-gl|--use-gl=*|--use-angle|--use-angle=*) @@ -1839,7 +1843,20 @@ should_disable_gpu_compositing() { return 1 } +effective_electron_ozone_platform() { + if [ -n "$ELECTRON_OZONE_PLATFORM" ]; then + echo "$ELECTRON_OZONE_PLATFORM" + return 0 + fi + + if [ -n "$ELECTRON_OZONE_PLATFORM_ARG" ]; then + echo "$ELECTRON_OZONE_PLATFORM_ARG" + fi +} + should_force_renderer_accessibility() { + local effective_platform + if [ -n "${CODEX_FORCE_RENDERER_ACCESSIBILITY:-}" ]; then if truthy_env_value "$CODEX_FORCE_RENDERER_ACCESSIBILITY"; then return 0 @@ -1856,9 +1873,14 @@ should_force_renderer_accessibility() { fi case "$ELECTRON_RENDERING_MODE" in - wslg|wayland-gpu) + wslg) return 1 ;; + wayland-gpu) + effective_platform="$(effective_electron_ozone_platform)" + [ "$effective_platform" = "wayland" ] && return 1 + return 0 + ;; esac return 0 @@ -1872,6 +1894,7 @@ set_electron_defaults() { ELECTRON_WSLG_DETECTED=0 ELECTRON_PLATFORM_EXPLICIT=0 ELECTRON_OZONE_SWITCH_IN_ARGS=0 + ELECTRON_OZONE_PLATFORM_ARG="" ELECTRON_GL_SWITCH_PROVIDED=0 ELECTRON_GL_SWITCH_ADDED=0 ELECTRON_GPU_DISABLE_SWITCH_IN_ARGS=0 diff --git a/tests/scripts_smoke.sh b/tests/scripts_smoke.sh index fe27ec0b..2a39c063 100755 --- a/tests/scripts_smoke.sh +++ b/tests/scripts_smoke.sh @@ -2097,6 +2097,18 @@ PY output="$(env -i PATH="$PATH" HOME="$HOME" CODEX_LINUX_RENDERING_MODE=wayland-gpu CODEX_FORCE_RENDERER_ACCESSIBILITY=1 "$launcher_probe" probe)" [[ "$output" == *"renderer_accessibility=1"* && "$output" == *"<--force-renderer-accessibility>"* ]] || fail "CODEX_FORCE_RENDERER_ACCESSIBILITY=1 must force renderer accessibility under wayland-gpu: $output" + output="$(env -i PATH="$PATH" HOME="$HOME" CODEX_LINUX_RENDERING_MODE=wayland-gpu "$launcher_probe" probe --x11)" + [[ "$output" == *"mode=wayland-gpu"* && "$output" == *"ozone_platform=x11"* ]] || fail "explicit --x11 must override the wayland-gpu platform: $output" + [[ "$output" == *"renderer_accessibility=1"* && "$output" == *"<--force-renderer-accessibility>"* ]] || fail "wayland-gpu with explicit --x11 must keep X11 renderer accessibility default: $output" + + output="$(env -i PATH="$PATH" HOME="$HOME" CODEX_LINUX_RENDERING_MODE=wayland-gpu "$launcher_probe" probe --safe-mode)" + [[ "$output" == *"mode=wayland-gpu"* && "$output" == *"ozone_platform=x11"* && "$output" == *"gpu=0"* ]] || fail "safe-mode must override wayland-gpu to X11 software rendering: $output" + [[ "$output" == *"renderer_accessibility=1"* && "$output" == *"<--force-renderer-accessibility>"* ]] || fail "wayland-gpu with safe-mode must keep X11 renderer accessibility default: $output" + + output="$(env -i PATH="$PATH" HOME="$HOME" CODEX_LINUX_RENDERING_MODE=wayland-gpu "$launcher_probe" probe -- --ozone-platform=x11)" + [[ "$output" == *"electron=<--ozone-platform=x11>"* && "$output" != *"<--ozone-platform-hint=auto>"* ]] || fail "pass-through X11 platform must override wayland-gpu hinting: $output" + [[ "$output" == *"renderer_accessibility=1"* && "$output" == *"<--force-renderer-accessibility>"* ]] || fail "wayland-gpu with pass-through X11 platform must keep X11 renderer accessibility default: $output" + output="$(env -i PATH="$PATH" HOME="$HOME" CODEX_LINUX_RENDERING_MODE=wslg "$launcher_probe" probe)" [[ "$output" == *"mode=wslg"* && "$output" == *"comp=0"* && "$output" == *"gl_added=1"* ]] || fail "forced WSLg profile must keep GPU compositing enabled and add ANGLE: $output" [[ "$output" == *"<--ozone-platform=x11>"* && "$output" == *"electron=<--use-gl=angle>"* ]] || fail "forced WSLg profile must use X11 and ANGLE by default: $output"