diff --git a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs index 0f68f5d258..7a9d3975e3 100644 --- a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs +++ b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs @@ -45,6 +45,7 @@ Copyright © 2019 Nikita Tsukanov */ using System; +using Avalonia.Input; using Avalonia.VisualTree; namespace Avalonia.Controls.Primitives.PopupPositioning @@ -446,13 +447,16 @@ namespace Avalonia.Controls.Primitives.PopupPositioning PopupAnchor anchor, PopupGravity gravity, PopupPositionerConstraintAdjustment constraintAdjustment, Rect? rect) { - // We need a better way for tracking the last pointer position - var pointer = topLevel.PointToClient(topLevel.PlatformImpl.MouseDevice.Position); - + positionerParameters.Offset = offset; positionerParameters.ConstraintAdjustment = constraintAdjustment; if (placement == PlacementMode.Pointer) { + // We need a better way for tracking the last pointer position + var pointer = topLevel.PointToClient( + (topLevel as ILastPointerPosition)?.LastPointerPosition ?? + topLevel.PlatformImpl.MouseDevice.Position); + positionerParameters.AnchorRectangle = new Rect(pointer, new Size(1, 1)); positionerParameters.Anchor = PopupAnchor.TopLeft; positionerParameters.Gravity = PopupGravity.BottomRight; diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index e30740e4e0..06d6340dbc 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/src/Avalonia.Controls/TopLevel.cs @@ -36,7 +36,8 @@ namespace Avalonia.Controls IStyleHost, ILogicalRoot, ITextInputMethodRoot, - IWeakEventSubscriber + IWeakEventSubscriber, + ILastPointerPosition { /// /// Defines the property. @@ -92,6 +93,7 @@ namespace Avalonia.Controls private WindowTransparencyLevel _actualTransparencyLevel; private ILayoutManager _layoutManager; private Border _transparencyFallbackBorder; + private PixelPoint? _lastPointerPosition; /// /// Initializes static members of the class. @@ -315,6 +317,8 @@ namespace Avalonia.Controls IRenderTarget IRenderRoot.CreateRenderTarget() => CreateRenderTarget(); + PixelPoint? ILastPointerPosition.LastPointerPosition => _lastPointerPosition; + /// protected virtual IRenderTarget CreateRenderTarget() { @@ -340,7 +344,9 @@ namespace Avalonia.Controls { return PlatformImpl?.PointToScreen(p) ?? default; } - + + void ILastPointerPosition.SetLastPointerPosition(PixelPoint point) => _lastPointerPosition = point; + /// /// Creates the layout manager for this . /// diff --git a/src/Avalonia.Input/ILastPointerPosition.cs b/src/Avalonia.Input/ILastPointerPosition.cs new file mode 100644 index 0000000000..99c4c72118 --- /dev/null +++ b/src/Avalonia.Input/ILastPointerPosition.cs @@ -0,0 +1,8 @@ +namespace Avalonia.Input +{ + public interface ILastPointerPosition + { + PixelPoint? LastPointerPosition { get; } + void SetLastPointerPosition(PixelPoint point); + } +} diff --git a/src/Avalonia.Input/MouseDevice.cs b/src/Avalonia.Input/MouseDevice.cs index 43e3d870b1..59a3518669 100644 --- a/src/Avalonia.Input/MouseDevice.cs +++ b/src/Avalonia.Input/MouseDevice.cs @@ -150,6 +150,8 @@ namespace Avalonia.Input if (e.Type == RawPointerEventType.NonClientLeftButtonDown) return; _position = e.Root.PointToScreen(e.Position); + (e.Root as ILastPointerPosition)?.SetLastPointerPosition(_position.Value); + var props = CreateProperties(e); var keyModifiers = KeyModifiersUtils.ConvertToKey(e.InputModifiers); switch (e.Type) diff --git a/src/Avalonia.Input/TouchDevice.cs b/src/Avalonia.Input/TouchDevice.cs index f4b7b871cb..1a121875cb 100644 --- a/src/Avalonia.Input/TouchDevice.cs +++ b/src/Avalonia.Input/TouchDevice.cs @@ -110,7 +110,7 @@ namespace Avalonia.Input GetKeyModifiers(args.InputModifiers), args.IntermediatePoints)); } - + (ev.Root as ILastPointerPosition)?.SetLastPointerPosition(ev.Root.PointToScreen(args.Position)); } public void Dispose()