From 03cc7adc250c7331d33e06425c5329be89753b13 Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Sat, 1 Aug 2026 18:04:35 +0100 Subject: [PATCH] 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. --- TEST_SCENARIOS.md | 2 ++ js/app.autofill.js | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/TEST_SCENARIOS.md b/TEST_SCENARIOS.md index 7cb021c..e1154b8 100644 --- a/TEST_SCENARIOS.md +++ b/TEST_SCENARIOS.md @@ -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. - **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. +- **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 - **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. diff --git a/js/app.autofill.js b/js/app.autofill.js index c559068..a0cc669 100644 --- a/js/app.autofill.js +++ b/js/app.autofill.js @@ -236,6 +236,17 @@ function autofillReportResult(ok) { async function autofillHandleRequest(windowTitle, kind) { 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) { // Vault is locked — bring the app to the front so the user can // unlock immediately, rather than silently no-op'ing the hotkey.