fix(typing): hybride xdotool type+key — rapide et compatible AZERTY/VM
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 13s
security-audit / pip-audit (CVE dépendances) (push) Successful in 10s
security-audit / Scan secrets (grep) (push) Successful in 7s
tests / Lint (ruff + black) (push) Successful in 14s
tests / Tests unitaires (sans GPU) (push) Failing after 13s
tests / Tests sécurité (critique) (push) Has been skipped

xdotool type pour les segments alphanumériques (un seul appel, rapide),
xdotool key avec keysym uniquement pour les caractères spéciaux
(:, /, @, etc.) qui cassent en AZERTY dans les VM.

Évite le subprocess par caractère (trop lent, effet visuel désagréable).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-04-18 23:18:21 +02:00
parent 588c8f22c1
commit 3aa806a630

View File

@@ -38,23 +38,37 @@ _CHAR_TO_KEYSYM = {
def _xdotool_type_by_keysym(text):
"""Tape du texte via xdotool key, caractère par caractère avec keysyms.
"""Tape du texte via xdotool — hybride rapide + fiable.
Indépendant du layout clavier — fonctionne en AZERTY dans une VM QWERTY
et inversement. Plus lent que xdotool type mais 100% fiable.
Les caractères alphanumériques passent par xdotool type (un seul appel,
rapide). Les caractères spéciaux (:, /, @, etc.) passent par xdotool key
avec les noms de keysym X11 pour éviter les erreurs AZERTY dans les VM.
"""
keys = []
segments = []
buf = []
def flush_buf():
if buf:
segments.append(('type', ''.join(buf)))
buf.clear()
for ch in text:
if ch in _CHAR_TO_KEYSYM:
keys.append(_CHAR_TO_KEYSYM[ch])
elif ch.isalnum():
keys.append(ch)
flush_buf()
segments.append(('key', _CHAR_TO_KEYSYM[ch]))
else:
keys.append(ch)
buf.append(ch)
flush_buf()
for key in keys:
for kind, value in segments:
if kind == 'type':
subprocess.run(
['xdotool', 'key', '--clearmodifiers', key],
['xdotool', 'type', '--delay', '0', '--clearmodifiers', '--', value],
timeout=10, check=True
)
else:
subprocess.run(
['xdotool', 'key', '--clearmodifiers', value],
timeout=2, check=True
)
time.sleep(0.02)