From 90dbac6a6f73151d93fe02243b337c7e82cbb611 Mon Sep 17 00:00:00 2001 From: Juha Date: Tue, 5 Mar 2024 16:02:03 +0200 Subject: [PATCH] LCL: Improve TApplication.ActivateHint. Issue #40820, patch by Alexander (Rouse_) Bagel. --- lcl/include/application.inc | 50 +++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/lcl/include/application.inc b/lcl/include/application.inc index 7ba94e8442..871bb7b894 100644 --- a/lcl/include/application.inc +++ b/lcl/include/application.inc @@ -177,7 +177,26 @@ end; procedure TApplication.ActivateHint(CursorPos: TPoint; CheckHintControlChange: Boolean); var Info: THintInfoAtMouse; - HintControlChanged: Boolean; + HintControlChanged, MouseLeaveHintRect, WasHintActive: Boolean; + HitControl: TControl; + + procedure StartHintTimerWithCustomPause; + var + Pause: Integer; + begin + Pause := IfThen(WasHintActive, 0, HintPause); + if Assigned(FHintControl) then + FHintControl.Perform(CM_HINTSHOWPAUSE, Ord(WasHintActive), LParam(@Pause)); + if Pause = 0 then + ShowHintWindow(Info) + else + begin + CancelHint; + FHintControl := Info.Control; + StartHintTimer(Pause, ahttShowHint); + end; + end; + begin Info := GetHintInfoAt(CursorPos); @@ -187,6 +206,7 @@ begin HintControlChanged := not CheckHintControlChange or (FHintControl <> Info.Control); if Info.ControlHasHint then begin + MouseLeaveHintRect := Assigned(FHintControl) and not PtInRect(FHintRect, FHintControl.ScreenToClient(CursorPos)); if HintControlChanged then begin StopHintTimer; @@ -194,28 +214,32 @@ begin FHintControl := Info.Control; FHintRect := FHintControl.BoundsRect; end else begin - Exit; + if not MouseLeaveHintRect then + Exit; end; + WasHintActive := Assigned(FHintWindow) and FHintWindow.Visible; case FHintTimerType of ahttNone, ahttHideHint: //react only if the hint control changed or if the mouse leave the previously set hint rect - if HintControlChanged or (not PtInRect(FHintRect, FHintControl.ScreenToClient(Info.MousePos))) then - begin - //if a hint is visible immediately query the app to show a new hint... - if FHintTimerType = ahttHideHint then - ShowHintWindow(Info); - //...if there's no hint window visible at this point then schedule a new query - if (FHintTimerType = ahttNone) or (FHintWindow = nil) or not FHintWindow.Visible then - StartHintTimer(HintPause, ahttShowHint); - end; + if HintControlChanged or MouseLeaveHintRect then + StartHintTimerWithCustomPause; ahttShowHint, ahttReshowHint: - StartHintTimer(HintPause, ahttShowHint); + StartHintTimerWithCustomPause; end; end else - CancelHint; + begin + // THintWindow should not be closed if there is a cursor above it + // Relevant for Linux only + {$IFNDEF MSWINDOWS} + HitControl := FindControlAtPosition(CursorPos, False); + if (HitControl = nil) or not (HitControl is THintWindow) then + {$ENDIF} + CancelHint; + end; end; + procedure TApplication.BringToFront; begin WidgetSet.AppBringToFront;