diff --git a/delphi-backend/UMainForm.pas b/delphi-backend/UMainForm.pas index 77292da..af5274c 100644 --- a/delphi-backend/UMainForm.pas +++ b/delphi-backend/UMainForm.pas @@ -72,6 +72,13 @@ type procedure btnToggleLogClick(Sender: TObject); procedure btnReloadClick(Sender: TObject); private + // Windows minimising the window from the outside (Win+D / Show desktop / + // taskbar) makes FMX forget it was maximised: the window comes back + // "normal". None of our restore paths run in that case — the taskbar + // restore is pure Windows + FMX — so the state is re-applied on activate, + // which happens however the user comes back. FWantMaximized mirrors the + // user's LAST deliberate choice, so we never fight a normal-size window. + FWantMaximized: Boolean; FServer: TPMHTTPServer; FBridge: TPMBridge; // Accumulates base64 chunks for large file saves (attachments too big @@ -116,6 +123,8 @@ type // needing two .fmx variants. Aligned to Client to fill the remaining // space between PanelTop (top) and PanelLog/Splitter (bottom). WebBrowser: TWebBrowserClass; + procedure FormActivateRestoreState(Sender: TObject); + procedure FormResizeTrackState(Sender: TObject); procedure AutofillTimerTick(Sender: TObject); // Shared by cmd://file/save (single-shot) and file/save-commit // (chunked): decode the base64, show the Save dialog, write, and fire @@ -162,6 +171,12 @@ function MaskAccessToken(const AUrl: string): string; forward; procedure TMainForm.FormCreate(Sender: TObject); begin + // The .fmx ships WindowState = wsMaximized, so that is the starting intent. + // Wired here (not in the .fmx) to keep the designer file untouched. + FWantMaximized := (WindowState = TWindowState.wsMaximized); + OnResize := FormResizeTrackState; + OnActivate := FormActivateRestoreState; + // Create the WebBrowser control programmatically so the {$IFDEF // USE_EDGE_BROWSER} directive can swap the concrete class without a // second .fmx variant. Align Client to fill the area below PanelTop @@ -1488,6 +1503,25 @@ begin Application.Terminate; end; +// Remember the window state the USER settled on. Minimised is skipped on +// purpose: that is precisely the state we have to survive, not record. +procedure TMainForm.FormResizeTrackState(Sender: TObject); +begin + if WindowState = TWindowState.wsMaximized then + FWantMaximized := True + else if WindowState = TWindowState.wsNormal then + FWantMaximized := False; +end; + +// Re-apply "maximised" when the window comes back from an external minimise. +// Runs however the user returns (taskbar, tray, Alt+Tab), because none of our +// own restore paths are involved in a plain taskbar click. +procedure TMainForm.FormActivateRestoreState(Sender: TObject); +begin + if FWantMaximized and (WindowState = TWindowState.wsNormal) then + WindowState := TWindowState.wsMaximized; +end; + procedure TMainForm.AutofillTimerTick(Sender: TObject); var TargetHwnd: HWND;