Browse Source

Do not recapture already captured element (#19740)

* Do not recapture already captured element

* Recapture tests

---------

Co-authored-by: Jan Kučera <miloush@users.noreply.github.com>
release/11.3.7
Jan Kučera 4 months ago
committed by Julien Lebosquain
parent
commit
f0818c5d2d
  1. 7
      src/Avalonia.Base/Input/Pointer.cs
  2. 17
      tests/Avalonia.Base.UnitTests/Input/PointerTests.cs
  3. 12
      tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs

7
src/Avalonia.Base/Input/Pointer.cs

@ -46,9 +46,12 @@ namespace Avalonia.Input
private void Capture(IInputElement? control, bool platformInitiated) private void Capture(IInputElement? control, bool platformInitiated)
{ {
if (Captured is Visual v1)
v1.DetachedFromVisualTree -= OnCaptureDetached;
var oldCapture = Captured; var oldCapture = Captured;
if (oldCapture == control)
return;
if (oldCapture is Visual v1)
v1.DetachedFromVisualTree -= OnCaptureDetached;
Captured = control; Captured = control;
if (!platformInitiated) if (!platformInitiated)

17
tests/Avalonia.Base.UnitTests/Input/PointerTests.cs

@ -36,5 +36,22 @@ namespace Avalonia.Base.UnitTests.Input
pointer.Capture(null); pointer.Capture(null);
Assert.True(receivers.SequenceEqual(new object[] { newCapture, newParent, el, root })); Assert.True(receivers.SequenceEqual(new object[] { newCapture, newParent, el, root }));
} }
[Fact]
public void Capture_Captured_ShouldNot_Call_Platform()
{
var pointer = new TestPointer(Pointer.GetNextFreeId(), PointerType.Mouse, true);
Border capture = new Border();
pointer.Capture(capture);
pointer.Capture(capture);
Assert.Equal(1, pointer.PlatformCaptureCalled);
pointer.Capture(null);
pointer.Capture(null);
Assert.Equal(2, pointer.PlatformCaptureCalled);
}
} }
} }

12
tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs

@ -16,6 +16,18 @@ namespace Avalonia.Base.UnitTests.Input;
public abstract class PointerTestsBase : ScopedTestBase public abstract class PointerTestsBase : ScopedTestBase
{ {
protected class TestPointer : Pointer
{
internal int PlatformCaptureCalled = 0;
internal TestPointer(int id, PointerType type, bool isPrimary) : base(id, type, isPrimary) { }
protected override void PlatformCapture(IInputElement? element)
{
PlatformCaptureCalled++;
}
}
private protected static void SetHit(Mock<IHitTester> renderer, Control? hit) private protected static void SetHit(Mock<IHitTester> renderer, Control? hit)
{ {
renderer.Setup(x => x.HitTest(It.IsAny<Point>(), It.IsAny<Visual>(), It.IsAny<Func<Visual, bool>>())) renderer.Setup(x => x.HitTest(It.IsAny<Point>(), It.IsAny<Visual>(), It.IsAny<Func<Visual, bool>>()))

Loading…
Cancel
Save