fix(window): apply the restore correction after FMX finishes, with tracing
The FWasMinimized gate never armed — FMX evidently fires no resize while the window is iconic — so activate bailed out and the maximised window still came back normal. Stop depending on that signal or on event ordering: snapshot the intent at activate (before a restore-time resize can overwrite it) and apply the correction from a queued call, which necessarily runs after FMX has finished sizing the window. FRestoring keeps that resize out of the tracking, and the intent is re-asserted afterwards since our own ShowWindow fires one too. Adds [winstate] LogLine traces so the next iteration works from observed event order instead of guesses (needs config.txt with debug=true). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -82,6 +82,9 @@ type
|
||||
// True between an external minimise and the following activate, so the
|
||||
// restore's own resize is not mistaken for a user resize.
|
||||
FWasMinimized: Boolean;
|
||||
// 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;
|
||||
FServer: TPMHTTPServer;
|
||||
FBridge: TPMBridge;
|
||||
// Accumulates base64 chunks for large file saves (attachments too big
|
||||
@@ -178,6 +181,7 @@ begin
|
||||
// Wired here (not in the .fmx) to keep the designer file untouched.
|
||||
FWantMaximized := (WindowState = TWindowState.wsMaximized);
|
||||
FWasMinimized := False;
|
||||
FRestoring := False;
|
||||
OnResize := FormResizeTrackState;
|
||||
OnActivate := FormActivateRestoreState;
|
||||
|
||||
@@ -1523,10 +1527,18 @@ begin
|
||||
if IsIconic(LHwnd) then
|
||||
begin
|
||||
FWasMinimized := True; // the state we must survive, not record
|
||||
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;
|
||||
if FWasMinimized then Exit; // this resize IS the restore
|
||||
FWantMaximized := IsZoomed(LHwnd); // genuine user-driven resize
|
||||
LogLine('[winstate] resize: want_max=' + BoolToStr(FWantMaximized, True));
|
||||
end;
|
||||
|
||||
// Re-apply the remembered state once the window is back. Runs however the
|
||||
@@ -1535,17 +1547,39 @@ end;
|
||||
// a maximised window to normal, and Windows can restore a normal window
|
||||
// maximised.
|
||||
procedure TMainForm.FormActivateRestoreState(Sender: TObject);
|
||||
var
|
||||
LWant: Boolean;
|
||||
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.
|
||||
LWant := FWantMaximized;
|
||||
if FRestoring then Exit; // one correction per return
|
||||
FRestoring := True;
|
||||
LogLine('[winstate] activate: want_max=' + BoolToStr(LWant, True) +
|
||||
' was_min=' + BoolToStr(FWasMinimized, True));
|
||||
// Queue the correction so it runs AFTER FMX has finished restoring the
|
||||
// window — applying it inline loses the race against FMX's own sizing.
|
||||
TThread.ForceQueue(nil,
|
||||
procedure
|
||||
var
|
||||
LHwnd: HWND;
|
||||
begin
|
||||
if not FWasMinimized then Exit;
|
||||
FRestoring := False;
|
||||
FWasMinimized := False;
|
||||
LHwnd := WindowHandleToPlatform(Self.Handle).Wnd;
|
||||
if (LHwnd = 0) or IsIconic(LHwnd) then Exit;
|
||||
FWasMinimized := False;
|
||||
if FWantMaximized = IsZoomed(LHwnd) then Exit; // already right
|
||||
if FWantMaximized then ShowWindow(LHwnd, SW_SHOWMAXIMIZED)
|
||||
if LWant <> IsZoomed(LHwnd) then
|
||||
begin
|
||||
LogLine('[winstate] correcting to ' +
|
||||
BoolToStr(LWant, True) + ' (was zoomed=' +
|
||||
BoolToStr(IsZoomed(LHwnd), True) + ')');
|
||||
if LWant then ShowWindow(LHwnd, SW_SHOWMAXIMIZED)
|
||||
else ShowWindow(LHwnd, SW_RESTORE);
|
||||
end;
|
||||
FWantMaximized := LWant; // our own ShowWindow fired a resize too
|
||||
end);
|
||||
end;
|
||||
|
||||
procedure TMainForm.AutofillTimerTick(Sender: TObject);
|
||||
var
|
||||
|
||||
Reference in New Issue
Block a user