Skip to content

[framework] Keep scrollable semantics role stable#187963

Merged
auto-submit[bot] merged 5 commits into
flutter:masterfrom
flutter-zl:issue_182122_textfield_focus
Jul 1, 2026
Merged

[framework] Keep scrollable semantics role stable#187963
auto-submit[bot] merged 5 commits into
flutter:masterfrom
flutter-zl:issue_182122_textfield_focus

Conversation

@flutter-zl

@flutter-zl flutter-zl commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Fixes #182122

Problem
On Flutter Web with a screen reader, typing into a TextField inside a scroll view can silently fail. During transient semantics updates before scroll dimensions are ready, the framework omitted hasImplicitScrolling, so web briefly classified the scroll node as generic and rebuilt DOM above the focused input.

Fix
Always set hasImplicitScrolling when describing the scroll semantics node, so its scrollable identity stays stable. Measured scroll fields still wait for position.haveDimensions.

Demo

Before: https://flutter-demo-40-before.web.app
After: https://flutter-demo-40-after.web.app

Steps: turn VoiceOver on, focus the text field, then type.
Before: the field stays empty. After: text enters normally.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 12, 2026
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) f: scrolling Viewports, list views, slivers, etc. platform-web Web applications specifically team-web Owned by Web platform team labels Jun 12, 2026

@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 enables the reuse of the host <flt-semantics> element when transitioning between generic and scrollable semantic roles to prevent losing focus on descendant elements. It also updates style property cleanup to use kebab-case and adds a test verifying this behavior. The reviewer suggests simplifying the implementation by removing the redundant _disposeBehaviorsForElementReuse() method, as the behaviors are already disposed of when the old semantic role is disposed.

Comment thread engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart Outdated
Comment thread engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart Outdated
@flutter-zl
flutter-zl requested review from chunhtai and mdebbar June 12, 2026 23:44
@mdebbar

mdebbar commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

I fixed this exact issue last year: #164491, but maybe my fix wasn't enough, or something broke since then?

I still prefer that we correctly detect the "scroll" role so we don't flip flop roles. If the scroll view is always present in the framework, then the semantics role should always remain "scroll". Can we pin-point why our detection is failing and falling back to the "generic" role?

@github-actions github-actions Bot added framework flutter/packages/flutter repository. See also f: labels. and removed engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team CICD Run CI/CD labels Jun 17, 2026
@flutter-zl flutter-zl changed the title [web] Reuse host element on scrollable/generic role change [framework] Keep scrollable semantics role stable Jun 17, 2026
@flutter-zl

Copy link
Copy Markdown
Contributor Author

I fixed this exact issue last year: #164491, but maybe my fix wasn't enough, or something broke since then?

I still prefer that we correctly detect the "scroll" role so we don't flip flop roles. If the scroll view is always present in the framework, then the semantics role should always remain "scroll". Can we pin-point why our detection is failing and falling back to the "generic" role?

Good catch. #164491 was still right.

The missing piece was that the framework only set hasImplicitScrolling after position.haveDimensions, so web could briefly lose the scroll signal and fall back to generic.

Updated the PR to always set hasImplicitScrolling; measured scroll fields still wait for dimensions.

@mdebbar

mdebbar commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

LGTM but I'll defer to @chunhtai to make the final call.

@chunhtai chunhtai 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.

The change itself seems fine according to the hasImplicitScrolling, but is the problem that a transient state may break a a textfield inside a semantics scrollable? if that is the case won't this only fix this specific case?

what if someone does

SemanticsRenderObject(
  hasImplicitScrolling: _toggle,
  child: TextField()
)
class RenderSemanticsRenderObject extend RenderProxyBox{

  bool hasImplicitScrolling; // set by SemanticsRenderObject

  @override
  void describeSemanticsConfiguration(config) {
    config.hasImplicitScrolling = hasImplicitScrolling
  }

}

@flutter-zl
flutter-zl requested a review from chunhtai June 25, 2026 19:11
@flutter-zl

Copy link
Copy Markdown
Contributor Author

The change itself seems fine according to the hasImplicitScrolling, but is the problem that a transient state may break a a textfield inside a semantics scrollable? if that is the case won't this only fix this specific case?

what if someone does

SemanticsRenderObject(
  hasImplicitScrolling: _toggle,
  child: TextField()
)
class RenderSemanticsRenderObject extend RenderProxyBox{

  bool hasImplicitScrolling; // set by SemanticsRenderObject

  @override
  void describeSemanticsConfiguration(config) {
    config.hasImplicitScrolling = hasImplicitScrolling
  }

}

Good catch. But I think that case is a separate web robustness issue.

If a custom render object intentionally toggles hasImplicitScrolling, web may still need to handle focus preservation better, but I’d treat that as a separate engine fix.

@chunhtai chunhtai 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.

left some questions about the test, the code LGTM

@override
bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) {
_applyingContentDimensions = true;
try {

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.

why a try catch in the test? test should be as deterministic as possible

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. simplified it.

bool _applyingContentDimensions = false;

@override
bool get haveDimensions => _applyingContentDimensions && super.haveDimensions;

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.

as the name apply, should shouldn't this always return false?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch, the old name was confusing. I renamed it to make the intent clearer.

@flutter-zl
flutter-zl requested a review from chunhtai June 26, 2026 17:59
@flutter-zl flutter-zl added the CICD Run CI/CD label Jun 26, 2026

@chunhtai chunhtai 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.

LGTM

@flutter-zl flutter-zl added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 29, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 29, 2026
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jul 1, 2026
This was referenced Jul 1, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Jul 8, 2026
…12135)

Manual roll Flutter from ca9f874f5284 to 6995038d96ef (44 revisions)

Manual roll requested by [email protected]

flutter/flutter@ca9f874...6995038

2026-07-03 [email protected] Roll Fuchsia Linux SDK from sx_eN0J_f2BV6jqjW... to Jr08vyeibMSv3Oxst... (flutter/flutter#188946)
2026-07-03 [email protected] Roll Packages from 420e135 to 2fbe873 (1 revision) (flutter/flutter#188945)
2026-07-03 [email protected] Roll Dart SDK from 786212a2ce0d to 1f9a08ce0638 (4 revisions) (flutter/flutter#188944)
2026-07-03 [email protected] Roll Skia from 5358ab75b840 to 919956953af6 (7 revisions) (flutter/flutter#188943)
2026-07-02 [email protected] [Windows] Keep regular windows in place when another is activated (flutter/flutter#188016)
2026-07-02 [email protected] [flutter_tools] Provide guided message when iOS/macOS build fails due to low minimum version (flutter/flutter#188812)
2026-07-02 [email protected] [Flutter GPU] Load a ShaderLibrary from shader bundle bytes (flutter/flutter#188596)
2026-07-02 [email protected] [tool] Enable record_use experiment by default on all channels (flutter/flutter#188887)
2026-07-02 [email protected] Roll Packages from e742106 to 420e135 (13 revisions) (flutter/flutter#188916)
2026-07-02 [email protected] Roll Fuchsia Linux SDK from I2h2eXk06RrA3pIG2... to sx_eN0J_f2BV6jqjW... (flutter/flutter#188915)
2026-07-02 [email protected] Clarify layout callback debug flag docs (flutter/flutter#186879)
2026-07-02 [email protected] Roll Skia from 0c4faca350cc to 5358ab75b840 (2 revisions) (flutter/flutter#188899)
2026-07-02 [email protected] Roll Dart SDK from e47361c7fe9a to 786212a2ce0d (2 revisions) (flutter/flutter#188898)
2026-07-01 [email protected] Roll Skia from 0fc8ba72e802 to 0c4faca350cc (2 revisions) (flutter/flutter#188886)
2026-07-01 [email protected] Hide draft PRs from the triage list (flutter/flutter#188885)
2026-07-01 [email protected] Stricten isSemantics and matchesSemantics children mismatch check (flutter/flutter#188827)
2026-07-01 [email protected] [AGP 9] Support Enabling Built-in Kotlin (flutter/flutter#188543)
2026-07-01 [email protected] Roll Skia from d19e557ac317 to 0fc8ba72e802 (4 revisions) (flutter/flutter#188879)
2026-07-01 [email protected] [ci] Increase test timeout for Mac_x64 build_tests shards (flutter/flutter#188804)
2026-07-01 [email protected] Roll Skia from bd4ae38ca3bb to d19e557ac317 (1 revision) (flutter/flutter#188865)
2026-07-01 [email protected] Roll Dart SDK from 26d723eb89af to e47361c7fe9a (5 revisions) (flutter/flutter#188864)
2026-07-01 [email protected] Update triage links for material_ui and cupertino_ui --> Design triage (flutter/flutter#188567)
2026-07-01 [email protected] [Impeller] Share a single ContextGLES among all PlaygroundImplGLES (flutter/flutter#188080)
2026-07-01 [email protected] Use null-aware elements in dev/devicelab/lib/integration_tests.dart (flutter/flutter#187852)
2026-07-01 [email protected] Roll Packages from 274ed3e to e742106 (18 revisions) (flutter/flutter#188863)
2026-07-01 [email protected] Add android 17 to embedding (flutter/flutter#187965)
2026-07-01 [email protected] Adds semantics role check to isSemantics and matchesSemantics (flutter/flutter#188825)
2026-07-01 [email protected] Roll Dart SDK from e1bdb9ce3327 to 26d723eb89af (3 revisions) (flutter/flutter#188795)
2026-07-01 [email protected] [web] Apply autocapitalize to text editing elements (flutter/flutter#188351)
2026-07-01 [email protected] Roll Fuchsia Linux SDK from RymJjIj7dd5vQ3Cnh... to I2h2eXk06RrA3pIG2... (flutter/flutter#188852)
2026-07-01 [email protected] [Impeller] Compute dispatch takes 3D workgroup counts and honors the shader local_size (flutter/flutter#188601)
2026-07-01 [email protected] Improve stylus support on linux (flutter/flutter#186831)
2026-07-01 [email protected] Resolve issue  Catch am start failures with 'Error type' and prevent hang (flutter/flutter#187196)
2026-07-01 [email protected] Roll Skia from ef178c9898af to bd4ae38ca3bb (3 revisions) (flutter/flutter#188834)
2026-07-01 [email protected] Roll Skia from 3ac99be47229 to ef178c9898af (3 revisions) (flutter/flutter#188831)
2026-07-01 [email protected] Add a macosArm64Only feature flag (flutter/flutter#188598)
2026-07-01 [email protected] Roll Skia from 15302f1625b2 to 3ac99be47229 (1 revision) (flutter/flutter#188819)
2026-07-01 [email protected] [flutter_tools] Track asset transformer dependencies for hot reload (Reland #187947) (flutter/flutter#188808)
2026-06-30 [email protected] Add TapRegion samples (flutter/flutter#188685)
2026-06-30 [email protected] Print a warning in `flutter doctor` when running on Intel Macs (flutter/flutter#188760)
2026-06-30 [email protected] [framework] Keep scrollable semantics role stable (flutter/flutter#187963)
2026-06-30 [email protected] feat(skills): Add shepherd-prs skill for managing approved external contributor PRs (flutter/flutter#188534)
2026-06-30 [email protected] Roll Skia from 71947c4110b0 to 15302f1625b2 (17 revisions) (flutter/flutter#188815)
2026-06-30 [email protected] [Tool] Run re-entrant upgrade in original CWD (flutter/flutter#188794)
...
kalyujniy pushed a commit to brickit-app/camera that referenced this pull request Jul 8, 2026
…lutter#12135)

Manual roll Flutter from ca9f874f5284 to 6995038d96ef (44 revisions)

Manual roll requested by [email protected]

flutter/flutter@ca9f874...6995038

2026-07-03 [email protected] Roll Fuchsia Linux SDK from sx_eN0J_f2BV6jqjW... to Jr08vyeibMSv3Oxst... (flutter/flutter#188946)
2026-07-03 [email protected] Roll Packages from 420e135 to 2fbe873 (1 revision) (flutter/flutter#188945)
2026-07-03 [email protected] Roll Dart SDK from 786212a2ce0d to 1f9a08ce0638 (4 revisions) (flutter/flutter#188944)
2026-07-03 [email protected] Roll Skia from 5358ab75b840 to 919956953af6 (7 revisions) (flutter/flutter#188943)
2026-07-02 [email protected] [Windows] Keep regular windows in place when another is activated (flutter/flutter#188016)
2026-07-02 [email protected] [flutter_tools] Provide guided message when iOS/macOS build fails due to low minimum version (flutter/flutter#188812)
2026-07-02 [email protected] [Flutter GPU] Load a ShaderLibrary from shader bundle bytes (flutter/flutter#188596)
2026-07-02 [email protected] [tool] Enable record_use experiment by default on all channels (flutter/flutter#188887)
2026-07-02 [email protected] Roll Packages from e742106 to 420e135 (13 revisions) (flutter/flutter#188916)
2026-07-02 [email protected] Roll Fuchsia Linux SDK from I2h2eXk06RrA3pIG2... to sx_eN0J_f2BV6jqjW... (flutter/flutter#188915)
2026-07-02 [email protected] Clarify layout callback debug flag docs (flutter/flutter#186879)
2026-07-02 [email protected] Roll Skia from 0c4faca350cc to 5358ab75b840 (2 revisions) (flutter/flutter#188899)
2026-07-02 [email protected] Roll Dart SDK from e47361c7fe9a to 786212a2ce0d (2 revisions) (flutter/flutter#188898)
2026-07-01 [email protected] Roll Skia from 0fc8ba72e802 to 0c4faca350cc (2 revisions) (flutter/flutter#188886)
2026-07-01 [email protected] Hide draft PRs from the triage list (flutter/flutter#188885)
2026-07-01 [email protected] Stricten isSemantics and matchesSemantics children mismatch check (flutter/flutter#188827)
2026-07-01 [email protected] [AGP 9] Support Enabling Built-in Kotlin (flutter/flutter#188543)
2026-07-01 [email protected] Roll Skia from d19e557ac317 to 0fc8ba72e802 (4 revisions) (flutter/flutter#188879)
2026-07-01 [email protected] [ci] Increase test timeout for Mac_x64 build_tests shards (flutter/flutter#188804)
2026-07-01 [email protected] Roll Skia from bd4ae38ca3bb to d19e557ac317 (1 revision) (flutter/flutter#188865)
2026-07-01 [email protected] Roll Dart SDK from 26d723eb89af to e47361c7fe9a (5 revisions) (flutter/flutter#188864)
2026-07-01 [email protected] Update triage links for material_ui and cupertino_ui --> Design triage (flutter/flutter#188567)
2026-07-01 [email protected] [Impeller] Share a single ContextGLES among all PlaygroundImplGLES (flutter/flutter#188080)
2026-07-01 [email protected] Use null-aware elements in dev/devicelab/lib/integration_tests.dart (flutter/flutter#187852)
2026-07-01 [email protected] Roll Packages from 274ed3e to e742106 (18 revisions) (flutter/flutter#188863)
2026-07-01 [email protected] Add android 17 to embedding (flutter/flutter#187965)
2026-07-01 [email protected] Adds semantics role check to isSemantics and matchesSemantics (flutter/flutter#188825)
2026-07-01 [email protected] Roll Dart SDK from e1bdb9ce3327 to 26d723eb89af (3 revisions) (flutter/flutter#188795)
2026-07-01 [email protected] [web] Apply autocapitalize to text editing elements (flutter/flutter#188351)
2026-07-01 [email protected] Roll Fuchsia Linux SDK from RymJjIj7dd5vQ3Cnh... to I2h2eXk06RrA3pIG2... (flutter/flutter#188852)
2026-07-01 [email protected] [Impeller] Compute dispatch takes 3D workgroup counts and honors the shader local_size (flutter/flutter#188601)
2026-07-01 [email protected] Improve stylus support on linux (flutter/flutter#186831)
2026-07-01 [email protected] Resolve issue  Catch am start failures with 'Error type' and prevent hang (flutter/flutter#187196)
2026-07-01 [email protected] Roll Skia from ef178c9898af to bd4ae38ca3bb (3 revisions) (flutter/flutter#188834)
2026-07-01 [email protected] Roll Skia from 3ac99be47229 to ef178c9898af (3 revisions) (flutter/flutter#188831)
2026-07-01 [email protected] Add a macosArm64Only feature flag (flutter/flutter#188598)
2026-07-01 [email protected] Roll Skia from 15302f1625b2 to 3ac99be47229 (1 revision) (flutter/flutter#188819)
2026-07-01 [email protected] [flutter_tools] Track asset transformer dependencies for hot reload (Reland #187947) (flutter/flutter#188808)
2026-06-30 [email protected] Add TapRegion samples (flutter/flutter#188685)
2026-06-30 [email protected] Print a warning in `flutter doctor` when running on Intel Macs (flutter/flutter#188760)
2026-06-30 [email protected] [framework] Keep scrollable semantics role stable (flutter/flutter#187963)
2026-06-30 [email protected] feat(skills): Add shepherd-prs skill for managing approved external contributor PRs (flutter/flutter#188534)
2026-06-30 [email protected] Roll Skia from 71947c4110b0 to 15302f1625b2 (17 revisions) (flutter/flutter#188815)
2026-06-30 [email protected] [Tool] Run re-entrant upgrade in original CWD (flutter/flutter#188794)
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) CICD Run CI/CD f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flutter Web VoicerOver breaks on TextField when a Theme extension is set

3 participants