fix(hotkeys): name the combo another app already owns

Two gaps when Windows refuses a RegisterHotKey:
- the toast said "one or both hotkeys" — wrong since there are three autofill
  combos, and it never said which one lost.
- Quick search and New entry failures were only written to the debug panel,
  which is off in production: the hotkey silently did nothing with no clue why.

Delphi now exposes the per-slot registration outcome and the host accumulates
the failed combo names across all five hotkeys, emitting one notification for
the batch. A combo the user deliberately cleared (vk=0) is never listed.
JS names them: "Already used by another app: 2FA code — pick another combo in
Settings".

Registration stays best-effort per slot: one clash doesn't disarm the others.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-07-25 17:46:33 +01:00
parent 4c745d2dd9
commit 3d3ab3b02b
4 changed files with 40 additions and 11 deletions
+9 -6
View File
@@ -218,12 +218,15 @@ const Bridge = (() => {
// Called by Delphi after a setAutofillHotkeys request, with true if
// BOTH combos registered successfully, false otherwise (clash with
// another app holding a global hotkey). Surfaces a toast.
onAutofillHotkeysResult(allOk) {
if (allOk) {
toast('Autofill hotkeys updated');
} else {
toast('Autofill: one or both hotkeys are already used by another app', 'warning');
}
// `failed` = comma-separated names of the combos Windows refused
// (another app already owns them); empty string = all registered.
// Naming them matters: a clashing hotkey is otherwise indistinguishable
// from a broken feature — it just silently does nothing.
onAutofillHotkeysResult(failed) {
const list = String(failed || '').trim();
if (!list) { toast('Hotkeys updated'); return; }
toast('Already used by another app: ' + list +
' — pick another combo in Settings', 'warning');
},
// ---- Device-bound prefs (DPAPI-backed) ----------------------------