2026-04-06 21:26:51 +02:00
|
|
|
"""Text-Einfügung via wl-copy + ydotool Ctrl+V."""
|
2026-04-06 20:28:18 +02:00
|
|
|
|
|
|
|
|
import asyncio
|
|
|
|
|
import logging
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
PASTE_DELAY = 0.2 # Sekunden Wartezeit vor Clipboard-Restore
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Inserter:
|
2026-04-06 21:26:51 +02:00
|
|
|
async def _run_capture(self, *cmd: str) -> bytes:
|
|
|
|
|
"""Führt einen Befehl aus und gibt stdout zurück."""
|
2026-04-06 20:28:18 +02:00
|
|
|
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())
|
2026-04-06 21:26:51 +02:00
|
|
|
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()
|
2026-04-06 20:28:18 +02:00
|
|
|
|
|
|
|
|
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
|
2026-04-06 21:26:51 +02:00
|
|
|
old_clipboard = await self._run_capture("wl-paste", "--no-newline")
|
2026-04-06 20:28:18 +02:00
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
# 2. Text in Zwischenablage kopieren
|
2026-04-06 21:26:51 +02:00
|
|
|
await self._run_fire("wl-copy", "--", text)
|
|
|
|
|
|
|
|
|
|
# 3. Kurz warten damit Clipboard bereit ist
|
|
|
|
|
await asyncio.sleep(0.05)
|
2026-04-06 20:28:18 +02:00
|
|
|
|
2026-04-06 21:26:51 +02:00
|
|
|
# 4. Ctrl+V simulieren via ydotool (Ctrl=29, V=47)
|
|
|
|
|
await self._run_fire("ydotool", "key", "29:1", "47:1", "47:0", "29:0")
|
2026-04-06 20:28:18 +02:00
|
|
|
|
2026-04-06 21:26:51 +02:00
|
|
|
# 5. Warten, dann Clipboard wiederherstellen
|
2026-04-06 20:28:18 +02:00
|
|
|
await asyncio.sleep(PASTE_DELAY)
|
|
|
|
|
finally:
|
2026-04-06 21:26:51 +02:00
|
|
|
await self._run_fire("wl-copy", "--", old_clipboard.decode())
|
2026-04-06 20:28:18 +02:00
|
|
|
|
|
|
|
|
logger.info("Text eingefügt (%d Zeichen)", len(text))
|