Skip to content

fix: allow page routes to opt out of route semantics - #182556

Closed
haashem wants to merge 9 commits into
flutter:masterfrom
haashem:fix-168915
Closed

haashem wants to merge 9 commits into
flutter:masterfrom
haashem:fix-168915

Conversation

@haashem

@haashem haashem commented Feb 18, 2026

Copy link
Copy Markdown

This PR addresses issue where selected tab is not announced by VoiceOver. When the route changes due to switching between tabs, iOS was still getting a screen-changed notification when a route change has no route name, which can suppress the selected-tab VoiceOver announcement.

iOS Behavior:

Shortcuts App
ScreenRecording_02-17-2026.21-25-37_1.MP4
Before After
before.MP4
after.mov

Resolves #168915

Test Scenario:

1- Build screen version 1: it has a route with no name, and one item.
2- Put focus on that item.
3- Apply UpdateSemantics
4- Clear previously captured notifications.
5- Build screen version 2: route changes to another route with no name, but same focused item stays.
6- Apply another UpdateSemantics

Expected result:

  • Only one notification is sent.
  • It is UIAccessibilityLayoutChangedNotification.
  • Its argument is NSNull (so no route name is spoken).

Pre-launch Checklist

@haashem
haashem requested a review from a team as a code owner February 18, 2026 19:11
@github-actions github-actions Bot added platform-ios iOS applications specifically engine flutter/engine related. See also e: labels. a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) team-ios Owned by iOS platform team labels Feb 18, 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 addresses an accessibility issue on iOS where VoiceOver announcements for tab selections were being suppressed. The change modifies accessibility_bridge.mm to prevent sending a screen-changed notification when a route change involves an unnamed route. This is achieved by checking if the route name has a positive length before posting the notification. A new test case has been added in accessibility_bridge_test.mm to verify this new behavior.

ios_delegate_->PostAccessibilityNotification(
UIAccessibilityLayoutChangedNotification,
(routeChanged || next != lastFocused) ? next.nativeAccessibility : NULL);
(shouldAnnounceRoute || next != lastFocused) ? next.nativeAccessibility : NULL);

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.

medium

This change from routeChanged to shouldAnnounceRoute is correct for the fix. However, it makes the comment on lines 224-226 slightly outdated. The comment states, 'If there is a route change, we always refocus,' but with this change, refocusing only happens for named route changes. It would be beneficial to update the comment to reflect this new behavior to prevent future confusion.

@chunhtai
chunhtai self-requested a review February 18, 2026 22:52
@chunhtai
chunhtai self-requested a review February 25, 2026 22:49
@vashworth
vashworth requested a review from LouiseHsu February 26, 2026 22:25
@chunhtai

Copy link
Copy Markdown
Contributor

This is still in my review list. will get to it soon

@hellohuanlin

hellohuanlin commented Mar 26, 2026 •

Copy link
Copy Markdown
Contributor

from triage: @chunhtai do you have time to take another look? thanks

@chunhtai

Copy link
Copy Markdown
Contributor

still in my queue, will take a look today or tmr

@zywek123

zywek123 commented Apr 9, 2026

Copy link
Copy Markdown

The last after messes up VoiceOver audio playback when switching between screens. Navigator.push and Navigator.pop would naturally send events about transitioning between screens or something similar, which is the case in every native app on iOS, just to at least open any app or open new settings screens.

@okorohelijah

Copy link
Copy Markdown
Contributor

from triage: @chunhtai is this still on your radar?

@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 a suggestion

@zywek123

Copy link
Copy Markdown

Is there any chance we could look into 3-finger scrolling while we're modifying this code?
There's no sound and no feedback at all. if #22747 fixes this, so not works.
No Message "Showing items 1 to 10 of 50"
No message "Page 1 of 20"
Use three fingers up or down gestures with VO turned on to reproduce.
I was able to reproduce it in 3.41.6

@chunhtai chunhtai added the waiting for response The Flutter team cannot make further progress on this issue until the original reporter responds label Apr 22, 2026
@haashem

haashem commented May 1, 2026

Copy link
Copy Markdown
Author

@chunhtai Thanks for the suggestion. I updated the fix, and it now covers these cases:

  1. Tab switch: does not post UIAccessibilityScreenChangedNotification, which fixes the original bug, announces the tab is selected.
  2. Navigator.push of an unnamed route: posts UIAccessibilityScreenChangedNotification with a nil argument, so iOS can choose a focusable element on the new screen. This is covered by a new regression test.
  3. Named route push/pop: keeps the existing behavior.

Here is the result:

ScreenRecording_05-01-2026.22-10-11_1.MP4

@github-actions github-actions Bot removed the waiting for response The Flutter team cannot make further progress on this issue until the original reporter responds label May 1, 2026
@haashem
haashem requested a review from chunhtai May 9, 2026 22:17
@chunhtai
chunhtai self-requested a review May 13, 2026 20:51
@zywek123

Copy link
Copy Markdown

For example, a route change should be emitted if you swipe left with three fingers to scroll the TabBar content to another page. But that’s a different issue and probably a different PR, which is unlikely to happen.

@github-actions github-actions Bot added p: material_ui material_ui package in flutter/packages p: cupertino_ui cupertino_ui package in flutter/packages f: routes Navigator, Router, and related APIs. labels May 19, 2026
@dkwingsmt

dkwingsmt commented May 27, 2026 •

Copy link
Copy Markdown
Contributor

Gentle nudge @chunhtai (from triage) Your comments have been replied.

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

code lgtm, just some comment on the doc

Comment thread packages/flutter/lib/src/widgets/pages.dart
Comment thread packages/flutter/lib/src/widgets/pages.dart Outdated
@haashem haashem changed the title fix: [iOS] [a11y] Skip unnamed route screen-change announcements fix: allow page routes to opt out of route semantics Jun 2, 2026
@dkwingsmt
dkwingsmt requested a review from chunhtai June 3, 2026 18:35
chunhtai
chunhtai previously approved these changes Jun 11, 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, left a minor comment

Comment thread packages/flutter/lib/src/widgets/pages.dart Outdated
@chunhtai
chunhtai requested a review from hannah-hyj June 11, 2026 18:08
@chunhtai

Copy link
Copy Markdown
Contributor

oh didn't realize this was affected by code freeze. In that case we should wait until the code freeze is lifted and migrate this pr to the material_ui and cupertino_ui library

@chunhtai

Copy link
Copy Markdown
Contributor

converting this to draft

@chunhtai
chunhtai marked this pull request as draft June 11, 2026 18:09
@chunhtai chunhtai added the waiting for code freeze This PR is waiting for a code freeze to resolve. label Jun 11, 2026
@Piinks Piinks added the Decoupling: Not ready to port yet Instructions will be provided when this is ready to move to flutter/packages. label Jun 24, 2026
@Piinks

Piinks commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

I've marked this PR as not ready to port to flutter/packages yet.
We'll provide instructions to move this change over to material_ui/cupertino_ui once ready to receive PRs. Thank you!

The changes not in the material or cupertino libraries will remain here.

@Piinks Piinks added the Decoupling: Split PR The PR will need to be split to separate Material & Cupertino changes label Jun 25, 2026
@Piinks

Piinks commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Advice for PR splitting: Since this touches material/cupertino along with other parts of flutter/flutter, it will need to be split up.

If the material/cupertino changes are dependent on the other non-material/cupertino changes in this PR, then the material/cupertino changes will need to wait for them to roll to stable before they can be ported over to material_ui/cupertino_ui in flutter/packages (which uses the stable branch).

  • If that is the case here, consider opening a new PR with the non-material/cupertino changes to move forward with so that waiting period can be reduced. Up to you!

@Piinks

Piinks commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

If you would like to return to this, material_ui and cupertino_ui are now accepting contributions. :)

The portions of this PR that affect the material and cupertino libraries can be ported over to flutter/packages, although they may have to wait for the changes in the core SDK to land here and reach stable first.

Guidance and instructions for easily porting over can be found in #188444

@Piinks Piinks added Decoupling: Port to flutter/packages This PR is ready to be ported to flutter/packages. We will provide instructions to do so. and removed Decoupling: Not ready to port yet Instructions will be provided when this is ready to move to flutter/packages. labels Aug 18, 2026
@haashem

haashem commented Aug 28, 2026

Copy link
Copy Markdown
Author

I created direct PR for Material and Cupertino libraries:
flutter/packages#12674

@haashem

haashem commented Sep 10, 2026

Copy link
Copy Markdown
Author

And finally the is fix is now merged to the Material and Cupertino UI libraries.

flutter/packages#12674

Thanks everyone on helping me resolve the issue.

Closing this PR now.

@haashem haashem closed this Sep 10, 2026
mboetger pushed a commit to mboetger/flutter that referenced this pull request Sep 10, 2026
…er#192550)

flutter/packages@36e088a...8a35b16

2026-09-10 [email protected] [material_ui]
Migrate M3 buttons template to use new gen_defaults
(flutter/packages#12744)
2026-09-09 [email protected] [cupertino_ui]Add awaitNotRequired to
Future-returning callsites without await (flutter/packages#12817)
2026-09-09 [email protected] [material_ui] Add awaitNotRequired
annotation to material_ui (flutter/packages#12622)
2026-09-09 [email protected] [image_picker] Add native tests
for photo-library access and UIImagePicker completion
(flutter/packages#12540)
2026-09-09 [email protected] [material_ui][cupertino_ui] allow page
routes to opt out of route semantics - flutter#182556 (flutter/packages#12674)
2026-09-09 [email protected] [image_picker] Add native tests
for pick results, camera access, and presentation
(flutter/packages#12539)
2026-09-09 [email protected] [cupertino_ui] Fix platform view sheet
transitions (flutter/packages#12565)
2026-09-09 [email protected]
[camera_android_camerax] Bump cameraxVersion to 1.6.2, remove
concurrent-futures workaround (flutter/packages#12698)
2026-09-09 [email protected] `[material_ui]`
replace identical checks with equality when dealing with enums
(flutter/packages#12633)
2026-09-09 [email protected] Roll Flutter from
b444e78 to 63b9518 (21 revisions) (flutter/packages#12814)
2026-09-09 [email protected]
`[cupertino_ui]` replace identical checks with equality when dealing
with enums (flutter/packages#12632)
2026-09-09 [email protected] [pigeon] add support for multiple swift
outputs (flutter/packages#12720)

If this roll has caused a breakage, revert this CL and set the roller
to dry run mode using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC [email protected] on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Decoupling: Port to flutter/packages This PR is ready to be ported to flutter/packages. We will provide instructions to do so. Decoupling: Split PR The PR will need to be split to separate Material & Cupertino changes f: routes Navigator, Router, and related APIs. framework flutter/packages/flutter repository. See also f: labels. p: cupertino_ui cupertino_ui package in flutter/packages p: material_ui material_ui package in flutter/packages waiting for code freeze This PR is waiting for a code freeze to resolve.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[go_router] Voice over drops reading BottomNavigationBar selected tab when it becomes selected

8 participants