Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: flutter/flutter
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 5fc346839b5d
Choose a base ref
...
head repository: flutter/flutter
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: abaf9c523780
Choose a head ref
  • 3 commits
  • 8 files changed
  • 3 contributors

Commits on Oct 7, 2026

  1. [stable] [iOS] Preserve semantics parents after reparenting (#189686)…

    … + Fix OverlayPortal semantics bounds corruption (#192139) (#193420)
    
    Cherry-picks #189686 and #192139 into `flutter-3.47-candidate.0` (stable). Both applied cleanly with `git cherry-pick -x`; both touch only `SemanticsObject.mm` (+ tests).
    
    ### Issue Link
    #182604 · #100946
    
    ### Impacted Users
    End users of iOS apps built with stable who rely on VoiceOver / Switch Control, and teams driving XCUITest / Maestro against Flutter apps. Any route that mounts a Material `Slider` is affected out of the box: `Slider` keeps its value-indicator `OverlayPortal` shown from construction (`slider.dart`: `OverlayPortalController(...)..show()`), so no popover, menu or reorder is needed to trigger it.
    
    ### Impact Description
    Since fccfa97 an `OverlayPortal` child has a different parent in traversal order and in hit-test order. The iOS accessibility bridge overwrote the native `SemanticsObject.parent` with the hit-test one (and cleared parents of moved children), so the parent chain used to compute `accessibilityFrame` no longer reaches the root: every element of the route reports a frame scaled by 1/devicePixelRatio (exactly 1/3 on a 3x device) and anchored top-left. VoiceOver touch exploration focuses the wrong place; `XCUIElement.tap()` misses the visible control. Measured on iPhone 16 Pro Max / iOS 26.7 with Flutter 3.44.8 (stable 3.47.5 has the same `SemanticsObject.mm`): a full-width CTA laid out at `{{32, 834}, {376, 56}}` is published as `{{10.7, 278.0}, {125.3, 18.7}}`; a player route with a `Slider` is 1/3 from its first frame. The corruption persists after the portal unmounts and after background/foreground.
    
    ### Changelog Description
    [flutter/182604](#182604) When a route shows an `OverlayPortal` on iOS (including any Material `Slider`), accessibility frames are shrunk by the device pixel ratio and anchored to the top-left, so VoiceOver focus and XCUITest taps miss the visible controls.
    
    ### Workaround
    Replace Material `Slider` with `CupertinoSlider` (no `OverlayPortal`) on affected routes and avoid `OverlayPortal` altogether. Not viable for apps using Material menus / dropdowns or third-party popovers.
    
    ### Risk
    Low. Parent bookkeeping only: #189686 clears `child.parent` only when the object still owns it; #192139 stops the hit-test-order setter from mutating `parent`. No behaviour change when traversal and hit-test parents coincide.
    
    ### Cherry-pick diff composition
    
    The two upstream PRs touch the same function, so the composed diff on `SemanticsObject.mm` (`+6 -8`) matches neither of them individually — upstream, #189686 is `+9 -3` on this file and #192139 is `+0 -8`. Net against the `flutter-3.47-candidate.0` base:
    
    | site | net effect vs. base |
    |---|---|
    | `dealloc` | `+3 -1` — guard becomes `if (child.parent == self) { child.parent = nil; }` |
    | `setChildren` | `+3 -1` — same guard |
    | `setChildrenInHitTestOrder` | `-6` — #189686 adds the guard here too, then #192139 deletes both parent loops outright, so those 3 added lines never survive and the block's 6 original lines go away |
    
    Additions `3 + 3 = 6`; deletions `1 + 1 + 6 = 8`. The three "missing" additions are the ones the second commit removes from the first. No conflict was resolved by hand — both applied cleanly with `git cherry-pick -x`.
    
    ### Test Coverage
    Yes. #189686 adds an iOS XCUITest (`testReorderableListAccessibilityHierarchyUpdates`) asserting the accessibility frame after reparenting; #192139 adds `SemanticsObjectTest.mm` coverage. Both have been on master since 2026-09-01/03 and ship in beta 3.49.0-0.1.pre.
    
    ### Validation Steps
    1. On a 3x iOS device, push a route (e.g. `MaterialApp.router` + `GoRoute`) whose body contains a Material `Slider`.
    2. Print `XCUIApplication().debugDescription` from an XCUITest, or inspect with Accessibility Inspector.
    3. Before: every element of the route reports a frame at 1/3 of its logical size near (0,0). After: frames match the visible layout, and `XCUIElement.tap()` / VoiceOver touch exploration hit the visible controls.
    JoX23 authored Oct 7, 2026
    Configuration menu
    Copy the full SHA
    deb2874 View commit details
    Browse the repository at this point in the history
  2. Update changelog for the single CP for this stable hotfix release. (#…

    …193959)
    
    Updates the changelog for the 3.47.7 stable hotfix release. The only cherry pick was #193420.
    justinmc authored Oct 7, 2026
    Configuration menu
    Copy the full SHA
    632f36e View commit details
    Browse the repository at this point in the history

Commits on Oct 8, 2026

  1. [flutter-3.47-candidate.0] Sync engine.version to deb2874 (#193957)

    Updates the engine.version file from `692136cb6582dbfc5af3fb33c2515a069f2f66d0` to `deb287481e3ce9468f3434937ced4240a70539ca`.
    flutteractionsbot authored Oct 8, 2026
    Configuration menu
    Copy the full SHA
    abaf9c5 View commit details
    Browse the repository at this point in the history
Loading