fix(wayland): reliable clipboard copy and ydotool injection on non-US layouts - #480
Merged
Merged
Conversation
Two independent text-injection bugs on Wayland: 1. Clipboard copy silently failed. wl-copy/xclip/xsel fork a background process that keeps owning the selection; capturing its stderr with subprocess.PIPE makes run() block on the surviving child until the clipboard is next overwritten, so the call always hits its timeout and _copy_to_clipboard reports failure even though the copy succeeded. Redirect stdout/stderr to DEVNULL so run() only waits for the short-lived foreground process. 2. ydotool scrambled text on non-US keyboard layouts. `ydotool type` emits positional evdev keycodes that get re-interpreted through the active layout (assumed US QWERTY), so dictated text came out garbled on AZERTY/QWERTZ/Dvorak (e.g. "message" -> ",essqge") and non-ASCII was dropped. Always inject via clipboard paste (Ctrl+V) for ydotool, which is layout-independent and Unicode-safe. Adds regression tests for both. Claude-Session: https://claude.ai/code/session_01EhyratrEE4vDWhriirUB9k
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #480 +/- ##
=======================================
Coverage 84.72% 84.72%
=======================================
Files 31 31
Lines 5068 5068
Branches 782 782
=======================================
Hits 4294 4294
Misses 595 595
Partials 179 179 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This was referenced Jun 25, 2026
Closed
jatinkrmalik
approved these changes
Jul 1, 2026
Member
|
Merged, thanks a lot @fsioni! The scrambled output on AZERTY/QWERTZ layouts has tripped up a bunch of people, and that clipboard hang was a nasty one to track down. This ships in v0.13.0-beta. |
2 tasks
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.
Summary
Fixes two independent text-injection bugs on Wayland that, combined, made dictation produce nothing usable (no text in the focused field, empty clipboard) on a GNOME/Mutter + AZERTY setup.
1. Clipboard copy silently failed (
_run_clipboard_command)wl-copy(andxclip/xsel) fork a background process that keeps owning the selection in order to serve it. That child inherits the pipes created bysubprocess.run(..., stderr=subprocess.PIPE), sorun()blocks reading stderr until the child exits — i.e. until the clipboard is next overwritten, which may be never. The call therefore hits_clipboard_timeoutand_copy_to_clipboardreturnsFalse, even though the copy actually succeeded.Reproduced on a real session:
Fix: redirect
stdout/stderrtoDEVNULLsorun()only waits for the short-lived foreground process. Measured:PIPE→ timeout;DEVNULL→ returns in ~0.06 s with the clipboard correctly set. I couldn't find this one reported elsewhere.2.
ydotool typescrambles text on non-US layouts (_inject_with_wayland_tool)ydotool typeemits positional evdev keycodes that the compositor re-interprets through the active keyboard layout, which ydotool assumes is US QWERTY. On AZERTY/QWERTZ/Dvorak the output is garbled (e.g.message→,essqge,avec→qvec) and non-ASCII characters are dropped.The code already used clipboard paste for non-ASCII text (#362); this extends it to all text when the tool is ydotool, since
Ctrl+Vis both layout-independent and Unicode-safe. (ydotool keyCtrl+V uses keycodes 29+47, which map to the same physical keys on QWERTY and AZERTY.)This completes #164: that issue was closed but only the non-ASCII case was actually fixed (via #362) — plain ASCII still garbled on non-US layouts.
Tests
tests/test_text_injector.pyandtests/test_text_injector_ext.pypass.test_ydotool_ascii_*to reflect that ydotool now always pastes.test_clipboard_command_does_not_capture_pipeas a regression guard for the PIPE→DEVNULL fix.blackandisortclean.Related issues
wl-copy/xclipPIPE hang plus theydotoolASCII case.ydotool/clipboard path largely because the IBus backend is often a silent no-op on Wayland ([BUG] IBus backend false-positive on niri/sway Wayland so text injection silently no-ops #478, [Wayland] IBus text injection reports success but no text appears on KDE Plasma (Garuda/Arch) #380), which is what surfaced both bugs here.Notes / scope
wtypekeeps its native Unicode typing path (it speaks the Wayland text-input protocol, so it is layout- and Unicode-correct already).setxkbmap-rewrites-XWayland-to-usside effect ([BUG] 0.12.0-beta changes keyboard layout from german to US #474) — kept separate to keep this PR to two self-contained bug fixes.https://claude.ai/code/session_01EhyratrEE4vDWhriirUB9k