Skip to content

Commit aadcd01

Browse files
authored
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>
1 parent 4312daf commit aadcd01

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

src/Avalonia.Base/Input/Pointer.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,12 @@ public void Capture(IInputElement? control)
4646

4747
private void Capture(IInputElement? control, bool platformInitiated)
4848
{
49-
if (Captured is Visual v1)
50-
v1.DetachedFromVisualTree -= OnCaptureDetached;
5149
var oldCapture = Captured;
50+
if (oldCapture == control)
51+
return;
52+
53+
if (oldCapture is Visual v1)
54+
v1.DetachedFromVisualTree -= OnCaptureDetached;
5255
Captured = control;
5356

5457
if (!platformInitiated)

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,22 @@ public void On_Capture_Transfer_PointerCaptureLost_Should_Propagate_Up_To_The_Co
3636
pointer.Capture(null);
3737
Assert.True(receivers.SequenceEqual(new object[] { newCapture, newParent, el, root }));
3838
}
39+
40+
[Fact]
41+
public void Capture_Captured_ShouldNot_Call_Platform()
42+
{
43+
var pointer = new TestPointer(Pointer.GetNextFreeId(), PointerType.Mouse, true);
44+
45+
Border capture = new Border();
46+
pointer.Capture(capture);
47+
pointer.Capture(capture);
48+
49+
Assert.Equal(1, pointer.PlatformCaptureCalled);
50+
51+
pointer.Capture(null);
52+
pointer.Capture(null);
53+
54+
Assert.Equal(2, pointer.PlatformCaptureCalled);
55+
}
3956
}
4057
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ namespace Avalonia.Base.UnitTests.Input;
1616

1717
public abstract class PointerTestsBase : ScopedTestBase
1818
{
19+
protected class TestPointer : Pointer
20+
{
21+
internal int PlatformCaptureCalled = 0;
22+
23+
internal TestPointer(int id, PointerType type, bool isPrimary) : base(id, type, isPrimary) { }
24+
25+
protected override void PlatformCapture(IInputElement? element)
26+
{
27+
PlatformCaptureCalled++;
28+
}
29+
}
30+
1931
private protected static void SetHit(Mock<IHitTester> renderer, Control? hit)
2032
{
2133
renderer.Setup(x => x.HitTest(It.IsAny<Point>(), It.IsAny<Visual>(), It.IsAny<Func<Visual, bool>>()))

0 commit comments

Comments
 (0)