diff --git a/visual_workflow_builder/backend/api_v3/execute.py b/visual_workflow_builder/backend/api_v3/execute.py index d66590efb..1fd57ecb9 100644 --- a/visual_workflow_builder/backend/api_v3/execute.py +++ b/visual_workflow_builder/backend/api_v3/execute.py @@ -78,26 +78,16 @@ def safe_type_text(text): """Saisie de texte compatible VM/Citrix et claviers AZERTY/QWERTY. Priorité : - 1. xdotool type → frappes clavier réelles, traverse QEMU/Citrix/RDP - 2. Presse-papier (xclip) + Ctrl+V → fallback local uniquement - 3. pyautogui.write() → dernier recours + 1. Presse-papier (xclip) + Ctrl+V → fiable, traverse spice/Citrix/RDP + 2. xdotool type → fallback si clipboard échoue + 3. pyautogui.write() → dernier recours """ import shutil import pyautogui - # 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: - _xdotool_type_by_keysym(text) - print(f" ✅ Saisie via xdotool key ({len(text)} car.)") - return - except Exception as e: - print(f" ⚠️ xdotool key échoué: {e}") - - # Méthode 2 : Presse-papier (fonctionne seulement en local, pas en VM) + # Méthode 1 : Presse-papier (le plus fiable) + # Traverse les VM via spice-vdagent et les sessions Citrix/RDP + # via le clipboard partagé natif. Pas de problème de layout clavier. xclip = shutil.which('xclip') if xclip: try: @@ -117,6 +107,19 @@ def safe_type_text(text): except Exception as e: print(f" ⚠️ xclip échoué: {e}") + # Méthode 2 : xdotool type (fallback si clipboard échoue) + if shutil.which('xdotool'): + try: + subprocess.run( + ['xdotool', 'type', '--delay', '0', '--clearmodifiers', '--', text], + timeout=max(30, len(text) * 0.05), + check=True + ) + print(f" ✅ Saisie via xdotool type ({len(text)} car.)") + return + except Exception as e: + print(f" ⚠️ xdotool type échoué: {e}") + # Méthode 3 : pyautogui (dernier recours — problèmes AZERTY possibles) print(" ⚠️ Saisie via pyautogui.write() (AZERTY non garanti)") pyautogui.write(text)