From c44dd17d478ee4da79f276feaf52d730b2073fab Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Tue, 3 Nov 2015 17:18:11 -0800 Subject: [PATCH] Always reset parentData when dropping children Previously, we'd leave the old values in the parent data if the types matches, but not all render objects would reset these values during layout. For example, RenderProxyBox doesn't set the position field because it doesn't read the position field. However, leaving the old data there violates the invariants of the box protocol and can cause trouble (e.g., localToGlobal giving the wrong result). Fixes #1939 --- .../flutter/lib/src/rendering/object.dart | 1 + packages/unit/test/rendering/box_test.dart | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index abec953c3c..efd9e75578 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -464,6 +464,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { assert(child.parentData != null); child._cleanRelayoutSubtreeRoot(); child.parentData.detach(); + child.parentData = null; super.dropChild(child); markNeedsLayout(); _markNeedsCompositingBitsUpdate(); diff --git a/packages/unit/test/rendering/box_test.dart b/packages/unit/test/rendering/box_test.dart index 680ede0236..cac8d1d664 100644 --- a/packages/unit/test/rendering/box_test.dart +++ b/packages/unit/test/rendering/box_test.dart @@ -73,4 +73,25 @@ void main() { expect(coloredBox.size.width, equals(780.0)); expect(coloredBox.size.height, equals(580.0)); }); + + test("reparenting should clear position", () { + RenderDecoratedBox coloredBox = new RenderDecoratedBox( + decoration: new BoxDecoration()); + RenderPadding paddedBox = new RenderPadding( + child: coloredBox, padding: const EdgeDims.all(10.0)); + + layout(paddedBox); + + BoxParentData parentData = coloredBox.parentData; + expect(parentData.position.x, isNot(equals(0.0))); + + paddedBox.child = null; + RenderConstrainedBox constraintedBox = new RenderConstrainedBox( + child: coloredBox, additionalConstraints: const BoxConstraints()); + + layout(constraintedBox); + + parentData = coloredBox.parentData; + expect(parentData.position.x, equals(0.0)); + }); }