Commit 141a6355 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Performance improvements for semantics tree compilation (#12682)

* Without checking compatibility

* ++

* ++

* ++

* more docs
parent 3206fb63
...@@ -2251,27 +2251,17 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -2251,27 +2251,17 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
void _updateSemantics() { void _updateSemantics() {
assert(_semanticsConfiguration.isSemanticBoundary || parent is! RenderObject); assert(_semanticsConfiguration.isSemanticBoundary || parent is! RenderObject);
final _SemanticsFragment fragment = _getSemanticsForParent( final _SemanticsFragment fragment = _getSemanticsForParent(
parentClippingRect: _semanticsClippingRect,
mergeIntoParent: _semantics?.parent?.isPartOfNodeMerging ?? false, mergeIntoParent: _semantics?.parent?.isPartOfNodeMerging ?? false,
); );
assert(fragment is _InterestingSemanticsFragment); assert(fragment is _InterestingSemanticsFragment);
final _InterestingSemanticsFragment interestingFragment = fragment; final _InterestingSemanticsFragment interestingFragment = fragment;
final SemanticsNode node = interestingFragment.compileChildren().single; final SemanticsNode node = interestingFragment.compileChildren(_semantics?.parentClipRect).single;
// Fragment only wants to add this node's SemanticsNode to the parent. // Fragment only wants to add this node's SemanticsNode to the parent.
assert(interestingFragment.config == null && node == _semantics); assert(interestingFragment.config == null && node == _semantics);
} }
/// Clip that needs to be applied to any [SemanticsNode] owned by this
/// [RenderObject].
///
/// Can be null if no clip is to be applied.
///
/// Updated by [_getSemanticsForParent].
Rect _semanticsClippingRect;
/// Returns the semantics that this node would like to add to its parent. /// Returns the semantics that this node would like to add to its parent.
_SemanticsFragment _getSemanticsForParent({ _SemanticsFragment _getSemanticsForParent({
@required Rect parentClippingRect,
@required bool mergeIntoParent, @required bool mergeIntoParent,
}) { }) {
assert(mergeIntoParent != null); assert(mergeIntoParent != null);
...@@ -2279,16 +2269,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -2279,16 +2269,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
final SemanticsConfiguration config = _semanticsConfiguration; final SemanticsConfiguration config = _semanticsConfiguration;
bool dropSemanticsOfPreviousSiblings = config.isBlockingSemanticsOfPreviouslyPaintedNodes; bool dropSemanticsOfPreviousSiblings = config.isBlockingSemanticsOfPreviouslyPaintedNodes;
final _SemanticsGeometry geometry = new _SemanticsGeometry(
owner: this,
parentClippingRect: parentClippingRect,
);
_semanticsClippingRect = geometry.clipRect;
// Shortcut if this fragment cannot be exposed to user.
if (_semanticsConfiguration.isSemanticBoundary && !mergeIntoParent && geometry.isInvisible)
return new _ContainerSemanticsFragment(dropsSemanticsOfPreviousSiblings: dropSemanticsOfPreviousSiblings);
final bool producesForkingFragment = !config.hasBeenAnnotated && !config.isSemanticBoundary; final bool producesForkingFragment = !config.hasBeenAnnotated && !config.isSemanticBoundary;
final List<_InterestingSemanticsFragment> fragments = <_InterestingSemanticsFragment>[]; final List<_InterestingSemanticsFragment> fragments = <_InterestingSemanticsFragment>[];
final Set<_InterestingSemanticsFragment> toBeMarkedExplicit = new Set<_InterestingSemanticsFragment>(); final Set<_InterestingSemanticsFragment> toBeMarkedExplicit = new Set<_InterestingSemanticsFragment>();
...@@ -2296,7 +2276,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -2296,7 +2276,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
visitChildrenForSemantics((RenderObject renderChild) { visitChildrenForSemantics((RenderObject renderChild) {
final _SemanticsFragment fragment = renderChild._getSemanticsForParent( final _SemanticsFragment fragment = renderChild._getSemanticsForParent(
parentClippingRect: _semanticsClippingRect,
mergeIntoParent: childrenMergeIntoParent, mergeIntoParent: childrenMergeIntoParent,
); );
if (fragment.dropsSemanticsOfPreviousSiblings) { if (fragment.dropsSemanticsOfPreviousSiblings) {
...@@ -2308,7 +2287,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -2308,7 +2287,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
// Figure out which child fragments are to be made explicit. // Figure out which child fragments are to be made explicit.
for (_InterestingSemanticsFragment fragment in fragment.interestingFragments) { for (_InterestingSemanticsFragment fragment in fragment.interestingFragments) {
fragments.add(fragment); fragments.add(fragment);
fragment.geometry.addAncestor(this); fragment.addAncestor(this);
fragment.addTags(config.tagsForChildren); fragment.addTags(config.tagsForChildren);
if (config.explicitChildNodes || parent is! RenderObject) { if (config.explicitChildNodes || parent is! RenderObject) {
fragment.markAsExplicit(); fragment.markAsExplicit();
...@@ -2347,7 +2326,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -2347,7 +2326,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
} else { } else {
result = new _SwitchableSemanticsFragment( result = new _SwitchableSemanticsFragment(
config: config, config: config,
geometry: geometry,
mergeIntoParent: mergeIntoParent, mergeIntoParent: mergeIntoParent,
owner: this, owner: this,
dropsSemanticsOfPreviousSiblings: dropSemanticsOfPreviousSiblings, dropsSemanticsOfPreviousSiblings: dropSemanticsOfPreviousSiblings,
...@@ -2998,18 +2976,20 @@ class _ContainerSemanticsFragment extends _SemanticsFragment { ...@@ -2998,18 +2976,20 @@ class _ContainerSemanticsFragment extends _SemanticsFragment {
/// merged into the parent's [SemanticsNode]. /// merged into the parent's [SemanticsNode].
abstract class _InterestingSemanticsFragment extends _SemanticsFragment { abstract class _InterestingSemanticsFragment extends _SemanticsFragment {
_InterestingSemanticsFragment({ _InterestingSemanticsFragment({
this.geometry, @required RenderObject owner,
@required this.owner,
@required bool dropsSemanticsOfPreviousSiblings @required bool dropsSemanticsOfPreviousSiblings
}) : assert(owner != null), }) : assert(owner != null),
_ancestorChain = <RenderObject>[owner],
super(dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings); super(dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings);
/// The [RenderObject] that owns this fragment (and any new [SemanticNode] /// The [RenderObject] that owns this fragment (and any new [SemanticNode]
/// introduced by it). /// introduced by it).
final RenderObject owner; RenderObject get owner => _ancestorChain.first;
final List<RenderObject> _ancestorChain;
/// The children to be added to the parent. /// The children to be added to the parent.
Iterable<SemanticsNode> compileChildren(); Iterable<SemanticsNode> compileChildren(Rect parentClipRect);
/// The [SemanticsConfiguration] the child wants to merge into the parent's /// The [SemanticsConfiguration] the child wants to merge into the parent's
/// [SemanticsNode] or null if it doesn't want to merge anything. /// [SemanticsNode] or null if it doesn't want to merge anything.
...@@ -3033,8 +3013,6 @@ abstract class _InterestingSemanticsFragment extends _SemanticsFragment { ...@@ -3033,8 +3013,6 @@ abstract class _InterestingSemanticsFragment extends _SemanticsFragment {
@override @override
void addAll(Iterable<_InterestingSemanticsFragment> fragments); void addAll(Iterable<_InterestingSemanticsFragment> fragments);
final _SemanticsGeometry geometry;
/// Whether this fragment wants to add any semantic information to the parent /// Whether this fragment wants to add any semantic information to the parent
/// [SemanticsNode]. /// [SemanticsNode].
bool get hasConfigForParent => config != null; bool get hasConfigForParent => config != null;
...@@ -3053,6 +3031,18 @@ abstract class _InterestingSemanticsFragment extends _SemanticsFragment { ...@@ -3053,6 +3031,18 @@ abstract class _InterestingSemanticsFragment extends _SemanticsFragment {
_tagsForChildren ??= new Set<SemanticsTag>(); _tagsForChildren ??= new Set<SemanticsTag>();
_tagsForChildren.addAll(tags); _tagsForChildren.addAll(tags);
} }
/// Adds the geometric information of `ancestor` to this object.
///
/// Those information are required to properly compute the value for
/// [SemanticsNode.transform], [SemanticsNode.clipRect], and
/// [SemanticsNode.rect].
///
/// Ancestors have to be added in order from [owner] up until the next
/// [RenderObject] that owns a [SemanticsNode] is reached.
void addAncestor(RenderObject ancestor) {
_ancestorChain.add(ancestor);
}
} }
/// A [_InterestingSemanticsFragment] that produces the root [SemanticsNode] of /// A [_InterestingSemanticsFragment] that produces the root [SemanticsNode] of
...@@ -3067,16 +3057,28 @@ class _RootSemanticsFragment extends _InterestingSemanticsFragment { ...@@ -3067,16 +3057,28 @@ class _RootSemanticsFragment extends _InterestingSemanticsFragment {
}) : super(owner: owner, dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings); }) : super(owner: owner, dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings);
@override @override
Iterable<SemanticsNode> compileChildren() sync* { Iterable<SemanticsNode> compileChildren(Rect parentClipRect) sync* {
assert(_tagsForChildren == null || _tagsForChildren.isEmpty); assert(_tagsForChildren == null || _tagsForChildren.isEmpty);
assert(parentClipRect == null);
assert(_ancestorChain.length == 1);
owner._semantics ??= new SemanticsNode.root( owner._semantics ??= new SemanticsNode.root(
showOnScreen: owner.showOnScreen, showOnScreen: owner.showOnScreen,
owner: owner.owner.semanticsOwner, owner: owner.owner.semanticsOwner,
); );
final SemanticsNode node = owner._semantics; final SemanticsNode node = owner._semantics;
assert(MatrixUtils.matrixEquals(node.transform, new Matrix4.identity())); assert(MatrixUtils.matrixEquals(node.transform, new Matrix4.identity()));
assert(!node.wasAffectedByClip); assert(node.parentClipRect == null);
node.rect = owner.semanticBounds; node.rect = owner.semanticBounds;
final List<SemanticsNode> children = <SemanticsNode>[];
for (_InterestingSemanticsFragment fragment in _children) {
assert(fragment.config == null);
children.addAll(fragment.compileChildren(parentClipRect));
}
node.updateWith(config: null, childrenInInversePaintOrder: children);
assert(!node.isInvisible); assert(!node.isInvisible);
yield node; yield node;
} }
...@@ -3084,6 +3086,8 @@ class _RootSemanticsFragment extends _InterestingSemanticsFragment { ...@@ -3084,6 +3086,8 @@ class _RootSemanticsFragment extends _InterestingSemanticsFragment {
@override @override
SemanticsConfiguration get config => null; SemanticsConfiguration get config => null;
final List<_InterestingSemanticsFragment> _children = <_InterestingSemanticsFragment>[];
@override @override
void markAsExplicit() { void markAsExplicit() {
// nothing to do, we are always explicit. // nothing to do, we are always explicit.
...@@ -3091,13 +3095,7 @@ class _RootSemanticsFragment extends _InterestingSemanticsFragment { ...@@ -3091,13 +3095,7 @@ class _RootSemanticsFragment extends _InterestingSemanticsFragment {
@override @override
void addAll(Iterable<_InterestingSemanticsFragment> fragments) { void addAll(Iterable<_InterestingSemanticsFragment> fragments) {
final SemanticsNode root = compileChildren().first; _children.addAll(fragments);
final List<SemanticsNode> children = <SemanticsNode>[];
for (_InterestingSemanticsFragment fragment in fragments) {
assert(fragment.config == null);
children.addAll(fragment.compileChildren());
}
root.updateWith(config: null, childrenInInversePaintOrder: children);
} }
} }
...@@ -3123,40 +3121,59 @@ class _SwitchableSemanticsFragment extends _InterestingSemanticsFragment { ...@@ -3123,40 +3121,59 @@ class _SwitchableSemanticsFragment extends _InterestingSemanticsFragment {
_SwitchableSemanticsFragment({ _SwitchableSemanticsFragment({
@required bool mergeIntoParent, @required bool mergeIntoParent,
@required SemanticsConfiguration config, @required SemanticsConfiguration config,
@required _SemanticsGeometry geometry,
@required RenderObject owner, @required RenderObject owner,
@required bool dropsSemanticsOfPreviousSiblings, @required bool dropsSemanticsOfPreviousSiblings,
}) : _mergeIntoParent = mergeIntoParent, }) : _mergeIntoParent = mergeIntoParent,
_config = config, _config = config,
assert(mergeIntoParent != null), assert(mergeIntoParent != null),
assert(config != null), assert(config != null),
super(geometry: geometry, owner: owner, dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings); super(owner: owner, dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings);
final bool _mergeIntoParent; final bool _mergeIntoParent;
SemanticsConfiguration _config; SemanticsConfiguration _config;
bool _isConfigWritable = false; bool _isConfigWritable = false;
final List<SemanticsNode> _children = <SemanticsNode>[]; final List<_InterestingSemanticsFragment> _children = <_InterestingSemanticsFragment>[];
@override @override
Iterable<SemanticsNode> compileChildren() sync* { Iterable<SemanticsNode> compileChildren(Rect parentClipRect) sync* {
if (!_isExplicit) { if (!_isExplicit) {
owner._semantics = null; owner._semantics = null;
yield* _children; for (_InterestingSemanticsFragment fragment in _children) {
assert(_ancestorChain.first == fragment._ancestorChain.last);
fragment._ancestorChain.addAll(_ancestorChain.sublist(1));
yield* fragment.compileChildren(parentClipRect);
}
return; return;
} }
if (!_mergeIntoParent && geometry.rect.isEmpty)
final _SemanticsGeometry geometry = _needsGeometryUpdate
? new _SemanticsGeometry(parentClipRect: parentClipRect, ancestors: _ancestorChain)
: null;
if (!_mergeIntoParent && (geometry?.isInvisible == true))
return; // Drop the node, it's not going to be visible. return; // Drop the node, it's not going to be visible.
owner._semantics ??= new SemanticsNode(showOnScreen: owner.showOnScreen); owner._semantics ??= new SemanticsNode(showOnScreen: owner.showOnScreen);
final SemanticsNode node = owner._semantics final SemanticsNode node = owner._semantics
..isMergedIntoParent = _mergeIntoParent ..isMergedIntoParent = _mergeIntoParent
..tags = _tagsForChildren; ..tags = _tagsForChildren;
geometry.updateNode(node); if (geometry != null) {
assert(_needsGeometryUpdate);
node
..rect = geometry.rect
..transform = geometry.transform
..parentClipRect = geometry.clipRect;
}
final List<SemanticsNode> children = <SemanticsNode>[];
for (_InterestingSemanticsFragment fragment in _children)
children.addAll(fragment.compileChildren(node.parentClipRect));
if (_config.isSemanticBoundary) { if (_config.isSemanticBoundary) {
owner.assembleSemanticsNode(node, _config, _children); owner.assembleSemanticsNode(node, _config, children);
} else { } else {
node.updateWith(config: _config, childrenInInversePaintOrder: _children); node.updateWith(config: _config, childrenInInversePaintOrder: children);
} }
yield node; yield node;
...@@ -3170,7 +3187,7 @@ class _SwitchableSemanticsFragment extends _InterestingSemanticsFragment { ...@@ -3170,7 +3187,7 @@ class _SwitchableSemanticsFragment extends _InterestingSemanticsFragment {
@override @override
void addAll(Iterable<_InterestingSemanticsFragment> fragments) { void addAll(Iterable<_InterestingSemanticsFragment> fragments) {
for (_InterestingSemanticsFragment fragment in fragments) { for (_InterestingSemanticsFragment fragment in fragments) {
_children.addAll(fragment.compileChildren()); _children.add(fragment);
if (fragment.config == null) if (fragment.config == null)
continue; continue;
if (!_isConfigWritable) { if (!_isConfigWritable) {
...@@ -3187,6 +3204,8 @@ class _SwitchableSemanticsFragment extends _InterestingSemanticsFragment { ...@@ -3187,6 +3204,8 @@ class _SwitchableSemanticsFragment extends _InterestingSemanticsFragment {
void markAsExplicit() { void markAsExplicit() {
_isExplicit = true; _isExplicit = true;
} }
bool get _needsGeometryUpdate => _ancestorChain.length > 1;
} }
/// Helper class that keeps track of the geometry of a [SemanticsNode]. /// Helper class that keeps track of the geometry of a [SemanticsNode].
...@@ -3195,109 +3214,68 @@ class _SwitchableSemanticsFragment extends _InterestingSemanticsFragment { ...@@ -3195,109 +3214,68 @@ class _SwitchableSemanticsFragment extends _InterestingSemanticsFragment {
/// [SemanticsNode.rect] and [SemanticsNode.transform]. /// [SemanticsNode.rect] and [SemanticsNode.transform].
class _SemanticsGeometry { class _SemanticsGeometry {
/// `parentClippingRect` may be null if no clip is to be applied. /// The `parentClippingRect` may be null if no clip is to be applied.
///
/// The `ancestors` list has to include all [RenderObject] in order that are
/// located between the [SemanticsNode] whose geometry is represented here
/// (first [RenderObject] in the list) and its closest ancestor [RenderObject]
/// that also owns its own [SemanticsNode] (last [RenderObject] in the list).
_SemanticsGeometry({ _SemanticsGeometry({
@required RenderObject owner, @required Rect parentClipRect,
@required Rect parentClippingRect @required List<RenderObject> ancestors,
}) : assert(owner != null), }) {
_ancestorChain = <RenderObject>[owner], _computeValues(parentClipRect, ancestors);
_parentClippingRect = parentClippingRect; }
final Rect _parentClippingRect;
final List<RenderObject> _ancestorChain;
RenderObject get _owner => _ancestorChain.first;
/// The current clip [Rect] that would be applied to the [SemanticsNode]
/// owned by [owner].
Rect get clipRect {
if (!_isClipRectValid) {
__clipRect = _computeClipRect();
_isClipRectValid = true;
}
return __clipRect;
}
Rect __clipRect;
bool _isClipRectValid = false;
Rect _computeClipRect() {
if (_owner.parent is! RenderObject)
return null;
final RenderObject parent = _owner.parent;
// Clip rect in parent's coordinate system.
Rect clip = parent.describeApproximatePaintClip(_owner);
if (clip == null) {
if (_parentClippingRect == null)
return null;
clip = _parentClippingRect;
} else if (_parentClippingRect != null) {
clip = _parentClippingRect.intersect(clip);
}
assert(clip != null); Rect _clipRect;
if (clip.isEmpty) Matrix4 _transform;
return Rect.zero; Rect _rect;
// Translate clip into owner's coordinate system. /// Value for [SemanticsNode.transform].
final Matrix4 clipTransform = new Matrix4.identity(); Matrix4 get transform => _transform;
parent.applyPaintTransform(_owner, clipTransform);
return MatrixUtils.inverseTransformRect(clipTransform, clip);
}
/// The value for [SemanticsNode.rect]. /// Value for [SemanticsNode.parentClipRect].
/// Rect get clipRect => _clipRect;
/// This is essentially [RenderObject.semanticsBound] with [clipRect] applied.
Rect get rect {
if (__rect == null)
__rect = _computeRect();
return __rect;
}
Rect __rect;
Rect _computeRect() { /// Value for [SemanticsNode.rect].
if (clipRect == null) Rect get rect => _rect;
return _owner.semanticBounds;
return clipRect.intersect(_owner.semanticBounds);
}
Matrix4 _computeTransformation() { void _computeValues(Rect parentClipRect, List<RenderObject> ancestors) {
assert(_ancestorChain.length > 1); assert(ancestors.length > 1);
final Matrix4 transform = new Matrix4.identity();
for (int index = _ancestorChain.length-1; index > 0; index -= 1) {
final RenderObject parent = _ancestorChain[index];
final RenderObject child = _ancestorChain[index - 1];
parent.applyPaintTransform(child, transform);
_transform = new Matrix4.identity();
_clipRect = parentClipRect;
for (int index = ancestors.length-1; index > 0; index -= 1) {
final RenderObject parent = ancestors[index];
final RenderObject child = ancestors[index-1];
_clipRect = _intersectClipRect(parent.describeApproximatePaintClip(child));
if (_clipRect != null) {
if (_clipRect.isEmpty) {
_clipRect = Rect.zero;
} else {
final Matrix4 clipTransform = new Matrix4.identity();
parent.applyPaintTransform(child, clipTransform);
_clipRect = MatrixUtils.inverseTransformRect(clipTransform, _clipRect);
}
}
parent.applyPaintTransform(child, _transform);
} }
return transform;
}
/// Annotates `node` with the latest geometry information. final RenderObject owner = ancestors.first;
/// _rect = _clipRect == null ? owner.semanticBounds : _clipRect.intersect(owner.semanticBounds);
/// It sets [SemanticsNode.rect], [SemanticsNode.transform], and
/// [SemanticsNode.wasAffectedByClip] to the current values.
void updateNode(SemanticsNode node) {
if (_ancestorChain.length > 1)
node.transform = _computeTransformation();
node.rect = rect;
node.wasAffectedByClip = rect != _owner.semanticBounds;
} }
/// Adds the geometric information of `ancestor` to this object. Rect _intersectClipRect(Rect other) {
/// if (_clipRect == null)
/// Those information are required to properly compute the value for return other;
/// [SemanticsNode.transform]. if (other == null)
/// return _clipRect;
/// Ancestors have to be added in order from [owner] up until the next return _clipRect.intersect(other);
/// [RenderObject] that owns a [SemanticsNode] is reached.
void addAncestor(RenderObject ancestor) {
_ancestorChain.add(ancestor);
} }
/// Whether a [SemanticsNode] annotated with the geometric information tracked /// Whether a [SemanticsNode] annotated with the geometric information tracked
/// by this object would be visible on screen. /// by this object would be visible on screen.
bool get isInvisible { bool get isInvisible {
return clipRect != null && clipRect.isEmpty || rect.isEmpty; return _rect.isEmpty;
} }
} }
...@@ -3086,7 +3086,6 @@ class RenderSemanticsGestureHandler extends RenderProxyBox { ...@@ -3086,7 +3086,6 @@ class RenderSemanticsGestureHandler extends RenderProxyBox {
_innerNode ??= new SemanticsNode(showOnScreen: showOnScreen); _innerNode ??= new SemanticsNode(showOnScreen: showOnScreen);
_innerNode _innerNode
..wasAffectedByClip = node.wasAffectedByClip
..isMergedIntoParent = node.isPartOfNodeMerging ..isMergedIntoParent = node.isPartOfNodeMerging
..rect = Offset.zero & node.rect.size; ..rect = Offset.zero & node.rect.size;
_annotatedNode = _innerNode; _annotatedNode = _innerNode;
......
...@@ -253,12 +253,11 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -253,12 +253,11 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
} }
} }
/// Whether [rect] was affected by a clip from an ancestors. /// The clip rect from an ancestor that was applied to this node.
/// ///
/// If this is true it means that an ancestor imposed a clip on this /// Expressed in the coordinate system of the node. May be null if no clip has
/// [SemanticsNode]. However, it does not mean that the clip had any effect /// been applied.
/// on the [rect] whatsoever. Rect parentClipRect;
bool wasAffectedByClip = false;
/// Whether the node is invisible. /// Whether the node is invisible.
/// ///
...@@ -488,7 +487,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -488,7 +487,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
return _label != config.label || return _label != config.label ||
_flags != config._flags || _flags != config._flags ||
_textDirection != config.textDirection || _textDirection != config.textDirection ||
_actionsAsBitMap(_actions) != _actionsAsBitMap(config._actions) || _actionsAsBits != config._actionsAsBits ||
_mergeAllDescendantsIntoThisNode != config.isMergingSemanticsOfDescendants; _mergeAllDescendantsIntoThisNode != config.isMergingSemanticsOfDescendants;
} }
...@@ -496,6 +495,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -496,6 +495,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
Map<SemanticsAction, VoidCallback> _actions = _kEmptyConfig._actions; Map<SemanticsAction, VoidCallback> _actions = _kEmptyConfig._actions;
int _actionsAsBits = _kEmptyConfig._actionsAsBits;
/// The [SemanticsTag]s this node is tagged with. /// The [SemanticsTag]s this node is tagged with.
/// ///
/// Tags are used during the construction of the semantics tree. They are not /// Tags are used during the construction of the semantics tree. They are not
...@@ -519,10 +520,6 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -519,10 +520,6 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
TextDirection get textDirection => _textDirection; TextDirection get textDirection => _textDirection;
TextDirection _textDirection = _kEmptyConfig.textDirection; TextDirection _textDirection = _kEmptyConfig.textDirection;
int _actionsAsBitMap(Map<SemanticsAction, VoidCallback> actions) {
return actions.keys.fold(0, (int prev, SemanticsAction action) => prev |= action.index);
}
bool _canPerformAction(SemanticsAction action) => _actions.containsKey(action); bool _canPerformAction(SemanticsAction action) => _actions.containsKey(action);
static final SemanticsConfiguration _kEmptyConfig = new SemanticsConfiguration(); static final SemanticsConfiguration _kEmptyConfig = new SemanticsConfiguration();
...@@ -539,6 +536,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -539,6 +536,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
_flags = config._flags; _flags = config._flags;
_textDirection = config.textDirection; _textDirection = config.textDirection;
_actions = new Map<SemanticsAction, VoidCallback>.from(config._actions); _actions = new Map<SemanticsAction, VoidCallback>.from(config._actions);
_actionsAsBits = config._actionsAsBits;
_mergeAllDescendantsIntoThisNode = config.isMergingSemanticsOfDescendants; _mergeAllDescendantsIntoThisNode = config.isMergingSemanticsOfDescendants;
_replaceChildren(childrenInInversePaintOrder ?? const <SemanticsNode>[]); _replaceChildren(childrenInInversePaintOrder ?? const <SemanticsNode>[]);
} }
...@@ -551,7 +549,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -551,7 +549,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// returned data matches the data on this node. /// returned data matches the data on this node.
SemanticsData getSemanticsData() { SemanticsData getSemanticsData() {
int flags = _flags; int flags = _flags;
int actions = _actionsAsBitMap(_actions); int actions = _actionsAsBits;
String label = _label; String label = _label;
TextDirection textDirection = _textDirection; TextDirection textDirection = _textDirection;
Set<SemanticsTag> mergedTags = tags == null ? null : new Set<SemanticsTag>.from(tags); Set<SemanticsTag> mergedTags = tags == null ? null : new Set<SemanticsTag>.from(tags);
...@@ -560,7 +558,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -560,7 +558,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
_visitDescendants((SemanticsNode node) { _visitDescendants((SemanticsNode node) {
assert(node.isMergedIntoParent); assert(node.isMergedIntoParent);
flags |= node._flags; flags |= node._flags;
actions |= _actionsAsBitMap(node._actions); actions |= node._actionsAsBits;
textDirection ??= node._textDirection; textDirection ??= node._textDirection;
if (node.tags != null) { if (node.tags != null) {
mergedTags ??= new Set<SemanticsTag>(); mergedTags ??= new Set<SemanticsTag>();
...@@ -673,7 +671,6 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -673,7 +671,6 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
} }
properties.add(new DiagnosticsProperty<Rect>('rect', rect, description: description, showName: false)); properties.add(new DiagnosticsProperty<Rect>('rect', rect, description: description, showName: false));
} }
properties.add(new FlagProperty('wasAffectedByClip', value: wasAffectedByClip, ifTrue: 'clipped'));
final List<String> actions = _actions.keys.map((SemanticsAction action) => describeEnum(action)).toList()..sort(); final List<String> actions = _actions.keys.map((SemanticsAction action) => describeEnum(action)).toList()..sort();
properties.add(new IterableProperty<String>('actions', actions, ifEmpty: null)); properties.add(new IterableProperty<String>('actions', actions, ifEmpty: null));
if (_hasFlag(SemanticsFlags.hasCheckedState)) if (_hasFlag(SemanticsFlags.hasCheckedState))
...@@ -871,7 +868,7 @@ class SemanticsOwner extends ChangeNotifier { ...@@ -871,7 +868,7 @@ class SemanticsOwner extends ChangeNotifier {
return handler; return handler;
} }
} }
return node._canPerformAction(action) ? node._actions[action] : null; return node._actions[action];
} }
/// Asks the [SemanticsNode] at the given position to perform the given action. /// Asks the [SemanticsNode] at the given position to perform the given action.
...@@ -985,11 +982,14 @@ class SemanticsConfiguration { ...@@ -985,11 +982,14 @@ class SemanticsConfiguration {
/// * [addAction] to add an action. /// * [addAction] to add an action.
final Map<SemanticsAction, VoidCallback> _actions = <SemanticsAction, VoidCallback>{}; final Map<SemanticsAction, VoidCallback> _actions = <SemanticsAction, VoidCallback>{};
int _actionsAsBits = 0;
/// Adds an `action` to the semantics tree. /// Adds an `action` to the semantics tree.
/// ///
/// Whenever the user performs `action` the provided `handler` is called. /// Whenever the user performs `action` the provided `handler` is called.
void addAction(SemanticsAction action, VoidCallback handler) { void addAction(SemanticsAction action, VoidCallback handler) {
_actions[action] = handler; _actions[action] = handler;
_actionsAsBits |= action.index;
_hasBeenAnnotated = true; _hasBeenAnnotated = true;
} }
...@@ -1083,7 +1083,7 @@ class SemanticsConfiguration { ...@@ -1083,7 +1083,7 @@ class SemanticsConfiguration {
bool isCompatibleWith(SemanticsConfiguration other) { bool isCompatibleWith(SemanticsConfiguration other) {
if (other == null || !other.hasBeenAnnotated || !hasBeenAnnotated) if (other == null || !other.hasBeenAnnotated || !hasBeenAnnotated)
return true; return true;
if (_actions.keys.toSet().intersection(other._actions.keys.toSet()).isNotEmpty) if (_actionsAsBits & other._actionsAsBits != 0)
return false; return false;
if ((_flags & other._flags) != 0) if ((_flags & other._flags) != 0)
return false; return false;
...@@ -1105,6 +1105,7 @@ class SemanticsConfiguration { ...@@ -1105,6 +1105,7 @@ class SemanticsConfiguration {
return; return;
_actions.addAll(other._actions); _actions.addAll(other._actions);
_actionsAsBits |= other._actionsAsBits;
_flags |= other._flags; _flags |= other._flags;
textDirection ??= other.textDirection; textDirection ??= other.textDirection;
...@@ -1138,6 +1139,7 @@ class SemanticsConfiguration { ...@@ -1138,6 +1139,7 @@ class SemanticsConfiguration {
.._textDirection = _textDirection .._textDirection = _textDirection
.._label = _label .._label = _label
.._flags = _flags .._flags = _flags
.._actionsAsBits = _actionsAsBits
.._actions.addAll(_actions); .._actions.addAll(_actions);
} }
} }
...@@ -40,12 +40,12 @@ void main() { ...@@ -40,12 +40,12 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 2, id: 1,
label: 'I am text!\nMoar text!!1', label: 'I am text!\nMoar text!!1',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 1, id: 2,
label: 'Button', label: 'Button',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
actions: SemanticsAction.tap.index, actions: SemanticsAction.tap.index,
......
...@@ -95,7 +95,7 @@ void main() { ...@@ -95,7 +95,7 @@ void main() {
expect(semantics, hasSemantics(new TestSemantics.root( expect(semantics, hasSemantics(new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 7, id: 1,
rect: new Rect.fromLTWH(0.0, 0.0, 800.0, 56.0), rect: new Rect.fromLTWH(0.0, 0.0, 800.0, 56.0),
transform: null, transform: null,
flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index, flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index,
...@@ -103,7 +103,7 @@ void main() { ...@@ -103,7 +103,7 @@ void main() {
label: 'aaa\nAAA', label: 'aaa\nAAA',
), ),
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 8, id: 4,
rect: new Rect.fromLTWH(0.0, 0.0, 800.0, 56.0), rect: new Rect.fromLTWH(0.0, 0.0, 800.0, 56.0),
transform: new Matrix4.translationValues(0.0, 56.0, 0.0), transform: new Matrix4.translationValues(0.0, 56.0, 0.0),
flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index, flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index,
...@@ -111,7 +111,7 @@ void main() { ...@@ -111,7 +111,7 @@ void main() {
label: 'bbb\nBBB', label: 'bbb\nBBB',
), ),
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 9, id: 7,
rect: new Rect.fromLTWH(0.0, 0.0, 800.0, 56.0), rect: new Rect.fromLTWH(0.0, 0.0, 800.0, 56.0),
transform: new Matrix4.translationValues(0.0, 112.0, 0.0), transform: new Matrix4.translationValues(0.0, 112.0, 0.0),
flags: SemanticsFlags.hasCheckedState.index, flags: SemanticsFlags.hasCheckedState.index,
......
...@@ -1011,11 +1011,11 @@ void main() { ...@@ -1011,11 +1011,11 @@ void main() {
final TestSemantics expectedSemantics = new TestSemantics.root( final TestSemantics expectedSemantics = new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 1, id: 2,
actions: SemanticsAction.tap.index, actions: SemanticsAction.tap.index,
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
label: 'TAB #0\nTab 1 of 2', label: 'TAB #0\nTab 1 of 2',
...@@ -1023,7 +1023,7 @@ void main() { ...@@ -1023,7 +1023,7 @@ void main() {
transform: new Matrix4.translationValues(0.0, 276.0, 0.0), transform: new Matrix4.translationValues(0.0, 276.0, 0.0),
), ),
new TestSemantics( new TestSemantics(
id: 2, id: 3,
actions: SemanticsAction.tap.index, actions: SemanticsAction.tap.index,
label: 'TAB #1\nTab 2 of 2', label: 'TAB #1\nTab 2 of 2',
rect: new Rect.fromLTRB(0.0, 0.0, 108.0, kTextTabBarHeight), rect: new Rect.fromLTRB(0.0, 0.0, 108.0, kTextTabBarHeight),
...@@ -1261,11 +1261,11 @@ void main() { ...@@ -1261,11 +1261,11 @@ void main() {
final TestSemantics expectedSemantics = new TestSemantics.root( final TestSemantics expectedSemantics = new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 25, id: 23,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 23, id: 24,
actions: SemanticsAction.tap.index, actions: SemanticsAction.tap.index,
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
label: 'Semantics override 0\nTab 1 of 2', label: 'Semantics override 0\nTab 1 of 2',
...@@ -1273,7 +1273,7 @@ void main() { ...@@ -1273,7 +1273,7 @@ void main() {
transform: new Matrix4.translationValues(0.0, 276.0, 0.0), transform: new Matrix4.translationValues(0.0, 276.0, 0.0),
), ),
new TestSemantics( new TestSemantics(
id: 24, id: 25,
actions: SemanticsAction.tap.index, actions: SemanticsAction.tap.index,
label: 'Semantics override 1\nTab 2 of 2', label: 'Semantics override 1\nTab 2 of 2',
rect: new Rect.fromLTRB(0.0, 0.0, 108.0, kTextTabBarHeight), rect: new Rect.fromLTRB(0.0, 0.0, 108.0, kTextTabBarHeight),
......
...@@ -198,7 +198,7 @@ void main() { ...@@ -198,7 +198,7 @@ void main() {
expect( expect(
minimalProperties.toStringDeep(minLevel: DiagnosticLevel.hidden), minimalProperties.toStringDeep(minLevel: DiagnosticLevel.hidden),
'SemanticsNode#16(owner: null, isPartOfNodeMerging: false, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), wasAffectedByClip: false, actions: [], isSelected: false, label: "", isButton: false, textDirection: null)\n', 'SemanticsNode#16(owner: null, isPartOfNodeMerging: false, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), actions: [], isSelected: false, label: "", isButton: false, textDirection: null)\n',
); );
final SemanticsConfiguration config = new SemanticsConfiguration() final SemanticsConfiguration config = new SemanticsConfiguration()
...@@ -214,11 +214,10 @@ void main() { ...@@ -214,11 +214,10 @@ void main() {
final SemanticsNode allProperties = new SemanticsNode() final SemanticsNode allProperties = new SemanticsNode()
..rect = new Rect.fromLTWH(50.0, 10.0, 20.0, 30.0) ..rect = new Rect.fromLTWH(50.0, 10.0, 20.0, 30.0)
..transform = new Matrix4.translation(new Vector3(10.0, 10.0, 0.0)) ..transform = new Matrix4.translation(new Vector3(10.0, 10.0, 0.0))
..wasAffectedByClip = true
..updateWith(config: config, childrenInInversePaintOrder: null); ..updateWith(config: config, childrenInInversePaintOrder: null);
expect( expect(
allProperties.toStringDeep(), allProperties.toStringDeep(),
'SemanticsNode#17(STALE, owner: null, leaf merge, Rect.fromLTRB(60.0, 20.0, 80.0, 50.0), clipped, actions: [longPress, scrollUp, showOnScreen], unchecked, selected, label: "Use all the properties", button, textDirection: rtl)\n', 'SemanticsNode#17(STALE, owner: null, leaf merge, Rect.fromLTRB(60.0, 20.0, 80.0, 50.0), actions: [longPress, scrollUp, showOnScreen], unchecked, selected, label: "Use all the properties", button, textDirection: rtl)\n',
); );
expect( expect(
allProperties.getSemanticsData().toString(), allProperties.getSemanticsData().toString(),
......
...@@ -229,20 +229,20 @@ void main() { ...@@ -229,20 +229,20 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 8, id: 5,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 5, id: 6,
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
label: 'node 1', label: 'node 1',
), ),
new TestSemantics( new TestSemantics(
id: 6, id: 7,
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
label: 'node 2', label: 'node 2',
), ),
new TestSemantics( new TestSemantics(
id: 7, id: 8,
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
label: 'node 3', label: 'node 3',
), ),
......
...@@ -104,11 +104,11 @@ void main() { ...@@ -104,11 +104,11 @@ void main() {
final TestSemantics expectedSemantics = new TestSemantics.root( final TestSemantics expectedSemantics = new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 2, id: 1,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 1, id: 2,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
actions: SemanticsAction.tap.index, actions: SemanticsAction.tap.index,
), ),
......
...@@ -53,17 +53,17 @@ void main() { ...@@ -53,17 +53,17 @@ void main() {
expect(semantics, hasSemantics(new TestSemantics.root( expect(semantics, hasSemantics(new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 1, id: 2,
label: 'child1', label: 'child1',
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 10.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 10.0),
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
), ),
new TestSemantics( new TestSemantics(
id: 2, id: 3,
label: 'child2', label: 'child2',
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 10.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 10.0),
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
...@@ -107,7 +107,7 @@ void main() { ...@@ -107,7 +107,7 @@ void main() {
expect(semantics, hasSemantics(new TestSemantics.root( expect(semantics, hasSemantics(new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
label: 'child1', label: 'child1',
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
...@@ -149,7 +149,7 @@ void main() { ...@@ -149,7 +149,7 @@ void main() {
expect(semantics, hasSemantics(new TestSemantics.root( expect(semantics, hasSemantics(new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
...@@ -159,7 +159,7 @@ void main() { ...@@ -159,7 +159,7 @@ void main() {
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
), ),
new TestSemantics( new TestSemantics(
id: 2, id: 3,
label: 'child2', label: 'child2',
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 10.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 10.0),
flags: SemanticsFlags.isSelected.index, flags: SemanticsFlags.isSelected.index,
......
...@@ -53,22 +53,22 @@ void main() { ...@@ -53,22 +53,22 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
label: 'L1', label: 'L1',
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
), ),
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 4, id: 2,
label: 'L2', label: 'L2',
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 1, id: 3,
flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index, flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
), ),
new TestSemantics( new TestSemantics(
id: 2, id: 4,
flags: SemanticsFlags.hasCheckedState.index, flags: SemanticsFlags.hasCheckedState.index,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
), ),
...@@ -113,12 +113,12 @@ void main() { ...@@ -113,12 +113,12 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
label: 'L1', label: 'L1',
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
), ),
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 4, id: 2,
label: 'L2', label: 'L2',
flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index, flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
...@@ -158,7 +158,7 @@ void main() { ...@@ -158,7 +158,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 4, id: 2,
label: 'L2', label: 'L2',
flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index, flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
......
...@@ -55,7 +55,7 @@ void main() { ...@@ -55,7 +55,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index, flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index,
label: label, label: label,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
...@@ -111,7 +111,7 @@ void main() { ...@@ -111,7 +111,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index, flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index,
label: label, label: label,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
......
...@@ -41,7 +41,7 @@ void main() { ...@@ -41,7 +41,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index, flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index,
label: 'label', label: 'label',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -79,7 +79,7 @@ void main() { ...@@ -79,7 +79,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 3, id: 1,
flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index, flags: SemanticsFlags.hasCheckedState.index | SemanticsFlags.isChecked.index,
label: 'label', label: 'label',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
......
...@@ -60,12 +60,6 @@ void main() { ...@@ -60,12 +60,6 @@ void main() {
ignoreTransform: true, ignoreTransform: true,
)); ));
final SemanticsNode node1 = tester.renderObject(find.byWidget(const Text('1'))).debugSemantics;
final SemanticsNode node2 = tester.renderObject(find.byWidget(const Text('2'))).debugSemantics;
expect(node1.wasAffectedByClip, false);
expect(node2.wasAffectedByClip, true);
semantics.dispose(); semantics.dispose();
}); });
......
...@@ -50,7 +50,7 @@ void main() { ...@@ -50,7 +50,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 4, id: 1,
tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics], tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics],
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
...@@ -58,15 +58,15 @@ void main() { ...@@ -58,15 +58,15 @@ void main() {
actions: SemanticsAction.scrollUp.index, actions: SemanticsAction.scrollUp.index,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 1, id: 2,
label: 'Item 0', label: 'Item 0',
), ),
new TestSemantics( new TestSemantics(
id: 2, id: 3,
label: 'Item 1', label: 'Item 1',
), ),
new TestSemantics( new TestSemantics(
id: 3, id: 4,
label: 'Semantics Test with Slivers', label: 'Semantics Test with Slivers',
), ),
], ],
...@@ -88,7 +88,7 @@ void main() { ...@@ -88,7 +88,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 4, id: 1,
tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics], tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics],
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
...@@ -96,11 +96,11 @@ void main() { ...@@ -96,11 +96,11 @@ void main() {
actions: SemanticsAction.scrollUp.index | SemanticsAction.scrollDown.index, actions: SemanticsAction.scrollUp.index | SemanticsAction.scrollDown.index,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 1, id: 2,
label: 'Item 0', label: 'Item 0',
), ),
new TestSemantics( new TestSemantics(
id: 2, id: 3,
label: 'Item 1', label: 'Item 1',
), ),
new TestSemantics( new TestSemantics(
...@@ -110,7 +110,7 @@ void main() { ...@@ -110,7 +110,7 @@ void main() {
], ],
), ),
new TestSemantics( new TestSemantics(
id: 3, id: 4,
label: 'Semantics Test with Slivers', label: 'Semantics Test with Slivers',
tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling], tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling],
), ),
...@@ -131,7 +131,7 @@ void main() { ...@@ -131,7 +131,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 4, id: 1,
tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics], tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics],
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
...@@ -139,11 +139,11 @@ void main() { ...@@ -139,11 +139,11 @@ void main() {
actions: SemanticsAction.scrollUp.index | SemanticsAction.scrollDown.index, actions: SemanticsAction.scrollUp.index | SemanticsAction.scrollDown.index,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 1, id: 2,
label: 'Item 0', label: 'Item 0',
), ),
new TestSemantics( new TestSemantics(
id: 2, id: 3,
label: 'Item 1', label: 'Item 1',
), ),
new TestSemantics( new TestSemantics(
...@@ -151,7 +151,7 @@ void main() { ...@@ -151,7 +151,7 @@ void main() {
label: 'Item 2', label: 'Item 2',
), ),
new TestSemantics( new TestSemantics(
id: 3, id: 4,
label: 'Semantics Test with Slivers', label: 'Semantics Test with Slivers',
), ),
], ],
...@@ -202,7 +202,7 @@ void main() { ...@@ -202,7 +202,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 9, id: 7,
tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics], tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics],
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
...@@ -210,12 +210,12 @@ void main() { ...@@ -210,12 +210,12 @@ void main() {
actions: SemanticsAction.scrollUp.index | SemanticsAction.scrollDown.index, actions: SemanticsAction.scrollUp.index | SemanticsAction.scrollDown.index,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 7, id: 8,
label: 'Item 2', label: 'Item 2',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
new TestSemantics( new TestSemantics(
id: 8, id: 9,
label: 'Item 1', label: 'Item 1',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
...@@ -256,34 +256,34 @@ void main() { ...@@ -256,34 +256,34 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 16, id: 11,
tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics], tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics],
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 17, id: 17,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 11, id: 12,
label: 'Item 4', label: 'Item 4',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
new TestSemantics( new TestSemantics(
id: 12, id: 13,
label: 'Item 3', label: 'Item 3',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
new TestSemantics( new TestSemantics(
id: 13, id: 14,
label: 'Item 2', label: 'Item 2',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
new TestSemantics( new TestSemantics(
id: 14, id: 15,
label: 'Item 1', label: 'Item 1',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
new TestSemantics( new TestSemantics(
id: 15, id: 16,
label: 'Item 0', label: 'Item 0',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
...@@ -337,7 +337,7 @@ void main() { ...@@ -337,7 +337,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 22, id: 18,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics], tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics],
children: <TestSemantics>[ children: <TestSemantics>[
...@@ -348,20 +348,20 @@ void main() { ...@@ -348,20 +348,20 @@ void main() {
children: <TestSemantics>[ children: <TestSemantics>[
// Item 0 is missing because its covered by the app bar. // Item 0 is missing because its covered by the app bar.
new TestSemantics( new TestSemantics(
id: 18, id: 19,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
// Item 1 starts 20.0dp below edge, so there would be room for Item 0. // Item 1 starts 20.0dp below edge, so there would be room for Item 0.
transform: new Matrix4.translation(new Vector3(0.0, 20.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 20.0, 0.0)),
label: 'Item 1', label: 'Item 1',
), ),
new TestSemantics( new TestSemantics(
id: 19, id: 20,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
transform: new Matrix4.translation(new Vector3(0.0, 220.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 220.0, 0.0)),
label: 'Item 2', label: 'Item 2',
), ),
new TestSemantics( new TestSemantics(
id: 20, id: 21,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
transform: new Matrix4.translation(new Vector3(0.0, 420.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 420.0, 0.0)),
label: 'Item 3', label: 'Item 3',
...@@ -369,7 +369,7 @@ void main() { ...@@ -369,7 +369,7 @@ void main() {
], ],
), ),
new TestSemantics( new TestSemantics(
id: 21, id: 22,
rect: new Rect.fromLTRB(0.0, 0.0, 120.0, 20.0), rect: new Rect.fromLTRB(0.0, 0.0, 120.0, 20.0),
tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling], tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling],
label: 'AppBar', label: 'AppBar',
...@@ -420,7 +420,7 @@ void main() { ...@@ -420,7 +420,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 28, id: 24,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics], tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics],
children: <TestSemantics>[ children: <TestSemantics>[
...@@ -430,19 +430,19 @@ void main() { ...@@ -430,19 +430,19 @@ void main() {
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 24, id: 25,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
transform: new Matrix4.translation(new Vector3(0.0, 420.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 420.0, 0.0)),
label: 'Item 3', label: 'Item 3',
), ),
new TestSemantics( new TestSemantics(
id: 25, id: 26,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
transform: new Matrix4.translation(new Vector3(0.0, 220.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 220.0, 0.0)),
label: 'Item 2', label: 'Item 2',
), ),
new TestSemantics( new TestSemantics(
id: 26, id: 27,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
// Item 1 starts 20.0dp below edge, so there would be room for Item 0. // Item 1 starts 20.0dp below edge, so there would be room for Item 0.
transform: new Matrix4.translation(new Vector3(0.0, 20.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 20.0, 0.0)),
...@@ -452,7 +452,7 @@ void main() { ...@@ -452,7 +452,7 @@ void main() {
], ],
), ),
new TestSemantics( new TestSemantics(
id: 27, id: 28,
rect: new Rect.fromLTRB(0.0, 0.0, 120.0, 20.0), rect: new Rect.fromLTRB(0.0, 0.0, 120.0, 20.0),
tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling], tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling],
label: 'AppBar' label: 'AppBar'
...@@ -505,7 +505,7 @@ void main() { ...@@ -505,7 +505,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 34, id: 30,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics], tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics],
children: <TestSemantics>[ children: <TestSemantics>[
...@@ -516,20 +516,20 @@ void main() { ...@@ -516,20 +516,20 @@ void main() {
children: <TestSemantics>[ children: <TestSemantics>[
// Item 0 is missing because its covered by the app bar. // Item 0 is missing because its covered by the app bar.
new TestSemantics( new TestSemantics(
id: 30, id: 31,
// Item 1 ends at 580dp, so there would be 20dp space for Item 0. // Item 1 ends at 580dp, so there would be 20dp space for Item 0.
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
transform: new Matrix4.translation(new Vector3(0.0, 380.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 380.0, 0.0)),
label: 'Item 1', label: 'Item 1',
), ),
new TestSemantics( new TestSemantics(
id: 31, id: 32,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
transform: new Matrix4.translation(new Vector3(0.0, 180.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 180.0, 0.0)),
label: 'Item 2', label: 'Item 2',
), ),
new TestSemantics( new TestSemantics(
id: 32, id: 33,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
transform: new Matrix4.translation(new Vector3(0.0, -20.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, -20.0, 0.0)),
label: 'Item 3', label: 'Item 3',
...@@ -537,7 +537,7 @@ void main() { ...@@ -537,7 +537,7 @@ void main() {
], ],
), ),
new TestSemantics( new TestSemantics(
id: 33, id: 34,
rect: new Rect.fromLTRB(0.0, 0.0, 120.0, 20.0), rect: new Rect.fromLTRB(0.0, 0.0, 120.0, 20.0),
transform: new Matrix4.translation(new Vector3(0.0, 544.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 544.0, 0.0)),
tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling], tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling],
...@@ -590,7 +590,7 @@ void main() { ...@@ -590,7 +590,7 @@ void main() {
new TestSemantics.root( new TestSemantics.root(
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics.rootChild( new TestSemantics.rootChild(
id: 40, id: 36,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics], tags: <SemanticsTag>[RenderSemanticsGestureHandler.useTwoPaneSemantics],
children: <TestSemantics>[ children: <TestSemantics>[
...@@ -600,19 +600,19 @@ void main() { ...@@ -600,19 +600,19 @@ void main() {
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
children: <TestSemantics>[ children: <TestSemantics>[
new TestSemantics( new TestSemantics(
id: 36, id: 37,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
transform: new Matrix4.translation(new Vector3(0.0, -20.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, -20.0, 0.0)),
label: 'Item 3', label: 'Item 3',
), ),
new TestSemantics( new TestSemantics(
id: 37, id: 38,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
transform: new Matrix4.translation(new Vector3(0.0, 180.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 180.0, 0.0)),
label: 'Item 2', label: 'Item 2',
), ),
new TestSemantics( new TestSemantics(
id: 38, id: 39,
rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0), rect: new Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
// Item 1 ends at 580dp, so there would be 20dp space for Item 0. // Item 1 ends at 580dp, so there would be 20dp space for Item 0.
transform: new Matrix4.translation(new Vector3(0.0, 380.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 380.0, 0.0)),
...@@ -622,7 +622,7 @@ void main() { ...@@ -622,7 +622,7 @@ void main() {
], ],
), ),
new TestSemantics( new TestSemantics(
id: 39, id: 40,
rect: new Rect.fromLTRB(0.0, 0.0, 120.0, 20.0), rect: new Rect.fromLTRB(0.0, 0.0, 120.0, 20.0),
transform: new Matrix4.translation(new Vector3(0.0, 544.0, 0.0)), transform: new Matrix4.translation(new Vector3(0.0, 544.0, 0.0)),
tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling], tags: <SemanticsTag>[RenderSemanticsGestureHandler.excludeFromScrolling],
......
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