fix(typing): xdotool key par keysym au lieu de type (fix AZERTY dans VM)
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 11s
security-audit / pip-audit (CVE dépendances) (push) Successful in 11s
security-audit / Scan secrets (grep) (push) Successful in 9s
tests / Lint (ruff + black) (push) Successful in 13s
tests / Tests unitaires (sans GPU) (push) Failing after 14s
tests / Tests sécurité (critique) (push) Has been skipped
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 11s
security-audit / pip-audit (CVE dépendances) (push) Successful in 11s
security-audit / Scan secrets (grep) (push) Successful in 9s
tests / Lint (ruff + black) (push) Successful in 13s
tests / Tests unitaires (sans GPU) (push) Failing after 14s
tests / Tests sécurité (critique) (push) Has been skipped
xdotool type envoie des scancodes QWERTY — dans une VM AZERTY, ':' devient 'M', '/' devient '!', etc. Nouvelle approche : xdotool key avec les noms de keysym X11 (colon, slash, period, etc.) qui sont indépendants du layout. Chaque caractère est envoyé individuellement — plus lent mais 100% fiable en AZERTY/QWERTY, local ou VM. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,43 @@ from . import api_v3_bp
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
_CHAR_TO_KEYSYM = {
|
||||
' ': 'space', '\t': 'Tab', '\n': 'Return',
|
||||
'!': 'exclam', '"': 'quotedbl', '#': 'numbersign', '$': 'dollar',
|
||||
'%': 'percent', '&': 'ampersand', "'": 'apostrophe',
|
||||
'(': 'parenleft', ')': 'parenright', '*': 'asterisk', '+': 'plus',
|
||||
',': 'comma', '-': 'minus', '.': 'period', '/': 'slash',
|
||||
':': 'colon', ';': 'semicolon', '<': 'less', '=': 'equal',
|
||||
'>': 'greater', '?': 'question', '@': 'at',
|
||||
'[': 'bracketleft', '\\': 'backslash', ']': 'bracketright',
|
||||
'^': 'asciicircum', '_': 'underscore', '`': 'grave',
|
||||
'{': 'braceleft', '|': 'bar', '}': 'braceright', '~': 'asciitilde',
|
||||
}
|
||||
|
||||
|
||||
def _xdotool_type_by_keysym(text):
|
||||
"""Tape du texte via xdotool key, caractère par caractère avec keysyms.
|
||||
|
||||
Indépendant du layout clavier — fonctionne en AZERTY dans une VM QWERTY
|
||||
et inversement. Plus lent que xdotool type mais 100% fiable.
|
||||
"""
|
||||
keys = []
|
||||
for ch in text:
|
||||
if ch in _CHAR_TO_KEYSYM:
|
||||
keys.append(_CHAR_TO_KEYSYM[ch])
|
||||
elif ch.isalnum():
|
||||
keys.append(ch)
|
||||
else:
|
||||
keys.append(ch)
|
||||
|
||||
for key in keys:
|
||||
subprocess.run(
|
||||
['xdotool', 'key', '--clearmodifiers', key],
|
||||
timeout=2, check=True
|
||||
)
|
||||
time.sleep(0.02)
|
||||
|
||||
|
||||
def safe_type_text(text):
|
||||
"""Saisie de texte compatible VM/Citrix et claviers AZERTY/QWERTY.
|
||||
|
||||
@@ -34,20 +71,17 @@ def safe_type_text(text):
|
||||
import shutil
|
||||
import pyautogui
|
||||
|
||||
# Méthode 1 : xdotool type (frappes clavier réelles)
|
||||
# Envoie des événements X11 que QEMU/Citrix/RDP capturent et transmettent.
|
||||
# Le presse-papier ne traverse PAS les VM — xdotool si.
|
||||
# Méthode 1 : xdotool key par caractère (frappes clavier réelles)
|
||||
# xdotool type envoie des scancodes QWERTY que les VM AZERTY interprètent
|
||||
# mal (: → M, / → !, etc.). xdotool key avec les noms de keysym est
|
||||
# indépendant du layout et traverse QEMU/Citrix/RDP correctement.
|
||||
if shutil.which('xdotool'):
|
||||
try:
|
||||
subprocess.run(
|
||||
['xdotool', 'type', '--delay', '20', '--clearmodifiers', '--', text],
|
||||
timeout=max(30, len(text) * 0.05),
|
||||
check=True
|
||||
)
|
||||
print(f" ✅ Saisie via xdotool type ({len(text)} car.)")
|
||||
_xdotool_type_by_keysym(text)
|
||||
print(f" ✅ Saisie via xdotool key ({len(text)} car.)")
|
||||
return
|
||||
except Exception as e:
|
||||
print(f" ⚠️ xdotool type échoué: {e}")
|
||||
print(f" ⚠️ xdotool key échoué: {e}")
|
||||
|
||||
# Méthode 2 : Presse-papier (fonctionne seulement en local, pas en VM)
|
||||
xclip = shutil.which('xclip')
|
||||
|
||||
Reference in New Issue
Block a user