fix(autofill): unregister new-entry hotkey during SendInput (chord fire)
Ctrl+Shift+P (password autofill) with Ctrl+Shift physically held triggered new-entry: the clear-field step injects a real Ctrl+A, and the held modifiers (re-pressed by keyboard auto-repeat faster than ForceReleaseModifiers clears them) make the system see Ctrl+Shift+A = our new-entry global hotkey. Injected keys are only Ctrl+A + Tab, and only 'A' matches a hotkey, so unregister NEW_ENTRY around the SendInput (try/finally re-register) — no WM_HOTKEY is generated. Password/username go as VK_PACKET unicode, can't chord. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1315,32 +1315,45 @@ begin
|
|||||||
// Past every bail-out — the keystrokes below are the fill itself.
|
// Past every bail-out — the keystrokes below are the fill itself.
|
||||||
Result := True;
|
Result := True;
|
||||||
|
|
||||||
// Username-only: type just the username into the focused field, no Tab,
|
// Our own new-entry hotkey is Ctrl+Shift+A. The clear-field step injects a
|
||||||
// no password. Used by the quick-search right-click / Shift+Enter path.
|
// real Ctrl+A; if the user still physically holds Ctrl+Shift (they just
|
||||||
if AUsernameOnly then
|
// pressed the autofill hotkey, and auto-repeat re-presses the modifiers
|
||||||
begin
|
// faster than ForceReleaseModifiers can clear them), the system sees
|
||||||
|
// Ctrl+Shift+A and fires new-entry mid-fill. Unregister it for the duration
|
||||||
|
// of the SendInput so no WM_HOTKEY is generated; re-register in finally.
|
||||||
|
UnregisterHotKey(FMsgWindow, NEW_ENTRY_HOTKEY_ID);
|
||||||
|
try
|
||||||
|
// Username-only: type just the username into the focused field, no Tab,
|
||||||
|
// no password. Used by the quick-search right-click / Shift+Enter path.
|
||||||
|
if AUsernameOnly then
|
||||||
|
begin
|
||||||
|
ClearFieldIfWanted;
|
||||||
|
SendUnicodeString(AUsername);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if AUsername = '' then
|
||||||
|
begin
|
||||||
|
ClearFieldIfWanted;
|
||||||
|
SendUnicodeString(APassword);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
ClearFieldIfWanted;
|
ClearFieldIfWanted;
|
||||||
SendUnicodeString(AUsername);
|
SendUnicodeString(AUsername);
|
||||||
Exit;
|
Sleep(200);
|
||||||
end;
|
// Real-VK send: a physically held Shift here turns Tab into Shift+Tab —
|
||||||
|
// focus moves BACKWARD and the password lands in the username field.
|
||||||
if AUsername = '' then
|
ForceReleaseModifiers;
|
||||||
begin
|
SendVKey(VK_TAB);
|
||||||
|
Sleep(200);
|
||||||
ClearFieldIfWanted;
|
ClearFieldIfWanted;
|
||||||
SendUnicodeString(APassword);
|
SendUnicodeString(APassword);
|
||||||
Exit;
|
finally
|
||||||
|
if FNewEntryHotkeyRegistered then
|
||||||
|
RegisterHotKey(FMsgWindow, NEW_ENTRY_HOTKEY_ID,
|
||||||
|
AF_MOD_CONTROL or AF_MOD_SHIFT, Ord('A'));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ClearFieldIfWanted;
|
|
||||||
SendUnicodeString(AUsername);
|
|
||||||
Sleep(200);
|
|
||||||
// Real-VK send: a physically held Shift here turns Tab into Shift+Tab —
|
|
||||||
// focus moves BACKWARD and the password lands in the username field.
|
|
||||||
ForceReleaseModifiers;
|
|
||||||
SendVKey(VK_TAB);
|
|
||||||
Sleep(200);
|
|
||||||
ClearFieldIfWanted;
|
|
||||||
SendUnicodeString(APassword);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|||||||
Reference in New Issue
Block a user