diff --git a/delphi-backend/Source/PM.Bridge.pas b/delphi-backend/Source/PM.Bridge.pas index 8957cd4..bf7607d 100644 --- a/delphi-backend/Source/PM.Bridge.pas +++ b/delphi-backend/Source/PM.Bridge.pas @@ -140,8 +140,11 @@ type procedure PrepareNid; procedure ShowTrayMenu; procedure ShowFirstTimeBalloon; - function FindFMXAppWindow: HWND; public + // The FMX taskbar proxy (TFMAppClass) — a SEPARATE top-level window from + // the form, and the one that owns the taskbar entry. Public so the host + // can hide it during a --tray launch, before MinimizeToTray gets to run. + function FindFMXAppWindow: HWND; // Tray balloon (caller applies its own gating setting). Used for // messages the user must see while the window is hidden — e.g. an // autofill blocked by an elevated target. diff --git a/delphi-backend/UMainForm.pas b/delphi-backend/UMainForm.pas index 2929977..7078051 100644 --- a/delphi-backend/UMainForm.pas +++ b/delphi-backend/UMainForm.pas @@ -220,6 +220,7 @@ begin begin Visible := False; OnActivate := TrayStartupHideOnce; + LogLine('[tray] FormCreate begin at ' + FormatDateTime('hh:nn:ss.zzz', Now)); end; // The .fmx ships WindowState = wsMaximized, so that is the starting intent. @@ -325,11 +326,13 @@ begin // it's noise when Windows itself put us in the tray (the user // didn't actively minimise). Manual launches still see it once. FBridge.BalloonShown := True; + LogLine('[tray] FormCreate end at ' + FormatDateTime('hh:nn:ss.zzz', Now)); TThread.ForceQueue(nil, procedure begin FBridge.MinimizeToTray; - LogLine('Launched with --tray, minimised at startup (balloon suppressed)'); + LogLine('[tray] deferred MinimizeToTray ran at ' + + FormatDateTime('hh:nn:ss.zzz', Now)); end); end; end; @@ -1600,13 +1603,22 @@ end; procedure TMainForm.TrayStartupHideOnce(Sender: TObject); var - LHwnd: HWND; + LHwnd, LAppHwnd: HWND; begin OnActivate := nil; // one shot — never fight the user afterwards Visible := False; LHwnd := WindowHandleToPlatform(Self.Handle).Wnd; if LHwnd <> 0 then ShowWindow(LHwnd, SW_HIDE); + // The taskbar entry belongs to the FMX proxy window, not the form — hiding + // the form alone leaves the button on the taskbar. + if Assigned(FBridge) then + begin + LAppHwnd := FBridge.FindFMXAppWindow; + if LAppHwnd <> 0 then ShowWindow(LAppHwnd, SW_HIDE); + end; + LogLine('[tray] activate-hide fired at ' + + FormatDateTime('hh:nn:ss.zzz', Now)); end; // Single entry point for every tray restore. ExecuteAutofill really minimises