fix(autofill): stop sending Ctrl+A after the Tab in a full fill

Tabbing into an input already selects its whole content, so the second clear was redundant. Where Tab lands on something that is not editable - a link, a reveal button, the document, as on the Reddit login form - Ctrl+A selected the entire page instead and the password went nowhere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-07-28 15:32:25 +01:00
parent 40e2054496
commit 38ba208455
2 changed files with 14 additions and 4 deletions
+9 -3
View File
@@ -328,6 +328,12 @@ garde refusait, à raison, de pré-remplir avec « Password Manager »).
- **Non-régression** : après un autofill (pick ou Esc), le focus reste sur la fenêtre **remplie** — ces deux chemins passent `AReturnForeground = False`, ayant déjà placé le premier plan eux-mêmes.
- **Historique — quatre tentatives, toutes tranchées par le log** : (1) rendre le focus *après* avoir caché la fenêtre — Windows n'autorise que le propriétaire courant du premier plan à le céder, l'appel était silencieusement refusé ; (2) échantillonner le premier plan au moment du besoin — il vaut alors *notre* fenêtre, la capture se rejetait elle-même et n'apprenait jamais rien (`prev=<none>` à chaque fois) ; (3) capturer au clic sur l'icône du tray — on obtient une fenêtre du **shell** (`NotifyIconOverflowWindow`, « Fenêtre de dépassement de capacité de la barre d'état système ») ; (4) consommer la valeur après usage — le premier masquage marchait, les suivants plus. **Solution** : un hook `EVENT_SYSTEM_FOREGROUND` (`WINEVENT_OUTOFCONTEXT`, aucune injection) note *chaque* changement et garde le dernier qui n'est ni à nous ni au shell ; la restitution se fait **avant** de cacher.
### H13 · pas de `Ctrl+A` après le Tab (formulaires type Reddit)
- **ACTION** : `Ctrl+Shift+L` sur un formulaire où **Tab depuis le username ne mène pas au champ mot de passe** (page de connexion Reddit : le Tab tombe à côté).
- **ATTENDU** : plus de **sélection de toute la page**. Le mot de passe peut malgré tout ne pas être saisi si le focus n'a pas atterri dans un champ éditable — c'est la limite du Tab, pas un bug de plus.
- **Contournement pour ces formulaires** : cliquer le champ mot de passe puis `Ctrl+Shift+P` (remplissage password seul, aucun Tab).
- **Historique** : la séquence envoyait `Ctrl+A + Del` avant **chaque** champ. Après le Tab c'était doublement mauvais : redondant (arriver par Tab sélectionne déjà tout le contenu du champ, cf. K1) et destructeur quand le Tab tombe sur un lien, un bouton ou le document — `Ctrl+A` sélectionne alors la page entière et la frappe se perd. Retiré ; celui d'avant le username reste (l'utilisateur y a placé le curseur par un clic, rien n'est sélectionné).
### H11 · l'application précédente réduite reste réduite
- **ACTION** : depuis X, **réduire X** dans la barre des tâches → ouvrir le coffre (icône du tray) → le fermer par la croix.
- **ATTENDU** : X **reste réduite**. Le focus part où Windows décide ; on ne rouvre pas une fenêtre que l'utilisateur a rangée.
@@ -455,9 +461,9 @@ est précisément le piège de coalescence documenté dans CLAUDE.md.
- **OBSERVÉ** : le **username** n'est pas effacé (la frappe s'insère), mais
l'ancien **password** disparaît et est remplacé.
- **C'EST NORMAL** — vérifié de bout en bout : le JS envoie `&clear=0`, Delphi
met `FAutofillPendingClear := False`, et les **deux** `ClearFieldIfWanted`
(avant username et avant password) sortent immédiatement. Notre code
n'efface rien.
met `FAutofillPendingClear := False`. Notre code n'efface rien. (Depuis le
correctif H13 il n'y a de toute façon **plus qu'un seul** `ClearFieldIfWanted`,
avant le username : celui d'avant le password a été retiré.)
La cause est le **Tab** du pipeline `username → Tab → password` : arriver
dans un champ par Tab **sélectionne tout son contenu** (comportement standard
Windows / navigateur), et la frappe remplace la sélection. Le username, lui,