Files
whisper-local/whisper_local/inserter.py
T
info 9c058a1ec8 fix: use ydotool + wl-copy for text insertion on KDE Wayland
Replace wtype (unsupported on KDE) with ydotool key for Ctrl+V
simulation. Use wl-copy for clipboard-based insertion to avoid
ydotool type's QWERTZ/QWERTY layout mismatch. Use DEVNULL instead
of PIPE for wl-copy to prevent hanging on its forked background
process.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 21:26:51 +02:00

57 lines
1.9 KiB
Python

"""Text-Einfügung via wl-copy + ydotool Ctrl+V."""
import asyncio
import logging
logger = logging.getLogger(__name__)
PASTE_DELAY = 0.2 # Sekunden Wartezeit vor Clipboard-Restore
class Inserter:
async def _run_capture(self, *cmd: str) -> bytes:
"""Führt einen Befehl aus und gibt stdout zurück."""
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
if proc.returncode != 0:
logger.warning("Befehl fehlgeschlagen: %s (stderr: %s)", cmd, stderr.decode())
return stdout
async def _run_fire(self, *cmd: str) -> None:
"""Führt einen Befehl aus ohne auf Pipes zu warten."""
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.DEVNULL,
stderr=asyncio.subprocess.DEVNULL,
)
await proc.wait()
async def insert(self, text: str) -> None:
"""Fügt Text ins aktive Fenster ein via Clipboard + Ctrl+V."""
if not text:
return
# 1. Aktuelle Zwischenablage sichern
old_clipboard = await self._run_capture("wl-paste", "--no-newline")
try:
# 2. Text in Zwischenablage kopieren
await self._run_fire("wl-copy", "--", text)
# 3. Kurz warten damit Clipboard bereit ist
await asyncio.sleep(0.05)
# 4. Ctrl+V simulieren via ydotool (Ctrl=29, V=47)
await self._run_fire("ydotool", "key", "29:1", "47:1", "47:0", "29:0")
# 5. Warten, dann Clipboard wiederherstellen
await asyncio.sleep(PASTE_DELAY)
finally:
await self._run_fire("wl-copy", "--", old_clipboard.decode())
logger.info("Text eingefügt (%d Zeichen)", len(text))