feat: Ctrl+Shift+Q quick-search-fill + Edge browser directive
Ctrl+Shift+Q quick-search + autofill
- New global hotkey: capture the foreground HWND, restore the window
if hidden, pop the quick-search modal in "fill mode". On pick, the
password is SendInput'd into the saved HWND — no clipboard touch.
- hide_after flag added to cmd://autofill/execute: when set (tray-mode
hotkey), Delphi MinimizeToTray's *after* SendInput completes. Hiding
before SendInput would trip Win10/11 anti-focus-stealing rules and
block focus handoff to the target.
- Quick-search modal hint text adapts to fill vs copy mode.
- Esc / close in fill mode sends cmd://autofill/cancel so a stale
HWND doesn't get reused by an unrelated Ctrl+Shift+L later.
Compile-time browser engine switch
- {.$DEFINE USE_EDGE_BROWSER} in UMainForm.pas selects between
TTMSFNCWebBrowser (default, cross-platform abstraction) and
TTMSFNCEdgeWebBrowser (Windows-only WebView2 wrapper). Both
inherit from TTMSFNCCustomWebBrowser so the bridge cmd:// glue is
unchanged; the field type is a conditional alias TWebBrowserClass.
- WebBrowser is created dynamically in FormCreate so neither variant
needs a second .fmx. Events are wired BEFORE Parent assignment so
OnInitialized doesn't race the WebView2 async init on fast/pre-warmed
Edge installs (was silently missing the disable-context-menu /
disable-accelerator-keys calls).
- Native context menu disabled by assigning an empty PopupMenu1 (works
for both backends, unlike OnGetContextMenu which is publish-gated
via {$IFNDEF FNCLIB} on TTMSFNCWebBrowser).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -109,6 +109,12 @@ type
|
||||
FOnDebugHotkey: TProc;
|
||||
FNewEntryHotkeyRegistered: Boolean;
|
||||
FOnNewEntryHotkey: TNewEntryHotkeyEvent;
|
||||
// Ctrl+Shift+Q — "Quick search + autofill": open the JS quick-search
|
||||
// modal, the user picks an entry, the password is SendInput'd into the
|
||||
// window that had focus at hotkey time (captured into FAutofillTargetHWND
|
||||
// by the host).
|
||||
FQuickSearchHotkeyRegistered: Boolean;
|
||||
FOnQuickSearchHotkey: TAutofillRequestEvent;
|
||||
procedure MsgWindowHandler(var AMsg: TMessage);
|
||||
procedure PrepareNid;
|
||||
procedure ShowTrayMenu;
|
||||
@@ -183,6 +189,11 @@ type
|
||||
// browser suffix by the JS layer before pre-fill).
|
||||
property OnNewEntryHotkey: TNewEntryHotkeyEvent
|
||||
read FOnNewEntryHotkey write FOnNewEntryHotkey;
|
||||
// Fires on Ctrl+Shift+Q — quick-search-and-fill. Args mirror the
|
||||
// regular autofill hotkey so the host can save the target HWND and
|
||||
// pop the JS modal. Kind is always akPasswordOnly (no Tab).
|
||||
property OnQuickSearchHotkey: TAutofillRequestEvent
|
||||
read FOnQuickSearchHotkey write FOnQuickSearchHotkey;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@@ -227,6 +238,7 @@ const
|
||||
AUTOFILL_HOTKEY_ID_PWDONLY = 43; // Ctrl+Shift+P → password only
|
||||
DEBUG_HOTKEY_ID = 44; // Ctrl+Shift+D → toggle debug panel
|
||||
NEW_ENTRY_HOTKEY_ID = 45; // Ctrl+Shift+A → quick-add from window title
|
||||
QUICK_SEARCH_HOTKEY_ID = 46; // Ctrl+Shift+Q → quick-search-and-fill
|
||||
AF_MOD_CONTROL = $0002; // same value as MOD_CONTROL
|
||||
AF_MOD_SHIFT = $0004; // same value as MOD_SHIFT
|
||||
|
||||
@@ -422,6 +434,8 @@ begin
|
||||
AF_MOD_CONTROL or AF_MOD_SHIFT, Ord('D'));
|
||||
FNewEntryHotkeyRegistered := RegisterHotKey(FMsgWindow, NEW_ENTRY_HOTKEY_ID,
|
||||
AF_MOD_CONTROL or AF_MOD_SHIFT, Ord('A'));
|
||||
FQuickSearchHotkeyRegistered := RegisterHotKey(FMsgWindow,
|
||||
QUICK_SEARCH_HOTKEY_ID, AF_MOD_CONTROL or AF_MOD_SHIFT, Ord('Q'));
|
||||
end;
|
||||
|
||||
destructor TPMBridge.Destroy;
|
||||
@@ -432,6 +446,9 @@ begin
|
||||
if FNewEntryHotkeyRegistered then
|
||||
UnregisterHotKey(FMsgWindow, NEW_ENTRY_HOTKEY_ID);
|
||||
|
||||
if FQuickSearchHotkeyRegistered then
|
||||
UnregisterHotKey(FMsgWindow, QUICK_SEARCH_HOTKEY_ID);
|
||||
|
||||
if (FPowerNotify <> 0) and Assigned(_PowerUnregister) then
|
||||
_PowerUnregister(FPowerNotify);
|
||||
|
||||
@@ -739,6 +756,22 @@ begin
|
||||
end;
|
||||
end
|
||||
|
||||
else if (AMsg.Msg = WM_HOTKEY) and (AMsg.WParam = QUICK_SEARCH_HOTKEY_ID) then
|
||||
begin
|
||||
// Quick-search + autofill: capture the foreground HWND BEFORE the JS
|
||||
// modal steals focus, hand it to the host so it can stash it in
|
||||
// FAutofillTargetHWND (consumed by cmd://autofill/execute later).
|
||||
if Assigned(FOnQuickSearchHotkey) then
|
||||
begin
|
||||
var LTarget := GetForegroundWindow;
|
||||
var LTitle: string;
|
||||
SetLength(LTitle, 512);
|
||||
var LLen := GetWindowTextW(LTarget, PChar(LTitle), 512);
|
||||
SetLength(LTitle, LLen);
|
||||
FOnQuickSearchHotkey(akPasswordOnly, LTarget, LTitle);
|
||||
end;
|
||||
end
|
||||
|
||||
else if (AMsg.Msg = WM_HOTKEY) and Assigned(FOnAutofillRequest) and
|
||||
((AMsg.WParam = AUTOFILL_HOTKEY_ID_FULL) or
|
||||
(AMsg.WParam = AUTOFILL_HOTKEY_ID_PWDONLY)) then
|
||||
|
||||
Reference in New Issue
Block a user