浏览代码

Merge pull request #3161 from AvaloniaUI/pointer-capture-transfer-fix

Properly raise PointerCaptureLost on capture transfer
Steven Kirk 6 年之前
父节点
当前提交
45d4d6870f

+ 1 - 1
src/Avalonia.Input/Pointer.cs

@@ -37,7 +37,7 @@ namespace Avalonia.Input
         {
         {
             if (Captured != null)
             if (Captured != null)
                 Captured.DetachedFromVisualTree -= OnCaptureDetached;
                 Captured.DetachedFromVisualTree -= OnCaptureDetached;
-            var oldCapture = control;
+            var oldCapture = Captured;
             Captured = control;
             Captured = control;
             PlatformCapture(control);
             PlatformCapture(control);
             if (oldCapture != null)
             if (oldCapture != null)

+ 39 - 0
tests/Avalonia.Input.UnitTests/PointerTests.cs

@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+using System.Linq;
+using Avalonia.Controls;
+using Avalonia.UnitTests;
+using Avalonia.VisualTree;
+using Xunit;
+
+namespace Avalonia.Input.UnitTests
+{
+    public class PointerTests
+    {
+        [Fact]
+        public void On_Capture_Transfer_PointerCaptureLost_Should_Propagate_Up_To_The_Common_Parent()
+        {
+            Border initialParent, initialCapture, newParent, newCapture;
+            var el = new StackPanel
+            {
+                Children =
+                {
+                    (initialParent = new Border { Child = initialCapture = new Border() }),
+                    (newParent = new Border { Child = newCapture = new Border() })
+                }
+            };
+            var receivers = new List<object>();
+            var root = new TestRoot(el);
+            foreach (InputElement d in root.GetSelfAndVisualDescendants())
+                d.PointerCaptureLost += (s, e) => receivers.Add(s);
+            var pointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true);
+            
+            pointer.Capture(initialCapture);
+            pointer.Capture(newCapture);
+            Assert.True(receivers.SequenceEqual(new[] { initialCapture, initialParent }));
+            
+            receivers.Clear();
+            pointer.Capture(null);
+            Assert.True(receivers.SequenceEqual(new object[] { newCapture, newParent, el, root }));
+        }
+    }
+}

+ 1 - 1
tests/Avalonia.UnitTests/MouseTestHelper.cs

@@ -84,9 +84,9 @@ namespace Avalonia.UnitTests
             );
             );
             if (ButtonCount(props) == 0)
             if (ButtonCount(props) == 0)
             {
             {
-                _pointer.Capture(null);
                 target.RaiseEvent(new PointerReleasedEventArgs(source, _pointer, (IVisual)target, position,
                 target.RaiseEvent(new PointerReleasedEventArgs(source, _pointer, (IVisual)target, position,
                     Timestamp(), props, GetModifiers(modifiers), _pressedButton));
                     Timestamp(), props, GetModifiers(modifiers), _pressedButton));
+                _pointer.Capture(null);
             }
             }
             else
             else
                 Move(target, source, position);
                 Move(target, source, position);