From 34eb2f7ecfd68a68a39df79786d89088ea92bcaf Mon Sep 17 00:00:00 2001 From: Jatin K Malik Date: Tue, 30 Jun 2026 19:55:55 -0700 Subject: [PATCH] feat(text-injection): speed up ydotool injection with explicit --key-delay (#488) Pass --key-delay 8 to ydotool type instead of relying on the default (12-20ms). This makes text injection ~3x faster while keeping key-delay above zero to avoid the Shift-leak bug where capital letters corrupt following characters. The delay is configurable via VOCALINUX_YDOTOOL_KEY_DELAY env var. Note: --key-hold flag from the original issue does not exist in standard ydotool (verified against official man page and v1.0.4 source). Fixes #482 --- src/vocalinux/text_injection/text_injector.py | 8 +++++++- tests/test_text_injector.py | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/vocalinux/text_injection/text_injector.py b/src/vocalinux/text_injection/text_injector.py index 16d04af..11f2abf 100644 --- a/src/vocalinux/text_injection/text_injector.py +++ b/src/vocalinux/text_injection/text_injector.py @@ -987,7 +987,13 @@ class TextInjector: if self.wayland_tool == "wtype": cmd = ["wtype", text] else: # ydotool - cmd = ["ydotool", "type", text] + # Pass explicit timing parameters to speed up injection. + # ydotool defaults to --key-delay 12 (or 20 in older versions). + # We use a faster default configurable via environment variable. + # IMPORTANT: key-delay must stay > 0 to avoid Shift-leak bug where + # capital letters corrupt following characters (e.g. "Can you" -> "CAN YOu"). + key_delay = os.environ.get("VOCALINUX_YDOTOOL_KEY_DELAY", "8") + cmd = ["ydotool", "type", "--key-delay", key_delay, text] try: subprocess.run(cmd, check=True, stderr=subprocess.PIPE, text=True) diff --git a/tests/test_text_injector.py b/tests/test_text_injector.py index c52f917..b68297e 100644 --- a/tests/test_text_injector.py +++ b/tests/test_text_injector.py @@ -205,9 +205,9 @@ class TestTextInjector(unittest.TestCase): # Inject text injector.inject_text("Hello world") - # Verify ydotool was called correctly + # Verify ydotool was called correctly with timing parameters self.mock_subprocess.assert_any_call( - ["ydotool", "type", "Hello world"], + ["ydotool", "type", "--key-delay", "8", "Hello world"], check=True, stderr=subprocess.PIPE, text=True,