genUiSemantics function
The meaningful part of root, in traversal order.
Nodes a platform adds to lay things out carry no name, value, role or action; they differ between platforms for reasons that have nothing to do with the surface, and are left out. What remains is what a screen reader user actually moves through.
Implementation
List<GenUiSemanticNode> genUiSemantics(SemanticsNode root) {
final result = <GenUiSemanticNode>[];
void walk(SemanticsNode node) {
final SemanticsData data = node.getSemanticsData();
final List<String> actions = <String>[
for (final action in SemanticsAction.values)
if (data.hasAction(action)) action.name,
];
final String role = _roleOf(data);
final bool carriesMeaning =
data.label.isNotEmpty ||
data.value.isNotEmpty ||
data.tooltip.isNotEmpty ||
role != 'group' ||
actions.isNotEmpty;
if (carriesMeaning) {
result.add(
GenUiSemanticNode(
role: role,
name: data.label,
value: data.value,
tooltip: data.tooltip,
state: _stateOf(data),
actions: actions,
),
);
}
node.visitChildren((SemanticsNode child) {
// A merged child is already part of the node above it; counting it twice
// would report two stops where a user finds one.
if (!child.isMergedIntoParent) walk(child);
return true;
});
}
walk(root);
return result;
}