diff --git a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
index 9742a6b3ba..e47c8e7e31 100644
--- a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
+++ b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
@@ -87,7 +87,16 @@ public class CompositingRenderer : IRendererWithCompositor
///
public IEnumerable HitTest(Point p, IVisual root, Func? filter)
{
- var res = CompositionTarget.TryHitTest(p, filter);
+ Func? f = null;
+ if (filter != null)
+ f = v =>
+ {
+ if (v is CompositionDrawListVisual dlv)
+ return filter(dlv.Visual);
+ return true;
+ };
+
+ var res = CompositionTarget.TryHitTest(p, f);
if(res == null)
yield break;
foreach(var v in res)
diff --git a/src/Avalonia.Base/Rendering/Composition/CompositionDrawListVisual.cs b/src/Avalonia.Base/Rendering/Composition/CompositionDrawListVisual.cs
index 77b392eee5..b019d1792b 100644
--- a/src/Avalonia.Base/Rendering/Composition/CompositionDrawListVisual.cs
+++ b/src/Avalonia.Base/Rendering/Composition/CompositionDrawListVisual.cs
@@ -54,13 +54,11 @@ internal class CompositionDrawListVisual : CompositionContainerVisual
Visual = visual;
}
- internal override bool HitTest(Point pt, Func? filter)
+ internal override bool HitTest(Point pt)
{
var custom = Visual as ICustomHitTest;
if (DrawList == null && custom == null)
return false;
- if (filter != null && !filter(Visual))
- return false;
if (custom != null)
{
// Simulate the old behavior
diff --git a/src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs b/src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs
index 4e53e163ec..eb499604e0 100644
--- a/src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs
+++ b/src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs
@@ -31,7 +31,7 @@ namespace Avalonia.Rendering.Composition
///
///
///
- public PooledList? TryHitTest(Point point, Func? filter)
+ public PooledList? TryHitTest(Point point, Func? filter)
{
Server.Readback.NextRead();
if (Root == null)
@@ -88,10 +88,14 @@ namespace Avalonia.Rendering.Composition
}
void HitTestCore(CompositionVisual visual, Point globalPoint, PooledList result,
- Func? filter)
+ Func? filter)
{
if (visual.Visible == false)
return;
+
+ if (filter != null && !filter(visual))
+ return;
+
if (!TryTransformTo(visual, globalPoint, out var point))
return;
@@ -111,7 +115,7 @@ namespace Avalonia.Rendering.Composition
}
// Hit-test the current node
- if (visual.HitTest(point, filter))
+ if (visual.HitTest(point))
result.Add(visual);
}
diff --git a/src/Avalonia.Base/Rendering/Composition/Visual.cs b/src/Avalonia.Base/Rendering/Composition/Visual.cs
index 7356b7b9e8..6d6818256a 100644
--- a/src/Avalonia.Base/Rendering/Composition/Visual.cs
+++ b/src/Avalonia.Base/Rendering/Composition/Visual.cs
@@ -53,6 +53,6 @@ namespace Avalonia.Rendering.Composition
internal object? Tag { get; set; }
- internal virtual bool HitTest(Point point, Func? filter) => true;
+ internal virtual bool HitTest(Point point) => true;
}
}
diff --git a/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs
index 02012bf62b..d83bb12aea 100644
--- a/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs
+++ b/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs
@@ -432,6 +432,33 @@ public class CompositorHitTestingTests : CompositorTestsBase
s.AssertHitTest(new Point(5, 10), null, targetRectangle);
}
}
+
+
+ [Fact]
+ public void HitTest_Filter_Should_Filter_Out_Children()
+ {
+ using (var s = new CompositorServices(new Size(200, 200)))
+ {
+ Border child, parent;
+ s.TopLevel.Content = parent = new Border
+ {
+ Width = 100,
+ Height = 100,
+ Background = Brushes.Red,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center,
+ Child = child = new Border
+ {
+ Background = Brushes.Red,
+ HorizontalAlignment = HorizontalAlignment.Stretch,
+ VerticalAlignment = VerticalAlignment.Stretch,
+ }
+ };
+
+ s.AssertHitTest(new Point(100, 100), null, child, parent);
+ s.AssertHitTest(new Point(100, 100), v => v != parent);
+ }
+ }
private IDisposable TestApplication()
{