Skip to content

fix(cua-driver/linux): fail loudly when X11 input can't be delivered on pure Wayland (#1921) - #1994

Merged
f-trycua merged 1 commit into
mainfrom
fix/wayland-input-fail-loud-1921
Jun 24, 2026
Merged

fix(cua-driver/linux): fail loudly when X11 input can't be delivered on pure Wayland (#1921)#1994
f-trycua merged 1 commit into
mainfrom
fix/wayland-input-fail-loud-1921

Conversation

@f-trycua

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

Copy link
Copy Markdown
Collaborator

Problem

On a native-Wayland session (WAYLAND_DISPLAY set, no DISPLAY), click returns ✅ Clicked at (x,y) but no pointer input is deliveredstrace shows zero pointer events. Silent false-success: the agent believes its clicks landed when nothing happened. Fixes #1921 (the near-term half).

Root cause

The native-Wayland backend (zwlr_virtual_pointer input) is opt-inis_wayland() is false unless CUA_DRIVER_RS_ENABLE_WAYLAND=1. So on a pure-Wayland box without that env, every input tool routes to the X11 XSendEvent path, which cannot deliver events with no X server — yet the failure surfaced as a cryptic connect error at best, or a silent success at worst.

Fix (issue's recommended "fail loudly" direction)

  • wayland::wayland_input_unavailable_reason()Some(actionable msg) only on a pure-Wayland session with the backend off; None for X11 and XWayland (where DISPLAY is set), so those paths are untouched.
  • input::connect_x11_for_input() wraps the X11 connect: it bails with that reason instead of attempting a doomed X11 injection, and otherwise surfaces DISPLAY on any connect failure. All 10 X11 input connect sites (click, drag, type, press-key, focus, …) now route through it.

Result: on pure Wayland without the backend, input tools return a clear "input cannot be delivered: pure Wayland session… set CUA_DRIVER_RS_ENABLE_WAYLAND=1 …or run under XWayland" error rather than reporting a false success. Wiring native zwlr_virtual_pointer as the default remains the larger #1910 follow-up.

Verification

  • Build-verified on Linux: cargo build -p platform-linux recompiled green (helper + all 10 routed sites present). Default features.
  • Runtime behaviour on a live headless-sway session not exercised here; the change converts a silent/cryptic failure on the existing no-DISPLAY path into an explicit, actionable error.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved error handling for Linux input injection with clearer, actionable error messages when input delivery is unavailable in Wayland sessions.
  • Improvements

    • Enhanced platform detection and user guidance for Wayland environments to help users resolve input injection issues.

…on pure Wayland (#1921)

On a pure-Wayland session (WAYLAND_DISPLAY set, no DISPLAY) with the native
Wayland backend not opted in, every input tool routed to the X11 XSendEvent
path, which cannot deliver events without an X server — yet the failure was a
cryptic x11rb connect error at best and a silent false-success at worst. An
agent then believes its clicks/keys landed when nothing happened.

- Add wayland::wayland_input_unavailable_reason(): Some(actionable msg) only on
  a pure Wayland session with the backend off; None for X11/XWayland.
- Route all 10 X11 input connect sites through connect_x11_for_input(), which
  bails with that reason instead of attempting X11, and otherwise surfaces
  DISPLAY on any connect failure so the cause is diagnosable.

Addresses the issue's 'fail loudly rather than fall through to the X11 no-op
and report success' direction. Wiring native zwlr_virtual_pointer as the
default remains the larger #1910 follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KMXCW4M5uK1HRGjjH4wueZ
@vercel

vercel Bot commented Jun 23, 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 Jun 23, 2026 9:11am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: be71886a-8b03-426b-811e-f3ab6cc27c70

📥 Commits

Reviewing files that changed from the base of the PR and between c898d7b and 479efbb.

📒 Files selected for processing (2)
  • libs/cua-driver/rust/crates/platform-linux/src/input/mod.rs
  • libs/cua-driver/rust/crates/platform-linux/src/wayland/mod.rs

📝 Walkthrough

Walkthrough

Adds a wayland_input_unavailable_reason() helper in wayland/mod.rs that detects a pure Wayland session (no native backend enabled). A new connect_x11_for_input() helper in input/mod.rs calls this check first and improves X11 connection error messages. All ten synthetic input entry points now use connect_x11_for_input() instead of calling RustConnection::connect(None) directly.

Changes

X11 Input Preflight Checks

Layer / File(s) Summary
Wayland session unavailability detector
libs/cua-driver/rust/crates/platform-linux/src/wayland/mod.rs
Adds wayland_input_unavailable_reason(): returns Some(message) with ENABLE_WAYLAND_ENV instructions when WAYLAND_DISPLAY is set, DISPLAY is unset, and wayland_enabled() is false; otherwise returns None.
connect_x11_for_input() helper and callsite updates
libs/cua-driver/rust/crates/platform-linux/src/input/mod.rs
Adds connect_x11_for_input() that calls wayland_input_unavailable_reason() as a preflight and includes DISPLAY details on connection failure. All ten send_* functions (send_focus_in, send_focus_out, send_click, send_drag, send_button_down, send_motion, send_button_up, send_type_text_with_delay, send_type_text_xtest, send_key) replace direct RustConnection::connect(None) calls with connect_x11_for_input().

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • #1921 (cua-driver-rs Linux/Wayland: click reports success but injects no input on native Wayland) — This PR directly implements the "fail loudly" fix direction described in that issue: when DISPLAY is unset and native Wayland backend is disabled, all send_* calls now return an actionable error instead of silently no-oping through the X11 path.

Possibly related PRs

  • trycua/cua#1789: Modifies the same platform-linux/src/input/mod.rs synthetic input functions that this PR now routes through connect_x11_for_input().
  • trycua/cua#1935: Modifies platform-linux/src/wayland/mod.rs to gate native Wayland input, which is the wayland_enabled() check that wayland_input_unavailable_reason() builds on.

Poem

🐇 Hoppity-hop through the display maze,
No silent no-ops to end your days!
WAYLAND_DISPLAY set? DISPLAY not found?
Now errors ring out, loud and profound.
connect_x11_for_input guards the gate —
Ten send_* friends all celebrate! 🎉

🚥 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: implementing fail-loudly behavior when X11 input cannot be delivered on pure Wayland systems.
Linked Issues check ✅ Passed The PR fully addresses issue #1921 by implementing the fail-loudly approach: detecting pure-Wayland sessions with disabled native backend via wayland_input_unavailable_reason() and routing all X11 input connections through connect_x11_for_input() wrapper that returns actionable errors.
Out of Scope Changes check ✅ Passed All changes are directly in-scope: the new wayland_input_unavailable_reason() helper and connect_x11_for_input() wrapper, plus updates to 10 input functions to use the wrapper. No unrelated modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/wayland-input-fail-loud-1921

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.

@github-actions

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

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.

cua-driver-rs (Linux/Wayland): click reports success but injects no input on native Wayland

1 participant