diff --git a/TEST_SCENARIOS.md b/TEST_SCENARIOS.md index 43a2d2d..27fa89c 100644 --- a/TEST_SCENARIOS.md +++ b/TEST_SCENARIOS.md @@ -459,8 +459,9 @@ l'éditeur slideover : créer + éditer une entrée, ajouter/retirer des tags, - **ATTENDU** : accepté et actif immédiatement ; **refusé** s'il duplique un des 4 autres hotkeys ; *Reset to defaults* le remet à `Ctrl+Shift+T` ; le réglage survit à un redémarrage (synced via `settings_json`). ### H5 · coffre verrouillé ✅ -- **ACTION** : verrouiller → `Ctrl+Shift+T`. -- **ATTENDU** : l'app revient au premier plan avec le focus sur le master password (même comportement que les autres hotkeys), pas de no-op silencieux. +- **ACTION** : verrouiller → `Ctrl+Shift+T`, puis **`Ctrl+Shift+Q`**, depuis une autre application (Notepad). +- **ATTENDU** : l'app revient au premier plan **et y reste**, focus sur le master password. Pas de no-op silencieux, et **aucun clignotement** : elle ne doit pas apparaître puis rendre la main à l'application de départ. +- **Historique** : les deux chemins « coffre verrouillé » annulaient l'autofill avec le refocus **par défaut**, qui rend volontairement le premier plan à la fenêtre cible — juste après que Delphi ait affiché notre fenêtre. Sur `Ctrl+Shift+Q` ça se voyait comme un flash d'une frame avant le retour à Notepad ; sur `Ctrl+Shift+L` le `focusApp()` qui suit reprenait le focus, donc deux déplacements de fenêtre pour finir là où un seul suffit. Les deux passent maintenant `refocus=false` (cf. B17 : **un refus ne doit jamais déplacer une fenêtre**). ### H9 · retour au tray après un pick dans le picker ✅ - **ACTION** : app **au tray** → `Ctrl+Shift+L` depuis une autre app sur un titre à plusieurs candidats → le picker sort la fenêtre du tray → choisir une entrée. diff --git a/js/app.autofill.js b/js/app.autofill.js index 06f2011..c9e5da4 100644 --- a/js/app.autofill.js +++ b/js/app.autofill.js @@ -253,7 +253,10 @@ async function autofillHandleRequest(windowTitle, kind) { 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. - Bridge.cancelAutofill(); + // refocus=false: the default hands the foreground back to the target, + // which focusApp would then have to take away again — two window moves + // to end where one gets us, and the round trip is visible. + Bridge.cancelAutofill(false); Bridge.focusApp(); setTimeout(() => { const pwd = document.getElementById('loginPassword'); diff --git a/js/app.js b/js/app.js index 15d0426..9cc8a98 100644 --- a/js/app.js +++ b/js/app.js @@ -550,8 +550,12 @@ const Bridge = (() => { if (typeof toast === 'function') toast('Vault is locked — unlock to search', 'warning'); // Tell Delphi we cancelled so the captured HWND doesn't - // linger waiting for a never-coming /execute. - if (forFill && Bridge.cancelAutofill) Bridge.cancelAutofill(); + // linger waiting for a never-coming /execute. refocus=false: + // Delphi has just brought our window up and we put the cursor + // in the master-password field — handing the foreground back + // to the target would undo that, which read as a 1-frame flash + // before the other application took over again. + if (forFill && Bridge.cancelAutofill) Bridge.cancelAutofill(false); return; } if (typeof openQuickSearchModal === 'function')