fix(autofill): refuse a fill while a blocking operation runs

Guarded in autofillHandleRequest, upstream of the single-match versus picker split, so it covers Ctrl+Shift+L/P/T and both outcomes: the picker would open behind the overlay, and a single-match fill would minimise our window mid-operation. Cancels the request so Delphi drops the captured target HWND.
This commit is contained in:
r-zakarya
2026-08-01 18:04:35 +01:00
parent be629b2bcf
commit 03cc7adc25
2 changed files with 13 additions and 0 deletions
+2
View File
@@ -174,6 +174,8 @@ plus bas.
- **ATTENDU** : ni l'éditeur ni la quick search ne s'ouvrent ; toast « Busy — try again in a moment ». Tout redevient normal une fois l'overlay parti. - **ATTENDU** : ni l'éditeur ni la quick search ne s'ouvrent ; toast « Busy — try again in a moment ». Tout redevient normal une fois l'overlay parti.
- **Pourquoi les hotkeys échappent aux gardes UI** : ils arrivent de Win32, **hors de la fenêtre**. L'overlay qui couvre l'application n'intercepte rien : le panneau s'ouvrait derrière lui, inaccessible. - **Pourquoi les hotkeys échappent aux gardes UI** : ils arrivent de Win32, **hors de la fenêtre**. L'overlay qui couvre l'application n'intercepte rien : le panneau s'ouvrait derrière lui, inaccessible.
- **Où est posé le garde** : dans `openSlideOver` et `openQuickSearchModal`, pas sur chaque déclencheur — c'est le point de passage de *tous* les appelants (hotkey, palette de commandes, bouton *Fix* du vault health). Sûr parce qu'**aucun chemin de sauvegarde n'affiche l'overlay** : rien de légitime n'ouvre l'éditeur pendant une opération bloquante. - **Où est posé le garde** : dans `openSlideOver` et `openQuickSearchModal`, pas sur chaque déclencheur — c'est le point de passage de *tous* les appelants (hotkey, palette de commandes, bouton *Fix* du vault health). Sûr parce qu'**aucun chemin de sauvegarde n'affiche l'overlay** : rien de légitime n'ouvre l'éditeur pendant une opération bloquante.
- **ACTION 2 — autofill** : pendant l'overlay, `Ctrl+Shift+L`, `Ctrl+Shift+P`, `Ctrl+Shift+T`, avec un titre à **un seul** candidat puis à **plusieurs**.
- **ATTENDU** : rien ne se remplit, aucun picker, même toast. Le garde est dans `autofillHandleRequest`, en amont du choix match-unique / picker, donc il couvre les trois hotkeys et les deux issues. Il appelle `Bridge.cancelAutofill()` pour que Delphi ne garde pas la fenêtre cible capturée en attente d'un remplissage qui ne viendra jamais.
### B14 · dialogues natifs ouverts par un clic programmatique ### B14 · dialogues natifs ouverts par un clic programmatique
- **ACTION** : `A` ouverte + **dirty** → (a) Settings → *Import vault* ; (b) télécharger une pièce jointe (fallback web) ; (c) *Upload icon* ; (d) joindre un fichier. - **ACTION** : `A` ouverte + **dirty** → (a) Settings → *Import vault* ; (b) télécharger une pièce jointe (fallback web) ; (c) *Upload icon* ; (d) joindre un fichier.
+11
View File
@@ -236,6 +236,17 @@ function autofillReportResult(ok) {
async function autofillHandleRequest(windowTitle, kind) { async function autofillHandleRequest(windowTitle, kind) {
if (!state.autofillEnabled) return; if (!state.autofillEnabled) return;
// A blocking operation owns the screen (export, sync, rotation). Covers all
// three hotkeys and both outcomes: the multi-match picker would open behind
// the overlay, unreachable, and a single-match fill would minimise our
// window and hand the foreground away mid-operation. cancelAutofill so
// Delphi doesn't keep the captured target HWND for a fill that never comes.
if (typeof isBusy === 'function' && isBusy()) {
Bridge.cancelAutofill();
toast('Busy — try again in a moment', 'warning');
return;
}
if (!state.cryptoKey || state.locked || !state.token) { if (!state.cryptoKey || state.locked || !state.token) {
// Vault is locked — bring the app to the front so the user can // Vault is locked — bring the app to the front so the user can
// unlock immediately, rather than silently no-op'ing the hotkey. // unlock immediately, rather than silently no-op'ing the hotkey.