fix(window): let an activate cancel the restore's own resize
The traces settled it: on a restore FMX fires its resize BEFORE the activate, already reporting "not maximised" — so any snapshot taken at activate time was too late. A genuine user resize, by contrast, is never followed by an activate (the window is already active). That is the discriminator. A resize no longer commits immediately: it queues, and an activate arriving first cancels it, leaving the intent intact for the correction to re-apply. Verified against every sequence in the log, including the startup burst (three resizes then an activate), which must NOT be mistaken for the user un-maximising. Skips resizes that don't change the maximised state, so dragging the window edge no longer floods the queue or the log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user