Skip to content

fix(linux): prefer dotool for reliable Wayland text input#1299

Open
aasmall wants to merge 1 commit intocjpais:mainfrom
aasmall:linux-dotool-typing
Open

fix(linux): prefer dotool for reliable Wayland text input#1299
aasmall wants to merge 1 commit intocjpais:mainfrom
aasmall:linux-dotool-typing

Conversation

@aasmall
Copy link
Copy Markdown

@aasmall aasmall commented Apr 15, 2026

Before Submitting This PR

Human Written Description

wtype works unreliably on wayland, often dropping characters. dotool was much more reliable. this PR adds it as a selectable option as well as hardens its implementation.

Prior art and context

dotool support on Linux was already discussed and accepted. This PR builds on that foundation:

  • Discussion #363 — "Supporting paste action on Wayland with dotool" is where the approach was originally proposed. @cjpais's response: "Would be happy to have a PR regarding dottool."
  • Discussion #742 — "Enable the ability to detect the current available typing methods" was a follow-up from a Niri user where wtype didn't work and dotool did. This motivated adding a user-facing selector.
  • PR #760 (merged by @kakapt) added the TypingTool enum and the Advanced > Experimental > Typing Tool dropdown. This PR builds directly on that infrastructure — the dropdown already exists; this PR makes the dotool path much more reliable when selected.

Related Issues/Discussions

Relevant to several open bugs around unreliable text input on Linux/Wayland:

  • #429 — First character missing on GNOME/Wayland Direct paste. The issue author specifically suggests dotool as a solution.
  • #315 — Typing fails due to window focus timing. dotool bypasses the virtual-keyboard protocol, sidestepping focus-related character loss.
  • #439 — Direct paste uses wrong keyboard layout. dotool may also address this since it operates at the uinput level.

Changes

  • Prefer dotoolc (daemon client, zero startup cost) with graceful fallback to standalone dotool when dotoold isn't running
  • Sanitize transcript text — strip all control characters to prevent dotool command injection via newlines
  • Capture stderr from the child process and surface it in error messages (keeps diagnostics that bare status codes would lose)
  • Poll-based timeout with child process cleanup on expiry (no orphaned threads or zombies). Timeout scales with text length and configured delay so long transcriptions aren't cut off mid-type; floored at max(delay_ms, 1) so delay_ms=0 still gets per-char headroom. Final try_wait() before declaring timeout prevents false positives when the child exits right at the deadline.
  • New typing_delay_ms setting (0–50ms, default 2ms) with UI slider in Advanced > Experimental, with translations across all 20 locales
  • Log warning on invalid typing_delay_ms values instead of silently falling back
  • Show actionable warning when no native typing tools are detected (previously a quiet info log)

Auto-detection priority unchanged. On Wayland the order remains wtype → dotool → ydotool, matching upstream behavior. dotool was already in the priority list via PR #760 — this PR just makes it more capable when selected or when the auto path lands on it.

Files changed: clipboard.rs (main logic), settings.rs (new setting + tests), shortcut/mod.rs (command registration), lib.rs (command wiring), bindings.ts, settingsStore.ts, TypingDelay.tsx (new slider), AdvancedSettings.tsx, translation.json + 19 locale files

This PR is rebased directly on upstream/main and does not depend on any other open PR.

Testing

  • Tested on Framework 13 AMD (Ryzen AI 300, Radeon 880M) running Arch Linux with Hyprland
  • dotool typing: fast, accurate output with zero dropped characters
  • Typing delay slider: verified 0ms through 50ms range, default 2ms is smooth
  • Fallback: tested with dotool present, with only wtype present, and with neither — warning displays correctly
  • Long transcription test: 2000+ chars at 50ms delay completes without timeout

All auto-triggered CI checks verified locally before marking ready:

  • cargo fmt --check, cargo test (9 clipboard tests pass, including the new timeout scaling test)
  • bun run lint, bun run format:check (excluding upstream's pre-existing AGENTS.md prettier issue)
  • bun run check:translations — all 20 languages have complete keys
  • bun run test:playwright — passes

Screenshots/Videos

screenshot-2026-04-17_12-24-38

AI Assistance

  • AI was used (please describe below)

If AI was used:

  • Tools used: Claude Code (Claude Opus 4.7), with code review from CodeRabbit, OpenAI Codex (GPT-5.2), and Grok
  • How extensively: Claude Opus wrote the implementation with human direction on architecture (dotool as opt-in enhancement rather than priority reorder, configurable typing_delay_ms, sanitization approach, dynamic timeout scaling). Multiple rounds of independent AI code review — every actionable finding was either addressed or consciously declined with a documented reason. Translations for the 19 non-English locales generated by Claude. Human tested all changes on real hardware and made scope decisions.

- Prefer dotoolc (daemon client, faster) when dotoold is running
- Add configurable typing delay (0-50ms, default 2ms)
- Sanitize text to prevent dotool stdin command injection
- Poll-based child process timeout (scales with text length and delay)
- Warn user when no native typing tools are available
@aasmall aasmall force-pushed the linux-dotool-typing branch from 6aced16 to 7ea5af0 Compare April 17, 2026 19:09
@aasmall aasmall marked this pull request as ready for review April 17, 2026 19:25
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