genUiSemantics function

List<GenUiSemanticNode> genUiSemantics(
  1. SemanticsNode root
)

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;
}