Skip to content

feat(cua-driver-rs)(linux): gate native-Wayland backend behind opt-in flag - #1935

Merged
f-trycua merged 2 commits into
mainfrom
feat/wayland-opt-in-flag
Jun 18, 2026
Merged

feat(cua-driver-rs)(linux): gate native-Wayland backend behind opt-in flag#1935
f-trycua merged 2 commits into
mainfrom
feat/wayland-opt-in-flag

Conversation

@f-trycua

@f-trycua f-trycua commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Why

The native-Wayland backend (#1910) was default-on: is_wayland() engaged it for any pure-Wayland session (WAYLAND_DISPLAY set, DISPLAY unset). But it's incomplete (toplevel enumeration + virtual-pointer/keyboard input; screen capture and full AT-SPI parity are still landing), so silently driving it on every Wayland session is the wrong default for a release.

What

Make it opt-in. is_wayland() now also requires CUA_DRIVER_RS_ENABLE_WAYLAND (any value other than empty / 0 / false):

  • Off (default) — a pure-Wayland session is treated as unsupported rather than quietly using a half-complete path.
  • On — current native-Wayland behavior (sway / labwc / Hyprland via wlroots protocols).
  • XWayland sessions are unaffected — they already have DISPLAY set, so is_wayland() was already false for them.

doctor reflects the state (native Wayland session — experimental backend ENABLED vs OFF; set CUA_DRIVER_RS_ENABLE_WAYLAND=1 to enable), and the structured output gains wayland_enabled.

Docs: linux.mdx gains an "Experimental native Wayland" section + updates the display-server probe table.

Release context

Landing this before cutting 0.5.7 so the experimental Wayland backend ships safely behind a flag, and we can validate it on a real sway VM using the exact released artifact.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Updated Linux getting-started guide with clearer explanation of native Wayland support and the experimental backend option.
  • New Features

    • Introduced opt-in experimental native Wayland backend for wlroots compositors, enabling toplevel enumeration and virtual input support.
    • Enhanced diagnostic tool to report experimental Wayland backend status.

… opt-in flag

The native-Wayland backend (#1910) was default-on: `is_wayland()` engaged it for
any pure-Wayland session (WAYLAND_DISPLAY set, DISPLAY unset). But the backend is
incomplete (toplevel enumeration + virtual-pointer/keyboard input; capture and
full AT-SPI parity still landing), so silently driving it on every Wayland
session is the wrong default.

Make it opt-in: `is_wayland()` now also requires `CUA_DRIVER_RS_ENABLE_WAYLAND`
(any value other than empty/0/false). Off by default, a pure-Wayland session is
treated as unsupported instead of quietly using a half-complete path; set the
flag to try the experimental backend. XWayland sessions are unaffected (they
already have DISPLAY set, so is_wayland() was already false for them).

`doctor` reflects the state (native Wayland session — backend ENABLED vs OFF with
the flag to set), and the structured output gains `wayland_enabled`. Docs:
linux.mdx gains an "Experimental native Wayland" section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Jun 18, 2026 4:33am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f0c06e35-86c7-4ed5-a2f1-8b7309821535

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The native Wayland backend in platform-linux is now opt-in via a new CUA_DRIVER_RS_ENABLE_WAYLAND environment variable. wayland_enabled() and ENABLE_WAYLAND_ENV are added; is_wayland() now requires the opt-in flag. CheckPermissionsTool surfaces the enabled/OFF state in both human-readable text and structured JSON. The Linux guide documents the feature.

Changes

Experimental Wayland Opt-in Gate

Layer / File(s) Summary
ENABLE_WAYLAND_ENV constant and wayland_enabled() logic
libs/cua-driver/rust/crates/platform-linux/src/wayland/mod.rs
Adds ENABLE_WAYLAND_ENV = "CUA_DRIVER_RS_ENABLE_WAYLAND" and wayland_enabled() that accepts non-empty values other than "0"/"false" (case-insensitive). Updates is_wayland() to require wayland_enabled() in addition to the existing WAYLAND_DISPLAY/DISPLAY presence checks.
CheckPermissionsTool diagnostic output
libs/cua-driver/rust/crates/platform-linux/src/tools/impl_.rs
Updates the Wayland branch of status_text to display ENABLED or OFF (set <ENV_VAR> to enable), and appends a wayland_enabled boolean field to the structured JSON output.
Linux getting-started docs
docs/content/docs/cua-driver/guide/getting-started/linux.mdx
Updates the pure-Wayland probe bullet to note unsupported-by-default behavior with an experimental opt-in, and adds a new subsection covering feature scope, the enable flag, supported wlroots compositors, and expected cua-driver doctor output.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • trycua/cua#1543: Touches the same platform-linux Wayland detection logic (is_wayland()) and cua-driver doctor probing that this PR directly modifies.

Poem

🐇 A Wayland door, once open wide,
Now needs a key before you're inside.
Set the env var, flip the bit,
The wlroots compositors say "that's it!"
OFF becomes ENABLED with a hop —
The rabbit checks the flag and doesn't stop. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: gating the native-Wayland backend behind an opt-in flag.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/wayland-opt-in-flag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…sion wrapper

The native-Wayland backend is now opt-in (CUA_DRIVER_RS_ENABLE_WAYLAND). Every
Wayland NixOS test (xfce-labwc/xfce-sway/kde/gnome x all scenarios) drives the
shared session.nix driverWrapper, so set the flag once in appBackendEnv — these
tests exist specifically to exercise the backend, which would otherwise be off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@libs/cua-driver/rust/crates/platform-linux/src/tools/impl_.rs`:
- Around line 2802-2810: The code at the Some(s) if
crate::wayland::wayland_enabled() match arm only checks for WAYLAND_DISPLAY but
fails to distinguish between native Wayland and XWayland sessions. Add logic to
check whether the DISPLAY environment variable is also set to differentiate
these cases. If both WAYLAND_DISPLAY and DISPLAY are present, it indicates an
XWayland session which should be reported separately from a native Wayland
session where only WAYLAND_DISPLAY is set. Update the branching logic to create
distinct reporting paths for native Wayland versus XWayland based on whether
DISPLAY is additionally present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f710dc08-300e-47c5-9776-723d94149094

📥 Commits

Reviewing files that changed from the base of the PR and between 6fed723 and 93df4d4.

📒 Files selected for processing (3)
  • docs/content/docs/cua-driver/guide/getting-started/linux.mdx
  • libs/cua-driver/rust/crates/platform-linux/src/tools/impl_.rs
  • libs/cua-driver/rust/crates/platform-linux/src/wayland/mod.rs

Comment on lines +2802 to 2810
Some(s) if crate::wayland::wayland_enabled() =>
format!("✅ native Wayland session (WAYLAND_DISPLAY={s}) — experimental backend ENABLED"),
Some(s) => format!(
"⚠️ native Wayland session (WAYLAND_DISPLAY={s}) — experimental backend OFF; \
set {}=1 to enable it",
crate::wayland::ENABLE_WAYLAND_ENV
),
None => "❌ not a Wayland session".to_string(),
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Incorrectly classifies XWayland sessions as native Wayland.

At Line 2802, matching only on WAYLAND_DISPLAY causes sessions with both WAYLAND_DISPLAY and DISPLAY to be reported as “native Wayland session,” which is inaccurate for XWayland. Add a DISPLAY check in this branching logic so XWayland is reported separately.

Suggested fix
-        let wayland_display = std::env::var("WAYLAND_DISPLAY").ok();
+        let wayland_display = std::env::var("WAYLAND_DISPLAY").ok();
+        let x_display = std::env::var("DISPLAY").ok();
@@
-            match &wayland_display {
-                Some(s) if crate::wayland::wayland_enabled() =>
+            match (&wayland_display, &x_display) {
+                (Some(s), Some(x)) => format!(
+                    "✅ Wayland session with XWayland (WAYLAND_DISPLAY={s}, DISPLAY={x}) — using X11/XWayland path"
+                ),
+                (Some(s), None) if crate::wayland::wayland_enabled() =>
                     format!("✅ native Wayland session (WAYLAND_DISPLAY={s}) — experimental backend ENABLED"),
-                Some(s) => format!(
+                (Some(s), None) => format!(
                     "⚠️  native Wayland session (WAYLAND_DISPLAY={s}) — experimental backend OFF; \
                      set {}=1 to enable it",
                     crate::wayland::ENABLE_WAYLAND_ENV
                 ),
-                None => "❌ not a Wayland session".to_string(),
+                (None, _) => "❌ not a Wayland session".to_string(),
             },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/cua-driver/rust/crates/platform-linux/src/tools/impl_.rs` around lines
2802 - 2810, The code at the Some(s) if crate::wayland::wayland_enabled() match
arm only checks for WAYLAND_DISPLAY but fails to distinguish between native
Wayland and XWayland sessions. Add logic to check whether the DISPLAY
environment variable is also set to differentiate these cases. If both
WAYLAND_DISPLAY and DISPLAY are present, it indicates an XWayland session which
should be reported separately from a native Wayland session where only
WAYLAND_DISPLAY is set. Update the branching logic to create distinct reporting
paths for native Wayland versus XWayland based on whether DISPLAY is
additionally present.

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Linux visual regression artifacts

Matrix jobs now run independently. Download visual artifacts from this workflow run.
Each background-GUI job uploads a .gif of the interaction plus two annotated PNGs (<app>.png raw, <app>-atspi.png with AT-SPI element boxes); the cua-driver-linux-som-overlays artifact adds <app>-som.png cua Set-of-Marks overlays:

  • cua-driver-linux-cursor-click-gif
  • cua-driver-linux-background-terminal-gif
  • cua-driver-linux-parallel-drag-xserver
  • cua-driver-linux-background-gui-chromium
  • cua-driver-linux-background-gui-tk
  • cua-driver-linux-background-gui-gtk3-gedit
  • cua-driver-linux-background-gui-gtk3-mousepad
  • cua-driver-linux-background-gui-gtk3-scite
  • cua-driver-linux-background-gui-gtk4-characters
  • cua-driver-linux-background-gui-qt5-manuskript
  • cua-driver-linux-background-gui-qt5-klog
  • cua-driver-linux-background-gui-qt5-openambit
  • cua-driver-linux-background-gui-qt6-kate
  • cua-driver-linux-background-gui-qt6-kcalc
  • cua-driver-linux-background-gui-qt6-okular
  • cua-driver-linux-background-gui-qt6-qownnotes
  • cua-driver-linux-background-gui-electron-zettlr
  • cua-driver-linux-background-gui-electron-joplin
  • cua-driver-linux-background-gui-electron-logseq
  • cua-driver-linux-som-overlays

Open workflow run and download artifacts

@f-trycua
f-trycua merged commit 1e39e8b into main Jun 18, 2026
64 checks passed
@f-trycua
f-trycua deleted the feat/wayland-opt-in-flag branch June 18, 2026 04:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant