2026-04-08 10:36:38 +02:00
|
|
|
"""Text-Einfügung via pynput Clipboard + Ctrl+V (Windows)."""
|
|
|
|
|
|
|
|
|
|
import asyncio
|
|
|
|
|
import logging
|
|
|
|
|
|
|
|
|
|
from pynput.keyboard import Controller, Key
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
PASTE_DELAY = 0.2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Win32Inserter:
|
2026-04-08 10:43:14 +02:00
|
|
|
def __init__(self):
|
|
|
|
|
self._keyboard = Controller()
|
|
|
|
|
|
2026-04-08 10:36:38 +02:00
|
|
|
def _get_clipboard(self) -> str:
|
|
|
|
|
"""Liest den aktuellen Clipboard-Inhalt (Text)."""
|
|
|
|
|
import win32clipboard
|
|
|
|
|
try:
|
|
|
|
|
win32clipboard.OpenClipboard()
|
|
|
|
|
try:
|
|
|
|
|
data = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
|
|
|
|
|
return data
|
|
|
|
|
except TypeError:
|
|
|
|
|
return ""
|
|
|
|
|
finally:
|
|
|
|
|
win32clipboard.CloseClipboard()
|
|
|
|
|
except Exception:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
def _set_clipboard(self, text: str) -> None:
|
|
|
|
|
"""Setzt den Clipboard-Inhalt."""
|
|
|
|
|
import win32clipboard
|
|
|
|
|
win32clipboard.OpenClipboard()
|
|
|
|
|
try:
|
|
|
|
|
win32clipboard.EmptyClipboard()
|
|
|
|
|
win32clipboard.SetClipboardText(text, win32clipboard.CF_UNICODETEXT)
|
|
|
|
|
finally:
|
|
|
|
|
win32clipboard.CloseClipboard()
|
|
|
|
|
|
2026-04-08 10:43:14 +02:00
|
|
|
def _send_paste(self) -> None:
|
|
|
|
|
"""Simuliert Ctrl+V."""
|
|
|
|
|
self._keyboard.press(Key.ctrl)
|
|
|
|
|
self._keyboard.press('v')
|
|
|
|
|
self._keyboard.release('v')
|
|
|
|
|
self._keyboard.release(Key.ctrl)
|
|
|
|
|
|
2026-04-08 10:36:38 +02:00
|
|
|
async def insert(self, text: str) -> None:
|
|
|
|
|
"""Fügt Text ins aktive Fenster ein via Clipboard + Ctrl+V."""
|
|
|
|
|
if not text:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
old_clipboard = await asyncio.to_thread(self._get_clipboard)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
await asyncio.to_thread(self._set_clipboard, text)
|
|
|
|
|
await asyncio.sleep(0.05)
|
2026-04-08 10:43:14 +02:00
|
|
|
await asyncio.to_thread(self._send_paste)
|
2026-04-08 10:36:38 +02:00
|
|
|
await asyncio.sleep(PASTE_DELAY)
|
|
|
|
|
finally:
|
|
|
|
|
await asyncio.to_thread(self._set_clipboard, old_clipboard)
|
|
|
|
|
|
|
|
|
|
logger.info("Text eingefügt (%d Zeichen)", len(text))
|