55 lines
1.6 KiB
Python
55 lines
1.6 KiB
Python
import os
|
|
import shutil
|
|
import subprocess
|
|
import time
|
|
|
|
|
|
def _pynput_type(text):
|
|
from pynput.keyboard import Controller as KeyboardController
|
|
KeyboardController().type(text)
|
|
|
|
|
|
def _wl_paste():
|
|
"""Read current clipboard contents, returns None on failure."""
|
|
try:
|
|
result = subprocess.run(
|
|
["wl-paste", "--no-newline"],
|
|
capture_output=True, timeout=2,
|
|
)
|
|
if result.returncode == 0:
|
|
return result.stdout
|
|
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
pass
|
|
return None
|
|
|
|
|
|
def _wl_copy_bytes(data):
|
|
"""Restore clipboard from raw bytes."""
|
|
try:
|
|
subprocess.run(
|
|
["wl-copy"],
|
|
input=data, check=False, timeout=2,
|
|
)
|
|
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
pass
|
|
|
|
|
|
def type_text(text):
|
|
"""Type text into the active window, cross-platform."""
|
|
if os.name == "nt":
|
|
_pynput_type(text)
|
|
return
|
|
session = os.environ.get("XDG_SESSION_TYPE", "")
|
|
if session == "wayland" and shutil.which("wl-copy"):
|
|
old_clipboard = _wl_paste()
|
|
subprocess.run(["wl-copy", "--", text], check=False)
|
|
time.sleep(0.05)
|
|
subprocess.run(["xdotool", "key", "ctrl+v"], check=False)
|
|
time.sleep(0.05)
|
|
if old_clipboard is not None:
|
|
_wl_copy_bytes(old_clipboard)
|
|
elif shutil.which("xdotool"):
|
|
subprocess.run(["xdotool", "type", "--clearmodifiers", "--", text], check=False)
|
|
else:
|
|
_pynput_type(text)
|