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
|
// True between an external minimise and the following activate, so the
|
||||||
// restore's own resize is not mistaken for a user resize.
|
// restore's own resize is not mistaken for a user resize.
|
||||||
FWasMinimized: Boolean;
|
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;
|
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
|
||||||
@@ -178,6 +181,7 @@ begin
|
|||||||
// Wired here (not in the .fmx) to keep the designer file untouched.
|
// Wired here (not in the .fmx) to keep the designer file untouched.
|
||||||
FWantMaximized := (WindowState = TWindowState.wsMaximized);
|
FWantMaximized := (WindowState = TWindowState.wsMaximized);
|
||||||
FWasMinimized := False;
|
FWasMinimized := False;
|
||||||
|
FRestoring := False;
|
||||||
OnResize := FormResizeTrackState;
|
OnResize := FormResizeTrackState;
|
||||||
OnActivate := FormActivateRestoreState;
|
OnActivate := FormActivateRestoreState;
|
||||||
|
|
||||||
@@ -1523,10 +1527,18 @@ begin
|
|||||||
if IsIconic(LHwnd) then
|
if IsIconic(LHwnd) then
|
||||||
begin
|
begin
|
||||||
FWasMinimized := True; // the state we must survive, not record
|
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;
|
Exit;
|
||||||
end;
|
end;
|
||||||
if FWasMinimized then Exit; // this resize IS the restore
|
|
||||||
FWantMaximized := IsZoomed(LHwnd); // genuine user-driven resize
|
FWantMaximized := IsZoomed(LHwnd); // genuine user-driven resize
|
||||||
|
LogLine('[winstate] resize: want_max=' + BoolToStr(FWantMaximized, True));
|
||||||
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
|
||||||
@@ -1536,15 +1548,37 @@ end;
|
|||||||
// maximised.
|
// maximised.
|
||||||
procedure TMainForm.FormActivateRestoreState(Sender: TObject);
|
procedure TMainForm.FormActivateRestoreState(Sender: TObject);
|
||||||
var
|
var
|
||||||
LHwnd: HWND;
|
LWant: Boolean;
|
||||||
begin
|
begin
|
||||||
if not FWasMinimized then Exit;
|
// 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
|
||||||
|
FRestoring := False;
|
||||||
|
FWasMinimized := False;
|
||||||
LHwnd := WindowHandleToPlatform(Self.Handle).Wnd;
|
LHwnd := WindowHandleToPlatform(Self.Handle).Wnd;
|
||||||
if (LHwnd = 0) or IsIconic(LHwnd) then Exit;
|
if (LHwnd = 0) or IsIconic(LHwnd) then Exit;
|
||||||
FWasMinimized := False;
|
if LWant <> IsZoomed(LHwnd) then
|
||||||
if FWantMaximized = IsZoomed(LHwnd) then Exit; // already right
|
begin
|
||||||
if FWantMaximized then ShowWindow(LHwnd, SW_SHOWMAXIMIZED)
|
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);
|
else ShowWindow(LHwnd, SW_RESTORE);
|
||||||
|
end;
|
||||||
|
FWantMaximized := LWant; // our own ShowWindow fired a resize too
|
||||||
|
end);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.AutofillTimerTick(Sender: TObject);
|
procedure TMainForm.AutofillTimerTick(Sender: TObject);
|
||||||
|
|||||||
Reference in New Issue
Block a user