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>
This commit is contained in:
+22
-11
@@ -1,4 +1,4 @@
|
||||
"""Text-Einfügung via Clipboard und wtype."""
|
||||
"""Text-Einfügung via wl-copy + ydotool Ctrl+V."""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
@@ -9,8 +9,8 @@ PASTE_DELAY = 0.2 # Sekunden Wartezeit vor Clipboard-Restore
|
||||
|
||||
|
||||
class Inserter:
|
||||
async def _run(self, *cmd: str) -> tuple[bytes, int]:
|
||||
"""Führt einen Befehl aus, gibt (stdout, returncode) zurück."""
|
||||
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,
|
||||
@@ -19,7 +19,16 @@ class Inserter:
|
||||
stdout, stderr = await proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
logger.warning("Befehl fehlgeschlagen: %s (stderr: %s)", cmd, stderr.decode())
|
||||
return stdout, proc.returncode
|
||||
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."""
|
||||
@@ -27,19 +36,21 @@ class Inserter:
|
||||
return
|
||||
|
||||
# 1. Aktuelle Zwischenablage sichern
|
||||
old_clipboard, _ = await self._run("wl-paste")
|
||||
old_clipboard = await self._run_capture("wl-paste", "--no-newline")
|
||||
|
||||
try:
|
||||
# 2. Text in Zwischenablage kopieren
|
||||
await self._run("wl-copy", text)
|
||||
await self._run_fire("wl-copy", "--", text)
|
||||
|
||||
# 3. Ctrl+V simulieren
|
||||
await self._run("wtype", "-M", "ctrl", "v", "-m", "ctrl")
|
||||
# 3. Kurz warten damit Clipboard bereit ist
|
||||
await asyncio.sleep(0.05)
|
||||
|
||||
# 4. Kurz warten, dann Clipboard wiederherstellen
|
||||
# 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:
|
||||
# Clipboard immer wiederherstellen
|
||||
await self._run("wl-copy", old_clipboard.decode())
|
||||
await self._run_fire("wl-copy", "--", old_clipboard.decode())
|
||||
|
||||
logger.info("Text eingefügt (%d Zeichen)", len(text))
|
||||
|
||||
Reference in New Issue
Block a user