Unverified Commit 96fbbdc3 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Fix "node._relayoutBoundary == _relayoutBoundary" crash (#44490)

parent eae05c7d
...@@ -1429,7 +1429,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -1429,7 +1429,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
static bool debugCheckingIntrinsics = false; static bool debugCheckingIntrinsics = false;
bool _debugSubtreeRelayoutRootAlreadyMarkedNeedsLayout() { bool _debugSubtreeRelayoutRootAlreadyMarkedNeedsLayout() {
if (_relayoutBoundary == null) if (_relayoutBoundary == null)
return true; // we haven't yet done layout even once, so there's nothing for us to do return true; // we don't know where our relayout boundary is yet
RenderObject node = this; RenderObject node = this;
while (node != _relayoutBoundary) { while (node != _relayoutBoundary) {
assert(node._relayoutBoundary == _relayoutBoundary); assert(node._relayoutBoundary == _relayoutBoundary);
...@@ -1677,6 +1677,14 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -1677,6 +1677,14 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
return; return;
} }
_constraints = constraints; _constraints = constraints;
if (_relayoutBoundary != null && relayoutBoundary != _relayoutBoundary) {
// The local relayout boundary has changed, must notify children in case
// they also need updating. Otherwise, they will be confused about what
// their actual relayout boundary is later.
visitChildren((RenderObject child) {
child._cleanRelayoutBoundary();
});
}
_relayoutBoundary = relayoutBoundary; _relayoutBoundary = relayoutBoundary;
assert(!_debugMutationsLocked); assert(!_debugMutationsLocked);
assert(!_doingThisLayoutWithCallback); assert(!_doingThisLayoutWithCallback);
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
void main() {
testWidgets('repaint boundary with constraint changes', (WidgetTester tester) async {
// Regression test for as https://github.com/flutter/flutter/issues/39151.
await tester.pumpWidget(const RelayoutBoundariesCrash());
tester.state<RelayoutBoundariesCrashState>(find.byType(RelayoutBoundariesCrash))._toggleMode();
await tester.pump();
});
}
class RelayoutBoundariesCrash extends StatefulWidget {
const RelayoutBoundariesCrash({Key key}) : super(key: key);
@override
RelayoutBoundariesCrashState createState() => RelayoutBoundariesCrashState();
}
class RelayoutBoundariesCrashState extends State<RelayoutBoundariesCrash> {
bool _mode = true;
void _toggleMode() {
setState(() {
_mode = !_mode;
});
}
@override
Widget build(BuildContext context) {
return Center(
child: SizedBox(
// when _mode is true, constraints are tight, otherwise constraints are loose
width: !_mode ? 100.0 : null,
height: !_mode ? 100.0 : null,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
// Make the outer SizedBoxes relayout without making the Placeholders relayout.
final double dimension = !_mode ? 10.0 : 20.0;
return Column(
children: <Widget>[
SizedBox(
width: dimension,
height: dimension,
child: const Placeholder(),
),
SizedBox(
width: dimension,
height: dimension,
child: const Placeholder(),
),
],
);
},
),
),
);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment