@ -17,6 +17,7 @@ namespace Avalonia.Controls
private long _l astTipCloseTime ;
private DispatcherTimer ? _ timer ;
private ulong _l astTipEventTime ;
private ulong _l astWindowEventTime ;
public ToolTipService ( IInputManager inputManager )
{
@ -36,18 +37,23 @@ namespace Avalonia.Controls
{
if ( e is RawPointerEventArgs pointerEvent )
{
bool isTooltipEvent = false ;
if ( _ tipControl ? . GetValue ( ToolTip . ToolTipProperty ) is { } currentTip & & e . Root = = currentTip . PopupHost )
{
isTooltipEvent = true ;
_l astTipEventTime = pointerEvent . Timestamp ;
var simultaneousTipEvent = _l astTipEventTime = = pointerEvent . Timestamp ;
}
else if ( e . Root = = _ tipControl ? . VisualRoot )
{
_l astWindowEventTime = pointerEvent . Timestamp ;
}
switch ( pointerEvent . Type )
{
// sometimes there is a null hit test as soon as the pointer enters a tooltip
case RawPointerEventType . Move when ! ( simultaneousTipEvent & & pointerEvent . InputHitTestResult . element = = null ) :
Update ( pointerEvent . InputHitTestResult . element as Visual ) ;
case RawPointerEventType . Move :
Update ( pointerEvent . Root , pointerEvent . InputHitTestResult . element as Visual ) ;
break ;
case RawPointerEventType . LeaveWindow when e . Root = = _ tipControl ? . VisualRoot & & ! simultaneousTipEvent :
case RawPointerEventType . LeaveWindow when ( e . Root = = _ tipControl ? . VisualRoot & & _l astTipEventTime ! = e . Timestamp ) | | ( isTooltipEvent & & _l astWindowEventTime ! = e . Timestamp ) :
ClearTip ( ) ;
_ tipControl = null ;
break ;
@ -68,10 +74,16 @@ namespace Avalonia.Controls
}
}
public void Update ( Visual ? candidateToolTipHost )
public void Update ( IInputRoot root , Visual ? candidateToolTipHost )
{
var currentToolTip = _ tipControl ? . GetValue ( ToolTip . ToolTipProperty ) ;
if ( root = = currentToolTip ? . VisualRoot )
{
// Don't update while the pointer is over a tooltip
return ;
}
while ( candidateToolTipHost ! = null )
{
if ( candidateToolTipHost = = currentToolTip ) // when OverlayPopupHost is in use, the tooltip is in the same window as the host control
@ -193,7 +205,11 @@ namespace Avalonia.Controls
private void StartShowTimer ( int showDelay , Control control )
{
_ timer = new DispatcherTimer { Interval = TimeSpan . FromMilliseconds ( showDelay ) , Tag = ( this , control ) } ;
_ timer . Tick + = ( o , e ) = > Open ( control ) ;
_ timer . Tick + = ( o , e ) = >
{
if ( _ timer ! = null )
Open ( control ) ;
} ;
_ timer . Start ( ) ;
}