Do not assert when semantics are on and app draws on 0x0 surface (#19059)

Instead, if the surface is 0x0 semantics will just generate one root semantics node with size of 0x0. The node will have no children because all children are invisible and (except for the root node with this change) invisible children are dropped.
This commit is contained in:
Michael Goderbauer 2018-07-11 09:46:24 -07:00 committed by GitHub
parent 2c070363c2
commit 36e16e7544
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 2 deletions

View File

@ -3196,7 +3196,12 @@ class _RootSemanticsFragment extends _InterestingSemanticsFragment {
}
node.updateWith(config: null, childrenInInversePaintOrder: children);
assert(!node.isInvisible);
// The root node is the only semantics node allowed to be invisible. This
// can happen when the canvas the app is drawn on has a size of 0 by 0
// pixel. If this happens, the root node must not have any children (because
// these would be invisible as well and are therefore excluded from the
// tree).
assert(!node.isInvisible || children.isEmpty);
yield node;
}

View File

@ -0,0 +1,47 @@
// 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/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'semantics_tester.dart';
void main() {
testWidgets('has only root node if surface size is 0x0', (WidgetTester tester) async {
final SemanticsTester semantics = new SemanticsTester(tester);
await tester.pumpWidget(new Semantics(
selected: true,
));
expect(semantics, hasSemantics(
new TestSemantics(
id: 0,
rect: new Rect.fromLTRB(0.0, 0.0, 2400.0, 1800.0),
children: <TestSemantics>[
new TestSemantics(
id: 1,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 600.0),
flags: <SemanticsFlag>[SemanticsFlag.isSelected],
),
],
), ignoreTransform: true,
));
await tester.binding.setSurfaceSize(const Size(0.0, 0.0));
await tester.pumpAndSettle();
expect(semantics, hasSemantics(
new TestSemantics(
id: 0,
rect: new Rect.fromLTRB(0.0, 0.0, 0.0, 0.0),
), ignoreTransform: true,
));
await tester.binding.setSurfaceSize(null);
semantics.dispose();
});
}

View File

@ -235,6 +235,33 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
});
}
Size _surfaceSize;
/// Artificially changes the surface size to `size` on the Widget binding,
/// then flushes microtasks.
///
/// Set to null to use the default surface size.
Future<Null> setSurfaceSize(Size size) {
return TestAsyncUtils.guard(() async {
assert(inTest);
if (_surfaceSize == size)
return null;
_surfaceSize = size;
handleMetricsChanged();
return null;
});
}
@override
ViewConfiguration createViewConfiguration() {
final double devicePixelRatio = ui.window.devicePixelRatio;
final Size size = _surfaceSize ?? ui.window.physicalSize / devicePixelRatio;
return new ViewConfiguration(
size: size,
devicePixelRatio: devicePixelRatio,
);
}
/// Acts as if the application went idle.
///
/// Runs all remaining microtasks, including those scheduled as a result of
@ -1250,7 +1277,7 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
@override
ViewConfiguration createViewConfiguration() {
return new TestViewConfiguration();
return new TestViewConfiguration(size: _surfaceSize ?? _kDefaultTestViewportSize);
}
@override