Skip to content

[A11y] Add semantics tree UI - #9982

Open
hannah-hyj wants to merge 2 commits into
flutter:masterfrom
hannah-hyj:a11y_tree_visualizer
Open

[A11y] Add semantics tree UI#9982
hannah-hyj wants to merge 2 commits into
flutter:masterfrom
hannah-hyj:a11y_tree_visualizer

Conversation

@hannah-hyj

@hannah-hyj hannah-hyj commented Aug 27, 2026

Copy link
Copy Markdown
Member

tracking issue: #9893
Added the tree UI
Screenshot 2026-08-27 at 16 59 03

Pre-launch Checklist

General checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read the Flutter Style Guide recently, and have followed its advice.
  • I signed the CLA.
  • I updated/added relevant documentation (doc comments with ///).

Issues checklist

Tests checklist

  • I added new tests to check the change I am making...
  • OR there is a reason for not adding tests, which I explained in the PR description.

AI-tooling checklist

  • I did not use any AI tooling in creating this PR.
  • OR I did use AI tooling, and...
    • I read the AI contributions guidelines and agree to follow them.
    • I reviewed all AI-generated code before opening this PR.
    • I understand and am able to discuss the code in this PR.
    • I have verifed the accuracy of any AI-generated text included in the PR description.
    • I commit to verifying the accuracy of any AI-generated code or text that I upload in response to review comments.

Feature-change checklist

  • This PR does not change the DevTools UI or behavior and...
    • I added the release-notes-not-required label or left a comment requesting the label be added.
  • OR this PR does change the DevTools UI or behavior and...
    • I added an entry to packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md.
    • I included before/after screenshots and/or a GIF demo of the new UI to my PR description.
    • I ran the DevTools app locally to manually verify my changes.

build.yaml badge

If you need help, consider asking for help on Discord.

@hannah-hyj
hannah-hyj requested a review from a team as a code owner August 27, 2026 06:12
@hannah-hyj
hannah-hyj requested review from srawlins and removed request for a team and srawlins August 27, 2026 06:12

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the accessibility semantics tree in DevTools, adding the SemanticsNodeModel to represent nodes, updating AccessibilityController to load and parse the tree via service extensions, and introducing the AccessibilitySemanticsTreePane UI along with comprehensive tests. The review feedback highlights several critical issues: a recursive parsing bug in _parseSemanticsNode that leads to duplicate child nodes, the use of a non-existent disposeSemantics service extension (which should be replaced with disabling enableSemantics), and the use of an invalid isCheckable flag which should be updated to hasCheckedState.

Comment thread packages/devtools_app/lib/src/screens/accessibility/accessibility_controller.dart Outdated

@srawlins srawlins left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice tests; I haven't quite looked at everything yet, but do you want to look at gemini's feedback and give each a thumbs up or down?

/// The current value of this node (e.g. the text in a text field).
final String value;

/// Additional hint text spoken after a delay (maps to `SemanticsData.hint`).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we link with [SemanticsData.hint]? If it is not imported, we can /// @docImport it.

@hannah-hyj

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the accessibility semantics tree view in DevTools. It introduces the SemanticsNodeModel to represent nodes in the semantics tree, adds logic to AccessibilityController to load, parse, and dispose of the semantics tree via service extensions, and replaces the placeholder AccessibilitySemanticsTreePane with a fully functional tree view UI (including empty, loading, and error states). Comprehensive unit and widget tests are also added. Feedback on the pull request suggests ensuring that stale semantics tree data and error states are cleared when the main isolate becomes null (e.g., when the application is disconnected).

Comment on lines +135 to +147
addAutoDisposeListener(
serviceConnection.serviceManager.isolateManager.mainIsolate,
() {
if (serviceConnection.serviceManager.isolateManager.mainIsolate.value !=
null) {
// Clear stale data from a previous isolate so the guard in
// _autoLoadSemanticsTreeIfNeeded doesn't skip the new load.
semanticsRoots.value = [];
semanticsTreeError.value = null;
unawaited(_autoLoadSemanticsTreeIfNeeded());
}
},
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

[MUST-FIX] When the main isolate becomes null (e.g., if the application is disconnected or stopped), the listener does not clear the semantics tree or error state. This can lead to stale data from the previous session being displayed in the UI.

Please add an else block to clear semanticsRoots and semanticsTreeError when mainIsolate.value is null.

    addAutoDisposeListener(
      serviceConnection.serviceManager.isolateManager.mainIsolate,
      () {
        if (serviceConnection.serviceManager.isolateManager.mainIsolate.value !=
            null) {
          // Clear stale data from a previous isolate so the guard in
          // _autoLoadSemanticsTreeIfNeeded doesn't skip the new load.
          semanticsRoots.value = [];
          semanticsTreeError.value = null;
          unawaited(_autoLoadSemanticsTreeIfNeeded());
        } else {
          semanticsRoots.value = [];
          semanticsTreeError.value = null;
        }
      },
    );

@hannah-hyj
hannah-hyj requested a review from srawlins August 28, 2026 00:23
@hannah-hyj
hannah-hyj force-pushed the a11y_tree_visualizer branch from 9e12ba6 to b4da3ce Compare August 28, 2026 00:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants