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
|
// Set from activate until the queued correction runs, so the restore's
|
||||||
// own resize is not mistaken for the user resizing the window.
|
// own resize is not mistaken for the user resizing the window.
|
||||||
FRestoring: Boolean;
|
FRestoring: Boolean;
|
||||||
|
// A resize awaiting confirmation that no activate follows it.
|
||||||
|
FResizePending, FPendingZoomed: Boolean;
|
||||||
FServer: TPMHTTPServer;
|
FServer: TPMHTTPServer;
|
||||||
FBridge: TPMBridge;
|
FBridge: TPMBridge;
|
||||||
// Accumulates base64 chunks for large file saves (attachments too big
|
// Accumulates base64 chunks for large file saves (attachments too big
|
||||||
@@ -182,6 +184,7 @@ begin
|
|||||||
FWantMaximized := (WindowState = TWindowState.wsMaximized);
|
FWantMaximized := (WindowState = TWindowState.wsMaximized);
|
||||||
FWasMinimized := False;
|
FWasMinimized := False;
|
||||||
FRestoring := False;
|
FRestoring := False;
|
||||||
|
FResizePending := False;
|
||||||
OnResize := FormResizeTrackState;
|
OnResize := FormResizeTrackState;
|
||||||
OnActivate := FormActivateRestoreState;
|
OnActivate := FormActivateRestoreState;
|
||||||
|
|
||||||
@@ -1530,15 +1533,27 @@ begin
|
|||||||
LogLine('[winstate] resize: minimised');
|
LogLine('[winstate] resize: minimised');
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
if FRestoring then
|
// Observed order on a restore: FMX fires its resize BEFORE the activate, so
|
||||||
begin
|
// committing here would destroy the intent we are about to need. A genuine
|
||||||
// The restore's own resize: reports whatever FMX decided, not intent.
|
// user resize is never followed by an activate (the window is already
|
||||||
LogLine('[winstate] resize during restore ignored (zoomed=' +
|
// active) — so defer the commit one message-pump turn and let an incoming
|
||||||
BoolToStr(IsZoomed(LHwnd), True) + ')');
|
// activate cancel it.
|
||||||
Exit;
|
// Nothing to learn when the maximised state is unchanged — and this is what
|
||||||
end;
|
// keeps a mouse-drag resize (which fires continuously) from flooding the
|
||||||
FWantMaximized := IsZoomed(LHwnd); // genuine user-driven resize
|
// queue and the log.
|
||||||
LogLine('[winstate] resize: want_max=' + BoolToStr(FWantMaximized, True));
|
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;
|
end;
|
||||||
|
|
||||||
// Re-apply the remembered state once the window is back. Runs however the
|
// 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
|
// 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
|
// after this activate depending on how the window came back, and if it
|
||||||
// lands first it would already have overwritten FWantMaximized.
|
// 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;
|
LWant := FWantMaximized;
|
||||||
if FRestoring then Exit; // one correction per return
|
if FRestoring then Exit; // one correction per return
|
||||||
FRestoring := True;
|
FRestoring := True;
|
||||||
|
|||||||
Reference in New Issue
Block a user