Send statusBarTouch events via dedicated messages#179643
Send statusBarTouch events via dedicated messages#179643auto-submit[bot] merged 26 commits intoflutter:masterfrom
Conversation
|
|
||
| @override | ||
| void deactivate() { | ||
| WidgetsBinding.instance.removeObserver(this); |
There was a problem hiding this comment.
It is more robust (currently) to do this in deactivate instead of dispose in case the callback throws an exception. Now I think about it, the decision to only try to call deactivate instead of dispose when an Element throws an exception when mounting/unmounting seems a bit random.
There was a problem hiding this comment.
Somewhat related: #180434, some tests were failing when addObserver/removeObserver were done in initState and dispose, because the WidgetsBindingObserver list is a singleton and doesn't reset between tests.
|
Sorry for the ping, but I was wondering if this PR will be included in the upcoming Flutter 3.38.9 hotfix? Thanks! |
Instead of using fake touch events. Before this patch `FlutterViewController` sends two fake touch events (down and up), at `(0, 0)` to the framework to signal that the status bar is tapped on iOS. The scaffold widget and the cupertino page scaffold widget set up gesture detectors to listen for these fake taps, and scroll the "primary" scrollable container to the top in response. This messaging mechanism is sometimes ambiguous, as the framework may interpret that as a pair of regular pointer tap events (for instance in flutter#177992 the modal barrier claims the tap gesture and as a result the modal barrier is dismissed by the fake touch events). This PR changes that to communicate the status bar tap event via a new system channel, and dispatch the events via `WidgetsBindingObserver`s in the framework. See also flutter#177992 (comment) Fixes flutter#177992, fixes flutter#175606 It appears that UIKit also has access to the coordinates of the touch events to determine which scrollable view(s?) to dispatch the scroll to top event to. ```objc * frame #0: 0x00000001032f6520 UIPlayground.debug.dylib`MyScrollViewController.scrollViewShouldScrollToTop(scrollView=0x0000000106014800) at UIScrollView.swift:13:3 frame flutter#2: 0x00000001867c9300 UIKitCore`-[UIScrollView _scrollToTopIfPossible:] + 316 frame flutter#3: 0x00000001867c9604 UIKitCore`-[UIScrollView _scrollToTopFromTouchAtScreenLocation:resultHandler:] + 40 frame flutter#4: 0x0000000186299bbc UIKitCore`__71-[UIWindow _scrollToTopViewsUnderScreenPointIfNecessary:resultHandler:]_block_invoke.358 + 168 frame flutter#5: 0x000000018629981c UIKitCore`-[UIWindow _scrollToTopViewsUnderScreenPointIfNecessary:resultHandler:] + 1212 frame flutter#6: 0x000000018581ed8c UIKitCore`-[UIStatusBarManager _handleScrollToTopAtXPosition:] + 192 frame flutter#7: 0x000000018581eb60 UIKitCore`-[UIStatusBarManager handleTapAction:] + 60 ``` Unfortunately that information is not available to user application. The iOS accessibility bridge currently does create dummy UIScrollViews for each scrollable in the accessibility tree so may be we can take advantage of that in the future. ## Pre-launch 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 and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Roll Flutter from dfd92b773219 to da72d5936d69 (39 revisions) flutter/flutter@dfd92b7...da72d59 2026-01-29 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[ Tool / Engine ] Cleanup x86 references (#181152)" (flutter/flutter#181643) 2026-01-29 [email protected] Roll Skia from 174db42b7300 to 89df65f8324c (2 revisions) (flutter/flutter#181636) 2026-01-29 [email protected] [material/menu_anchor.dart] Add animations to MenuAnchor. (flutter/flutter#176494) 2026-01-28 [email protected] Roll Skia from 8e09f8a82251 to 174db42b7300 (6 revisions) (flutter/flutter#181627) 2026-01-28 [email protected] Send statusBarTouch events via dedicated messages (flutter/flutter#179643) 2026-01-28 [email protected] test: Improve DropdownMenuFormField tests (flutter/flutter#181369) 2026-01-28 [email protected] Account for vec3 padding in Metal (flutter/flutter#181563) 2026-01-28 [email protected] [ Tool / Engine ] Cleanup x86 references (flutter/flutter#181152) 2026-01-28 [email protected] Fix the issue on macOS where, after a hot restart with multiple windows, unresponsive windows are left behind. (flutter/flutter#180287) 2026-01-28 [email protected] Roll Skia from 675444e94bc9 to 8e09f8a82251 (7 revisions) (flutter/flutter#181606) 2026-01-28 [email protected] Roll Packages from e37af11 to 1cb2148 (5 revisions) (flutter/flutter#181608) 2026-01-28 [email protected] fix: swap app and engine version in vk::ApplicationInfo (flutter/flutter#181432) 2026-01-28 [email protected] Adds impeller backend to skia gold client (flutter/flutter#181503) 2026-01-28 [email protected] Remove chrome_and_driver dependency where it's not needed (flutter/flutter#178174) 2026-01-28 [email protected] chore: Windows_mokey basic_material_app_win__compile !bringup (flutter/flutter#180985) 2026-01-28 [email protected] Fix generating both `settings.gradle` and `settings.gradle.kts` for plugins (flutter/flutter#181592) 2026-01-28 [email protected] Roll Skia from 6614f89de521 to 675444e94bc9 (3 revisions) (flutter/flutter#181587) 2026-01-28 [email protected] Fix `todayBorder` todayBorder color is incorrectly overridden by `todayForegroundColor` in CalendarDatePicker (flutter/flutter#178792) 2026-01-28 [email protected] Roll Skia from 8f1695a4b328 to 6614f89de521 (2 revisions) (flutter/flutter#181583) 2026-01-28 [email protected] feat: add RoundedSuperellipseInputBorder (flutter/flutter#177220) 2026-01-28 [email protected] Roll Dart SDK from 38e351498549 to f10dcbfca98f (2 revisions) (flutter/flutter#181582) 2026-01-28 [email protected] Roll Skia from f424d58e37a3 to 8f1695a4b328 (6 revisions) (flutter/flutter#181577) 2026-01-28 [email protected] Remove unused code paths in `PlatformViewsController.java` (flutter/flutter#181393) 2026-01-28 [email protected] feat: add onEnd to AnimatedCrossFade (flutter/flutter#181455) 2026-01-28 [email protected] Don't pass bounds to saveLayer call when painting ImageFilter (flutter/flutter#181353) 2026-01-28 [email protected] test: Clarify failure messages on gestures/debug_test.dart (flutter/flutter#181109) 2026-01-27 [email protected] Roll Fuchsia Linux SDK from akraNGn2lw4T1msgZ... to adhoq9ouVRh0xzkm3... (flutter/flutter#181571) 2026-01-27 [email protected] Roll Dart SDK from 4c7cb0a1d07d to 38e351498549 (4 revisions) (flutter/flutter#181570) 2026-01-27 [email protected] Make sure that an AnimatedPadding doesn't crash in 0x0 environment (flutter/flutter#181235) 2026-01-27 [email protected] Make sure that an ImageFiltered doesn't crash at 0x0 environment (flutter/flutter#181067) 2026-01-27 [email protected] Marks firebase_release_smoke_test to be unflaky (flutter/flutter#181308) 2026-01-27 [email protected] Fix remove material import box decoration test (flutter/flutter#181253) 2026-01-27 [email protected] Roll Skia from c2754838b077 to f424d58e37a3 (8 revisions) (flutter/flutter#181564) 2026-01-27 [email protected] Make sure that an AnimatedAlign doesn't crash in 0x0 environment (flutter/flutter#181361) 2026-01-27 [email protected] Make sure that an ImageIcon doesn't crash in 0x0 environment (flutter/flutter#181099) 2026-01-27 [email protected] Make sure that an AnimatedContainer doesn't crash in 0x0 environment (flutter/flutter#181198) 2026-01-27 [email protected] Make sure that an AnimatedRotation doesn't crash in 0x0 environment (flutter/flutter#181486) 2026-01-27 [email protected] Make sure that an AnimatedPositionedDirectional doesn't crash in 0x0 … (flutter/flutter#181451) 2026-01-27 [email protected] Merge changelog for 3.38.8. (flutter/flutter#181558) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. ...
Instead of using fake touch events. Before this patch `FlutterViewController` sends two fake touch events (down and up), at `(0, 0)` to the framework to signal that the status bar is tapped on iOS. The scaffold widget and the cupertino page scaffold widget set up gesture detectors to listen for these fake taps, and scroll the "primary" scrollable container to the top in response. This messaging mechanism is sometimes ambiguous, as the framework may interpret that as a pair of regular pointer tap events (for instance in flutter#177992 the modal barrier claims the tap gesture and as a result the modal barrier is dismissed by the fake touch events). This PR changes that to communicate the status bar tap event via a new system channel, and dispatch the events via `WidgetsBindingObserver`s in the framework. See also flutter#177992 (comment) Fixes flutter#177992, fixes flutter#175606 It appears that UIKit also has access to the coordinates of the touch events to determine which scrollable view(s?) to dispatch the scroll to top event to. ```objc * frame #0: 0x00000001032f6520 UIPlayground.debug.dylib`MyScrollViewController.scrollViewShouldScrollToTop(scrollView=0x0000000106014800) at UIScrollView.swift:13:3 frame flutter#2: 0x00000001867c9300 UIKitCore`-[UIScrollView _scrollToTopIfPossible:] + 316 frame flutter#3: 0x00000001867c9604 UIKitCore`-[UIScrollView _scrollToTopFromTouchAtScreenLocation:resultHandler:] + 40 frame flutter#4: 0x0000000186299bbc UIKitCore`__71-[UIWindow _scrollToTopViewsUnderScreenPointIfNecessary:resultHandler:]_block_invoke.358 + 168 frame flutter#5: 0x000000018629981c UIKitCore`-[UIWindow _scrollToTopViewsUnderScreenPointIfNecessary:resultHandler:] + 1212 frame flutter#6: 0x000000018581ed8c UIKitCore`-[UIStatusBarManager _handleScrollToTopAtXPosition:] + 192 frame flutter#7: 0x000000018581eb60 UIKitCore`-[UIStatusBarManager handleTapAction:] + 60 ``` Unfortunately that information is not available to user application. The iOS accessibility bridge currently does create dummy UIScrollViews for each scrollable in the accessibility tree so may be we can take advantage of that in the future. ## Pre-launch 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 and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…182223) This reverts commit f4c83de. See b/482565401. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…9643)" (flutter#182223) This reverts commit f4c83de. See b/482565401. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…us bar tap (#182391) Reland #179643, with [changes](3f7d345) to fix #182233. The reland closes #177992, closes #175606. The crash happened because `Scaffold.handleStatusBar` (and subsequently `ScrollController.animateTo`) is called on a scaffold that [has never been laid out](#182233 (comment)). Before #179643, the iOS embedder sends a fake touch down pointer event at `(0, 0)` to the framework, followed by a touch up pointer event at the same location. That ensured only the foreground `Scaffold` could claim the tap gesture and handle the status bar tap. The fix tries to restore the previous behavior (where the iOS behavior sends fake touches instead of platform messages) by performing a hit-test at `(0, 0)` before trying to scroll the primary controller of a `Scaffold` to the top, this should make sure that only the foreground scaffold (in theory it's still possible for more than one Scaffold to receive the hittest and handle the status bar tap event, but the foreground scaffold should block the hit-test on background ones instead of relying on gesture disambiguation). ## Pre-launch 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 and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…on status bar tap (flutter#182391) Reland flutter#179643, with [changes](flutter@3f7d345) to fix flutter#182233. The reland closes flutter#177992, closes flutter#175606. The crash happened because `Scaffold.handleStatusBar` (and subsequently `ScrollController.animateTo`) is called on a scaffold that [has never been laid out](flutter#182233 (comment)). Before flutter#179643, the iOS embedder sends a fake touch down pointer event at `(0, 0)` to the framework, followed by a touch up pointer event at the same location. That ensured only the foreground `Scaffold` could claim the tap gesture and handle the status bar tap. The fix tries to restore the previous behavior (where the iOS behavior sends fake touches instead of platform messages) by performing a hit-test at `(0, 0)` before trying to scroll the primary controller of a `Scaffold` to the top, this should make sure that only the foreground scaffold (in theory it's still possible for more than one Scaffold to receive the hittest and handle the status bar tap event, but the foreground scaffold should block the hit-test on background ones instead of relying on gesture disambiguation). - [ ] 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 and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…9643)" (flutter#182223) This reverts commit f4c83de. See b/482565401. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…on status bar tap (flutter#182391) Reland flutter#179643, with [changes](flutter@3f7d345) to fix flutter#182233. The reland closes flutter#177992, closes flutter#175606. The crash happened because `Scaffold.handleStatusBar` (and subsequently `ScrollController.animateTo`) is called on a scaffold that [has never been laid out](flutter#182233 (comment)). Before flutter#179643, the iOS embedder sends a fake touch down pointer event at `(0, 0)` to the framework, followed by a touch up pointer event at the same location. That ensured only the foreground `Scaffold` could claim the tap gesture and handle the status bar tap. The fix tries to restore the previous behavior (where the iOS behavior sends fake touches instead of platform messages) by performing a hit-test at `(0, 0)` before trying to scroll the primary controller of a `Scaffold` to the top, this should make sure that only the foreground scaffold (in theory it's still possible for more than one Scaffold to receive the hittest and handle the status bar tap event, but the foreground scaffold should block the hit-test on background ones instead of relying on gesture disambiguation). - [ ] 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 and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…l views on status bar tap (flutter#182391)" This reverts commit d2eeab6.
…9643)" (flutter#182223) This reverts commit f4c83de. See b/482565401. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…on status bar tap (flutter#182391) Reland flutter#179643, with [changes](flutter@3f7d345) to fix flutter#182233. The reland closes flutter#177992, closes flutter#175606. The crash happened because `Scaffold.handleStatusBar` (and subsequently `ScrollController.animateTo`) is called on a scaffold that [has never been laid out](flutter#182233 (comment)). Before flutter#179643, the iOS embedder sends a fake touch down pointer event at `(0, 0)` to the framework, followed by a touch up pointer event at the same location. That ensured only the foreground `Scaffold` could claim the tap gesture and handle the status bar tap. The fix tries to restore the previous behavior (where the iOS behavior sends fake touches instead of platform messages) by performing a hit-test at `(0, 0)` before trying to scroll the primary controller of a `Scaffold` to the top, this should make sure that only the foreground scaffold (in theory it's still possible for more than one Scaffold to receive the hittest and handle the status bar tap event, but the foreground scaffold should block the hit-test on background ones instead of relying on gesture disambiguation). - [ ] 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 and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This pull request is manually created because there were merge conflicts. <details> <summary><b>Click here for the conflicts</b></summary> ```diff diff --cc packages/flutter/test/widgets/interactive_viewer_test.dart index e4ef349,63b1c353d72..00000000000 --- a/packages/flutter/test/widgets/interactive_viewer_test.dart +++ b/packages/flutter/test/widgets/interactive_viewer_test.dart @@@ -1044,25 -956,22 +1044,43 @@@ void main() var calledStart = false; var calledUpdate = false; var calledEnd = false; + const sizedBox = SizedBox(width: 200.0, height: 200.0); await tester.pumpWidget( ++<<<<<<< HEAD + MaterialApp( + home: Scaffold( + body: Center( + child: InteractiveViewer( + transformationController: transformationController, + scaleEnabled: false, + onInteractionStart: (ScaleStartDetails details) { + calledStart = true; + }, + onInteractionUpdate: (ScaleUpdateDetails details) { + calledUpdate = true; + }, + onInteractionEnd: (ScaleEndDetails details) { + calledEnd = true; + }, + child: const SizedBox(width: 200.0, height: 200.0), + ), + ), ++======= + Center( + child: InteractiveViewer( + transformationController: transformationController, + scaleEnabled: false, + onInteractionStart: (ScaleStartDetails details) { + calledStart = true; + }, + onInteractionUpdate: (ScaleUpdateDetails details) { + calledUpdate = true; + }, + onInteractionEnd: (ScaleEndDetails details) { + calledEnd = true; + }, + child: sizedBox, ++>>>>>>> 91b2d41 (Reland #179643, only scroll hit-testable primary scroll views on status bar tap (#182391)) ), ), ); @@@ -1119,25 -1028,22 +1137,43 @@@ var calledStart = false; var calledUpdate = false; var calledEnd = false; + const sizedBox = SizedBox(width: 200.0, height: 200.0); await tester.pumpWidget( ++<<<<<<< HEAD + MaterialApp( + home: Scaffold( + body: Center( + child: InteractiveViewer( + transformationController: transformationController, + scaleEnabled: false, + onInteractionStart: (ScaleStartDetails details) { + calledStart = true; + }, + onInteractionUpdate: (ScaleUpdateDetails details) { + calledUpdate = true; + }, + onInteractionEnd: (ScaleEndDetails details) { + calledEnd = true; + }, + child: const SizedBox(width: 200.0, height: 200.0), + ), + ), ++======= + Center( + child: InteractiveViewer( + transformationController: transformationController, + scaleEnabled: false, + onInteractionStart: (ScaleStartDetails details) { + calledStart = true; + }, + onInteractionUpdate: (ScaleUpdateDetails details) { + calledUpdate = true; + }, + onInteractionEnd: (ScaleEndDetails details) { + calledEnd = true; + }, + child: sizedBox, ++>>>>>>> 91b2d41 (Reland #179643, only scroll hit-testable primary scroll views on status bar tap (#182391)) ), ), ); ``` </details> ### Issue Link: What is the link to the issue this cherry-pick is addressing? #182233 The bug was introduced in #179643 which was cherry picked to 3.41 beta (so the crash should exist on both current beta and stable). ### Impact Description: On iOS, the app may crash when the user taps on the status bar to scroll to top, when the app has a primary scroll view that has never been laid out (for example, in a route that has been obstructed by other routes since its creation). ### Changelog Description: - [flutter/182233](#182233) - Tapping on the status bar may crash the app on iOS when there's a primary scroll view that has never been laid out. Additionally this patch only dispatches the "scroll to top" command to the topmost Scaffold which is generally better UX for most apps (this doesn't have to be in the changlog) ### Workaround: No known easy workarounds. ### Risk: What is the risk level of this cherry-pick? ### Test Coverage: Are you confident that your fix is well-tested by automated tests? ### Validation Steps: What are the steps to validate that this fix works? I've manually tested the fix on iOS/iPadOS simulators. There are also unit tests.
This pull request is manually created because there were merge conflicts. <details> <summary><b>Click here for the conflicts</b></summary> ```diff diff --cc packages/flutter/test/widgets/interactive_viewer_test.dart index e4ef349,63b1c353d72..00000000000 --- a/packages/flutter/test/widgets/interactive_viewer_test.dart +++ b/packages/flutter/test/widgets/interactive_viewer_test.dart @@@ -1044,25 -956,22 +1044,43 @@@ void main() var calledStart = false; var calledUpdate = false; var calledEnd = false; + const sizedBox = SizedBox(width: 200.0, height: 200.0); await tester.pumpWidget( ++<<<<<<< HEAD + MaterialApp( + home: Scaffold( + body: Center( + child: InteractiveViewer( + transformationController: transformationController, + scaleEnabled: false, + onInteractionStart: (ScaleStartDetails details) { + calledStart = true; + }, + onInteractionUpdate: (ScaleUpdateDetails details) { + calledUpdate = true; + }, + onInteractionEnd: (ScaleEndDetails details) { + calledEnd = true; + }, + child: const SizedBox(width: 200.0, height: 200.0), + ), + ), ++======= + Center( + child: InteractiveViewer( + transformationController: transformationController, + scaleEnabled: false, + onInteractionStart: (ScaleStartDetails details) { + calledStart = true; + }, + onInteractionUpdate: (ScaleUpdateDetails details) { + calledUpdate = true; + }, + onInteractionEnd: (ScaleEndDetails details) { + calledEnd = true; + }, + child: sizedBox, ++>>>>>>> 91b2d41 (Reland #179643, only scroll hit-testable primary scroll views on status bar tap (#182391)) ), ), ); @@@ -1119,25 -1028,22 +1137,43 @@@ var calledStart = false; var calledUpdate = false; var calledEnd = false; + const sizedBox = SizedBox(width: 200.0, height: 200.0); await tester.pumpWidget( ++<<<<<<< HEAD + MaterialApp( + home: Scaffold( + body: Center( + child: InteractiveViewer( + transformationController: transformationController, + scaleEnabled: false, + onInteractionStart: (ScaleStartDetails details) { + calledStart = true; + }, + onInteractionUpdate: (ScaleUpdateDetails details) { + calledUpdate = true; + }, + onInteractionEnd: (ScaleEndDetails details) { + calledEnd = true; + }, + child: const SizedBox(width: 200.0, height: 200.0), + ), + ), ++======= + Center( + child: InteractiveViewer( + transformationController: transformationController, + scaleEnabled: false, + onInteractionStart: (ScaleStartDetails details) { + calledStart = true; + }, + onInteractionUpdate: (ScaleUpdateDetails details) { + calledUpdate = true; + }, + onInteractionEnd: (ScaleEndDetails details) { + calledEnd = true; + }, + child: sizedBox, ++>>>>>>> 91b2d41 (Reland #179643, only scroll hit-testable primary scroll views on status bar tap (#182391)) ), ), ); ``` </details> ### Issue Link: What is the link to the issue this cherry-pick is addressing? #182233 The bug was introduced in #179643 which was cherry picked to 3.41 beta (so the crash should exist on both current beta and stable). ### Impact Description: On iOS, the app may crash when the user taps on the status bar to scroll to top, when the app has a primary scroll view that has never been laid out (for example, in a route that has been obstructed by other routes). ### Changelog Description: - [flutter/182233](#182233) - Tapping on the status bar may crash the app on iOS when there's a primary scroll view that has never been laid out. Additionally this patch only dispatches the "scroll to top" command to the topmost Scaffold which is generally better UX for most apps (this doesn't have to be in the changlog) ### Workaround: No known easy workarounds. ### Risk: What is the risk level of this cherry-pick? ### Test Coverage: Are you confident that your fix is well-tested by automated tests? ### Validation Steps: What are the steps to validate that this fix works? I've manually tested the fix on iOS/iPadOS simulators. There are also unit tests.
|
Am I correct that this fix will land in stable in 3.44 in May 2026? |
This has already been cherry-picked to the current stable (but you might want to wait for this week's stable hotfix since there was a crash). |
Alright, nice. Does that mean it'll land in 3.41.3 like tomorrow? |
…on status bar tap (flutter#182391) Reland flutter#179643, with [changes](flutter@3f7d345) to fix flutter#182233. The reland closes flutter#177992, closes flutter#175606. The crash happened because `Scaffold.handleStatusBar` (and subsequently `ScrollController.animateTo`) is called on a scaffold that [has never been laid out](flutter#182233 (comment)). Before flutter#179643, the iOS embedder sends a fake touch down pointer event at `(0, 0)` to the framework, followed by a touch up pointer event at the same location. That ensured only the foreground `Scaffold` could claim the tap gesture and handle the status bar tap. The fix tries to restore the previous behavior (where the iOS behavior sends fake touches instead of platform messages) by performing a hit-test at `(0, 0)` before trying to scroll the primary controller of a `Scaffold` to the top, this should make sure that only the foreground scaffold (in theory it's still possible for more than one Scaffold to receive the hittest and handle the status bar tap event, but the foreground scaffold should block the hit-test on background ones instead of relying on gesture disambiguation). ## Pre-launch 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 and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Instead of using fake touch events.
Before this patch
FlutterViewControllersends two fake touch events (down and up), at(0, 0)to the framework to signal that the status bar is tapped on iOS. The scaffold widget and the cupertino page scaffold widget set up gesture detectors to listen for these fake taps, and scroll the "primary" scrollable container to the top in response.This messaging mechanism is sometimes ambiguous, as the framework may interpret that as a pair of regular pointer tap events (for instance in #177992 the modal barrier claims the tap gesture and as a result the modal barrier is dismissed by the fake touch events). This PR changes that to communicate the status bar tap event via a new system channel, and dispatch the events via
WidgetsBindingObservers in the framework.See also #177992 (comment)
Fixes #177992, fixes #175606
It appears that UIKit also has access to the coordinates of the touch events to determine which scrollable view(s?) to dispatch the scroll to top event to.
Unfortunately that information is not available to user application. The iOS accessibility bridge currently does create dummy UIScrollViews for each scrollable in the accessibility tree so may be we can take advantage of that in the future.
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.