diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/ExperimentalAcrylicNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/ExperimentalAcrylicNode.cs index 8bd079d070..2dae96f144 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/ExperimentalAcrylicNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/ExperimentalAcrylicNode.cs @@ -83,7 +83,7 @@ namespace Avalonia.Rendering.SceneGraph if (Material != null) { var rect = Rect.Rect; - return rect.Contains(p); + return rect.ContainsExclusive(p); } } diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs index a6dba1bd32..54eb5372c3 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs @@ -76,6 +76,6 @@ namespace Avalonia.Rendering.SceneGraph } /// - public override bool HitTest(Point p) => Bounds.Contains(p); + public override bool HitTest(Point p) => Bounds.ContainsExclusive(p); } } diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs index d3da19d8c9..a17dde656f 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs @@ -109,7 +109,7 @@ namespace Avalonia.Rendering.SceneGraph } /// - public override bool HitTest(Point p) => Bounds.Contains(p); + public override bool HitTest(Point p) => Bounds.ContainsExclusive(p); public override void Dispose() { diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs index 285fbce605..f1f4e82ea2 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs @@ -106,13 +106,13 @@ namespace Avalonia.Rendering.SceneGraph if (Brush != null) { var rect = Rect.Rect.Inflate((Pen?.Thickness / 2) ?? 0); - return rect.Contains(p); + return rect.ContainsExclusive(p); } else { var borderRect = Rect.Rect.Inflate((Pen?.Thickness / 2) ?? 0); var emptyRect = Rect.Rect.Deflate((Pen?.Thickness / 2) ?? 0); - return borderRect.Contains(p) && !emptyRect.Contains(p); + return borderRect.ContainsExclusive(p) && !emptyRect.ContainsExclusive(p); } } diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs index d8e5baac97..24800a7591 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs @@ -301,7 +301,7 @@ namespace Avalonia.Rendering.SceneGraph if (node.ClipToBounds) { clip = clip == null ? node.ClipBounds : clip.Value.Intersect(node.ClipBounds); - clipped = !clip.Value.Contains(_point); + clipped = !clip.Value.ContainsExclusive(_point); } if (node.GeometryClip != null) diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs index d24d183709..9b0e32e5fa 100644 --- a/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs +++ b/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs @@ -538,6 +538,38 @@ namespace Avalonia.Visuals.UnitTests.Rendering } } + [Fact] + public void HitTest_Should_Not_Hit_Controls_Next_Pixel() + { + using (TestApplication()) + { + Border targetRectangle; + + var root = new TestRoot + { + Width = 50, + Height = 200, + Child = new StackPanel + { + Orientation = Orientation.Vertical, + HorizontalAlignment = HorizontalAlignment.Left, + Children = + { + new Border { Width = 50, Height = 50, Background = Brushes.Red}, + { targetRectangle = new Border { Width = 50, Height = 50, Background = Brushes.Green} } + } + } + }; + + root.Renderer = new DeferredRenderer(root, null); + root.Measure(Size.Infinity); + root.Arrange(new Rect(root.DesiredSize)); + + var result = root.Renderer.HitTest(new Point(25, 50), root, null); + Assert.Equal(new[] { targetRectangle }, result); + } + } + private IDisposable TestApplication() { return UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);