diff --git a/delphi-backend/Source/PM.Bridge.pas b/delphi-backend/Source/PM.Bridge.pas index d166fa1..402b730 100644 --- a/delphi-backend/Source/PM.Bridge.pas +++ b/delphi-backend/Source/PM.Bridge.pas @@ -41,6 +41,9 @@ type TSecureClipboard = class private FClearTimer: TTimer; + // Clipboard sequence number right after OUR SetText. If it moved, the + // user copied something else since — that content is theirs, not ours. + FSetSequence: DWORD; procedure ClearTimerTick(Sender: TObject); public constructor Create; @@ -50,6 +53,10 @@ type // AClearAfterMs = 0 disables auto-clear; default is 30 seconds. procedure SetText(const AText: string; AClearAfterMs: Integer = 30000); procedure Clear; + // Clear only if the clipboard still holds what WE put there (sequence + // unchanged). Auto-clear timer + minimize-to-tray use this so they never + // wipe something the user copied from another app in the meantime. + procedure ClearIfOurs; end; // Distinguishes the "fill everything" hotkey (Ctrl+Shift+L) from the @@ -341,7 +348,7 @@ end; procedure TSecureClipboard.ClearTimerTick(Sender: TObject); begin FClearTimer.Enabled := False; - Clear; + ClearIfOurs; end; procedure TSecureClipboard.SetText(const AText: string; AClearAfterMs: Integer); @@ -385,6 +392,10 @@ begin CloseClipboard; end; + // Snapshot the sequence AFTER our write — any later copy (ours or another + // app's) bumps it, which is exactly the "is it still ours?" signal. + FSetSequence := GetClipboardSequenceNumber; + if AClearAfterMs > 0 then begin FClearTimer.Interval := AClearAfterMs; @@ -402,6 +413,12 @@ begin end; end; +procedure TSecureClipboard.ClearIfOurs; +begin + if GetClipboardSequenceNumber = FSetSequence then + Clear; +end; + function TSecureClipboard.ReadText: string; var H: THandle; @@ -581,9 +598,10 @@ begin // out of sight. SKIPPED when AClearClipboard=False — the quick-search // copy-then-hide flow deliberately keeps the password on the clipboard // (the 30s auto-clear timer still guards it) so the user can paste it - // into their target app after we minimise. + // into their target app after we minimise. ClearIfOurs: never wipe + // content the user copied from another app since. if AClearClipboard then - FSecureClipboard.Clear; + FSecureClipboard.ClearIfOurs; LFormHwnd := MainFormHWND(FMainForm); LAppHwnd := FindFMXAppWindow;