From 1ae1d482f0bc5fbc999f8a7000794232744d1f31 Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Tue, 22 Sep 2026 15:38:05 +0100 Subject: [PATCH] fix(fillbar): remonte la barrette quand elle est recouverte, au lieu de la deplacer Elle a le droit de se poser sur la barre des taches. Redemander HWND_TOPMOST quand on l'est deja ne change rien : le shell restait devant au demarrage de session et au menu Demarrer. Le passage NOTOPMOST -> TOPMOST force la remontee, fait seulement quand le centre de la barrette appartient a une autre fenetre. Co-Authored-By: Claude Opus 5 --- delphi-backend/Source/PM.Bridge.pas | 62 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/delphi-backend/Source/PM.Bridge.pas b/delphi-backend/Source/PM.Bridge.pas index 93c4e9c..caf9e80 100644 --- a/delphi-backend/Source/PM.Bridge.pas +++ b/delphi-backend/Source/PM.Bridge.pas @@ -1202,25 +1202,34 @@ begin Result := CallWindowProc(GLazyOldBtnProc, AWnd, AMsg, AWp, ALp); end; -// LA BARRE DES TACHES EST TOPMOST ELLE AUSSI : une barrette posee dessus passe -// derriere elle des que le shell se remet en tete (demarrage de Windows, menu -// Demarrer) et parait disparue. Elle est donc ramenee dans la zone de travail -// de l'ecran ou elle se trouve - au chargement comme a la fin d'un deplacement. -procedure ClampToWorkArea(AWidth, AHeight: Integer; var AX, AY: Integer); +// LA BARRE DES TACHES EST TOPMOST ELLE AUSSI, et la barrette a le droit de se +// poser dessus. Redemander HWND_TOPMOST ne suffit pas quand on l'est deja : +// Windows n'y voit rien a changer et la barrette reste dessous - invisible au +// demarrage de session, puis des qu'on ouvre le menu Demarrer. Le passage par +// NOTOPMOST force la remontee en tete de la bande. Fait seulement quand elle +// est vraiment recouverte (un point de sa surface ne lui appartient plus), +// pour ne pas remuer l'ordre des fenetres cinq fois par seconde. +function LazyIsCovered(AWnd: HWND): Boolean; var LRect: TRect; - LMon: HMONITOR; - LInfo: TMonitorInfo; + LPt: TPoint; + LHit: HWND; begin - LRect := Rect(AX, AY, AX + AWidth, AY + AHeight); - LMon := MonitorFromRect(@LRect, MONITOR_DEFAULTTONEAREST); - if LMon = 0 then Exit; - LInfo.cbSize := SizeOf(LInfo); - if not GetMonitorInfo(LMon, @LInfo) then Exit; - if AX + AWidth > LInfo.rcWork.Right then AX := LInfo.rcWork.Right - AWidth; - if AY + AHeight > LInfo.rcWork.Bottom then AY := LInfo.rcWork.Bottom - AHeight; - if AX < LInfo.rcWork.Left then AX := LInfo.rcWork.Left; - if AY < LInfo.rcWork.Top then AY := LInfo.rcWork.Top; + Result := False; + if not GetWindowRect(AWnd, LRect) then Exit; + LPt.X := (LRect.Left + LRect.Right) div 2; + LPt.Y := (LRect.Top + LRect.Bottom) div 2; + LHit := WindowFromPoint(LPt); + if LHit = 0 then Exit; + Result := (LHit <> AWnd) and (GetAncestor(LHit, GA_ROOT) <> AWnd); +end; + +procedure LazyForceToTop(AWnd: HWND); +begin + SetWindowPos(AWnd, HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE); + SetWindowPos(AWnd, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE); end; procedure TPMBridge.DrawLazyButton(ADraw: PDrawItemStruct); @@ -1394,7 +1403,6 @@ end; procedure TPMBridge.LazyWindowHandler(var AMsg: TMessage); var LRect: TRect; - LX, LY: Integer; LBrush: HBRUSH; LPt: TPoint; LIn: Boolean; @@ -1411,13 +1419,10 @@ begin ApplyLazyAlpha(LIn); end; // TOPMOST N'EST PAS UN RANG, C'EST UNE BANDE. La barre des taches y est - // elle aussi, et cliquer son fond vide la remonte en tete de cette - // bande : une barrette posee dessus passe DERRIERE et semble avoir - // disparu, alors qu'elle est seulement recouverte. La reposer a chaque - // battement est ce que font tous les outils flottants ; sans mouvement - // ni taille a changer, l'appel ne repeint rien. - SetWindowPos(FLazyWnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE); + // elle aussi, et se remet en tete de cette bande au demarrage de la + // session comme a l'ouverture du menu Demarrer : une barrette posee + // dessus passe DERRIERE et semble avoir disparu. + if LazyIsCovered(FLazyWnd) then LazyForceToTop(FLazyWnd); Exit; end; // Fin du glissement (la boucle modale ouverte par HTCAPTION), donc une @@ -1425,13 +1430,7 @@ begin WM_EXITSIZEMOVE: begin GetWindowRect(FLazyWnd, LRect); - LX := LRect.Left; - LY := LRect.Top; - ClampToWorkArea(FLazyW, LAZY_H, LX, LY); - if (LX <> LRect.Left) or (LY <> LRect.Top) then - SetWindowPos(FLazyWnd, HWND_TOPMOST, LX, LY, 0, 0, - SWP_NOSIZE or SWP_NOACTIVATE); - SetPref(LAZY_POS_KEY, Format('%d,%d', [LX, LY])); + SetPref(LAZY_POS_KEY, Format('%d,%d', [LRect.Left, LRect.Top])); Exit; end; // Deux portes pour un seul menu : le fond de la barrette est declare @@ -1686,7 +1685,6 @@ begin LRect := Rect(LPosX, LPosY, LPosX + FLazyW, LPosY + LAZY_H); if MonitorFromRect(@LRect, MONITOR_DEFAULTTONULL) <> 0 then begin - ClampToWorkArea(FLazyW, LAZY_H, LPosX, LPosY); LX := LPosX; LY := LPosY; end;