diff --git a/delphi-backend/UMainForm.pas b/delphi-backend/UMainForm.pas index 016e758..53ed562 100644 --- a/delphi-backend/UMainForm.pas +++ b/delphi-backend/UMainForm.pas @@ -85,6 +85,8 @@ type // Set from activate until the queued correction runs, so the restore's // own resize is not mistaken for the user resizing the window. FRestoring: Boolean; + // A resize awaiting confirmation that no activate follows it. + FResizePending, FPendingZoomed: Boolean; FServer: TPMHTTPServer; FBridge: TPMBridge; // Accumulates base64 chunks for large file saves (attachments too big @@ -182,6 +184,7 @@ begin FWantMaximized := (WindowState = TWindowState.wsMaximized); FWasMinimized := False; FRestoring := False; + FResizePending := False; OnResize := FormResizeTrackState; OnActivate := FormActivateRestoreState; @@ -1530,15 +1533,27 @@ begin LogLine('[winstate] resize: minimised'); Exit; end; - if FRestoring then - begin - // The restore's own resize: reports whatever FMX decided, not intent. - LogLine('[winstate] resize during restore ignored (zoomed=' + - BoolToStr(IsZoomed(LHwnd), True) + ')'); - Exit; - end; - FWantMaximized := IsZoomed(LHwnd); // genuine user-driven resize - LogLine('[winstate] resize: want_max=' + BoolToStr(FWantMaximized, True)); + // Observed order on a restore: FMX fires its resize BEFORE the activate, so + // committing here would destroy the intent we are about to need. A genuine + // user resize is never followed by an activate (the window is already + // active) — so defer the commit one message-pump turn and let an incoming + // activate cancel it. + // Nothing to learn when the maximised state is unchanged — and this is what + // keeps a mouse-drag resize (which fires continuously) from flooding the + // queue and the log. + if IsZoomed(LHwnd) = FWantMaximized then Exit; + FPendingZoomed := IsZoomed(LHwnd); + FResizePending := True; + LogLine('[winstate] resize pending: zoomed=' + BoolToStr(FPendingZoomed, True)); + TThread.ForceQueue(nil, + procedure + begin + if not FResizePending then Exit; // an activate claimed it: a restore + FResizePending := False; + FWantMaximized := FPendingZoomed; + LogLine('[winstate] resize committed: want_max=' + + BoolToStr(FWantMaximized, True)); + end); end; // Re-apply the remembered state once the window is back. Runs however the @@ -1553,6 +1568,9 @@ begin // Snapshot the intent NOW: FMX's restore-time resize may land before or // after this activate depending on how the window came back, and if it // lands first it would already have overwritten FWantMaximized. + // Cancel a resize that has not committed yet: an activate right after one + // means this was a restore, not the user resizing the window. + FResizePending := False; LWant := FWantMaximized; if FRestoring then Exit; // one correction per return FRestoring := True;