From 6bed75f49ee049baed4eeb0392e449cfa0b3ac2f Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Sat, 25 Jul 2026 19:50:24 +0100 Subject: [PATCH] fix(window): a maximised window comes back maximised after Show desktop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Win+D / Show desktop minimises the window without any tray transition, so the restore took the non-tray branch. FMainForm.Show runs first there and re-applies FMX's own WindowState (normal), discarding the WPF_RESTORETOMAXIMIZED flag Windows had recorded — the app returned in normal size. Read the placement flag BEFORE showing, and re-apply SW_SHOWMAXIMIZED when it was set. The tray path is untouched: it already replays its own captured placement. Co-Authored-By: Claude Opus 4.8 --- delphi-backend/Source/PM.Bridge.pas | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/delphi-backend/Source/PM.Bridge.pas b/delphi-backend/Source/PM.Bridge.pas index 21b7cc7..8957cd4 100644 --- a/delphi-backend/Source/PM.Bridge.pas +++ b/delphi-backend/Source/PM.Bridge.pas @@ -693,7 +693,8 @@ end; procedure TPMBridge.RestoreFromTray; var LFormHwnd, LAppHwnd: HWND; - LWasTrayHidden: Boolean; + LWasTrayHidden, LRestoreMax: Boolean; + LPlace: TWindowPlacement; begin // Tray icon stays in the tray — we only show the window again. LFormHwnd := MainFormHWND(FMainForm); @@ -713,6 +714,19 @@ begin // MinimizeToTray) vs merely taskbar-minimised (Visible but iconic). LWasTrayHidden := not FMainForm.Visible; + // Windows remembers "this minimised window was maximised" in the placement + // flags, but FMainForm.Show below re-applies FMX's own WindowState (normal) + // and loses it — hence a maximised window coming back normal after Win+D / + // Show desktop. Read the flag BEFORE showing so we can re-apply it. + LRestoreMax := False; + if not LWasTrayHidden then + begin + FillChar(LPlace, SizeOf(LPlace), 0); + LPlace.length := SizeOf(LPlace); + LRestoreMax := GetWindowPlacement(LFormHwnd, @LPlace) and + ((LPlace.flags and WPF_RESTORETOMAXIMIZED) <> 0); + end; + // Reverse order: show the app proxy first so the taskbar entry comes back, // then show and foreground the form. if LAppHwnd <> 0 then @@ -747,6 +761,11 @@ begin end; SetWindowPlacement(LFormHwnd, @FSavedPlacement); end + else if LRestoreMax then + // Was maximised before Windows minimised it (Win+D, taskbar, Show + // desktop): come back maximised. SW_RESTORE alone would land on the + // pre-maximise "normal" geometry. + ShowWindow(LFormHwnd, SW_SHOWMAXIMIZED) else begin ShowWindow(LFormHwnd, SW_SHOW);