disable hit testing if the CompositedTransformFollower is hidden when… (#54981)
* disable hit testing if the CompositedTransformFollower is hidden when there is no leader layer
* update comment
diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart
index 25f8c83..676bfbf 100644
--- a/packages/flutter/lib/src/rendering/proxy_box.dart
+++ b/packages/flutter/lib/src/rendering/proxy_box.dart
@@ -4914,7 +4914,7 @@
///
/// When the render object is not linked, then: if [showWhenUnlinked] is true,
/// the child is visible and not repositioned; if it is false, then child is
- /// hidden.
+ /// hidden, and its hit testing is also disabled.
bool get showWhenUnlinked => _showWhenUnlinked;
bool _showWhenUnlinked;
set showWhenUnlinked(bool value) {
@@ -4962,6 +4962,9 @@
@override
bool hitTest(BoxHitTestResult result, { Offset position }) {
+ // Disables the hit testing if this render object is hidden.
+ if (link.leader == null && !showWhenUnlinked)
+ return false;
// RenderFollowerLayer objects don't check if they are
// themselves hit, because it's confusing to think about
// how the untransformed size and the child's transformed
diff --git a/packages/flutter/test/rendering/proxy_box_test.dart b/packages/flutter/test/rendering/proxy_box_test.dart
index 60dbb5f..6a49841 100644
--- a/packages/flutter/test/rendering/proxy_box_test.dart
+++ b/packages/flutter/test/rendering/proxy_box_test.dart
@@ -493,6 +493,61 @@
box.translation = const Offset(0.3, 0.3);
expect(box.markNeedsSemanticsUpdateCallCount, 3);
});
+
+ test('RenderFollowerLayer hit test without a leader layer and the showWhenUnlinked is true', () {
+ final RenderFollowerLayer follower = RenderFollowerLayer(
+ link: LayerLink(),
+ showWhenUnlinked: true,
+ child: RenderSizedBox(const Size(1.0, 1.0)),
+ );
+ layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
+ final BoxHitTestResult hitTestResult = BoxHitTestResult();
+ expect(follower.hitTest(hitTestResult, position: const Offset(0.0, 0.0)), isTrue);
+ });
+
+ test('RenderFollowerLayer hit test without a leader layer and the showWhenUnlinked is false', () {
+ final RenderFollowerLayer follower = RenderFollowerLayer(
+ link: LayerLink(),
+ showWhenUnlinked: false,
+ child: RenderSizedBox(const Size(1.0, 1.0)),
+ );
+ layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
+ final BoxHitTestResult hitTestResult = BoxHitTestResult();
+ expect(follower.hitTest(hitTestResult, position: const Offset(0.0, 0.0)), isFalse);
+ });
+
+ test('RenderFollowerLayer hit test with a leader layer and the showWhenUnlinked is true', () {
+ // Creates a layer link with a leader.
+ final LayerLink link = LayerLink();
+ final LeaderLayer leader = LeaderLayer(link: link);
+ leader.attach(Object());
+
+ final RenderFollowerLayer follower = RenderFollowerLayer(
+ link: link,
+ showWhenUnlinked: true,
+ child: RenderSizedBox(const Size(1.0, 1.0)),
+ );
+ layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
+ final BoxHitTestResult hitTestResult = BoxHitTestResult();
+ expect(follower.hitTest(hitTestResult, position: const Offset(0.0, 0.0)), isTrue);
+ });
+
+ test('RenderFollowerLayer hit test with a leader layer and the showWhenUnlinked is false', () {
+ // Creates a layer link with a leader.
+ final LayerLink link = LayerLink();
+ final LeaderLayer leader = LeaderLayer(link: link);
+ leader.attach(Object());
+
+ final RenderFollowerLayer follower = RenderFollowerLayer(
+ link: link,
+ showWhenUnlinked: false,
+ child: RenderSizedBox(const Size(1.0, 1.0)),
+ );
+ layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
+ final BoxHitTestResult hitTestResult = BoxHitTestResult();
+ // The follower is still hit testable because there is a leader layer.
+ expect(follower.hitTest(hitTestResult, position: const Offset(0.0, 0.0)), isTrue);
+ });
}
class _TestRectClipper extends CustomClipper<Rect> {