-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Implements engine-side declarative pointer event handling for semantics. #176974
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
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 effectively fixes an issue where dialogs on the web could be prematurely dismissed when semantics are enabled. The root cause was that non-interactive semantic leaf nodes were incorrectly intercepting pointer events.
The fix introduces a more nuanced policy for determining which semantic nodes accept pointer events:
- Route-scoped containers (like dialogs) now accept pointer events to function as a barrier.
- Leaf nodes only accept pointer events if they are interactive (e.g., buttons, text fields).
This change is well-supported by a comprehensive set of new unit tests that verify the behavior of various interactive and non-interactive nodes. The implementation is clear and directly addresses the problem. I have a couple of suggestions to further improve robustness and test maintainability.
engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart
Outdated
Show resolved
Hide resolved
engine/src/flutter/lib/web_ui/test/engine/semantics/semantics_test.dart
Outdated
Show resolved
Hide resolved
| return semanticsObject.isTappable || | ||
| semanticsObject.isButton || | ||
| semanticsObject.isCheckable || | ||
| semanticsObject.flags.isTextField || | ||
| semanticsObject.flags.isLink || | ||
| semanticsObject.flags.isSlider || | ||
| semanticsObject.isIncrementable; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these have their own Semantics role or behavior (except isSlider [1]). Let's override the acceptsPointerEvents in the corresponding classes.
[1] It looks like semantic sliders are not implemented? So let's not worry about it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented engine-side declarative pointer event handling for semantics based on discussion. Please review.
engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart
Outdated
Show resolved
Hide resolved
Enhanced acceptsPointerEvents with: - Multi-tier policy documentation (4 tiers) - Tier 1: Explicit behaviors (Tappable, TextField, etc.) - Tier 2: Framework declaration (TODO for future SemanticsHitTestBehavior) - Tier 3: Route-scoped containers fallback (current fix) - Tier 4: Default transparent leaf nodes The fallback ensures: - Immediate bug fix for dialog dismissal - Backward compatibility during framework transition - Support for third-party packages - Graceful degradation for custom widgets Prepared for future framework PR that will add SemanticsHitTestBehavior enum for declarative control over pointer event handling. Related: #149001 Discussion: #176974
a5c665d to
69dfd15
Compare
| @@ -1156,6 +1156,34 @@ enum Tristate { | |||
| } | |||
| } | |||
|
|
|||
| /// Describes how a semantic node should behave during hit testing. | |||
| /// | |||
| /// This enum is used by the web engine to determine whether semantic elements | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing. I updated the PR accordingly.
| enum SemanticsHitTestBehavior { | ||
| /// The semantic element is opaque to hit testing, consuming any pointer | ||
| /// events within its bounds and preventing them from reaching elements | ||
| /// behind it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this blocking child or sibling in hittest order? or both? should document this more clearly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing. I updated the PR accordingly.
| @@ -1792,12 +1820,20 @@ abstract class SemanticsUpdateBuilder { | |||
| /// not use this argument should use other ways to communicate validation | |||
| /// errors to the user, such as embedding validation error text in the label. | |||
| /// | |||
| /// The `hitTestBehavior` describes how this node should behave during hit | |||
| /// testing. If null, the platform will infer appropriate behavior based on | |||
| /// other semantic properties. This is primarily used by the web platform to | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same for the comment here, should be platform neutral
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the infer behavior? do they inherited from the parent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing. I updated the PR accordingly.
| @@ -1792,12 +1820,20 @@ abstract class SemanticsUpdateBuilder { | |||
| /// not use this argument should use other ways to communicate validation | |||
| /// errors to the user, such as embedding validation error text in the label. | |||
| /// | |||
| /// The `hitTestBehavior` describes how this node should behave during hit | |||
| /// testing. If null, the platform will infer appropriate behavior based on | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of using null, consider give it a enum SemanticsHitTestBehavior.defer and makes it the default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing. I updated the PR accordingly.
| @@ -1913,6 +1949,7 @@ base class _NativeSemanticsUpdateBuilder extends NativeFieldWrapperClass1 | |||
| SemanticsRole role = SemanticsRole.none, | |||
| required List<String>? controlsNodes, | |||
| SemanticsValidationResult validationResult = SemanticsValidationResult.none, | |||
| SemanticsHitTestBehavior? hitTestBehavior, | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should remove nullable and make required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing. I updated the PR accordingly.
| /// | ||
| /// This is the default behavior for non-interactive semantic nodes. | ||
| /// | ||
| /// On the web, this results in `pointer-events: none` CSS property. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In framework transparent means this node receives hittest, but won't block the silbing and child behind it from receiving hittest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing. I updated the PR accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In framework transparent means this node receives hittest, but won't block the silbing and child behind it from receiving hittest
I think you meant "translucent"?
flutter/packages/flutter/lib/src/rendering/proxy_box.dart
Lines 144 to 158 in 542705c
| /// How to behave during hit tests. | |
| enum HitTestBehavior { | |
| /// Targets that defer to their children receive events within their bounds | |
| /// only if one of their children is hit by the hit test. | |
| deferToChild, | |
| /// Opaque targets can be hit by hit tests, causing them to both receive | |
| /// events within their bounds and prevent targets visually behind them from | |
| /// also receiving events. | |
| opaque, | |
| /// Translucent targets both receive events within their bounds and permit | |
| /// targets visually behind them to also receive events. | |
| translucent, | |
| } |
"transparent" is defined in platform view behaviors:
flutter/packages/flutter/lib/src/rendering/platform_view.dart
Lines 19 to 32 in 542705c
| enum PlatformViewHitTestBehavior { | |
| /// Opaque targets can be hit by hit tests, causing them to both receive | |
| /// events within their bounds and prevent targets visually behind them from | |
| /// also receiving events. | |
| opaque, | |
| /// Translucent targets both receive events within their bounds and permit | |
| /// targets visually behind them to also receive events. | |
| translucent, | |
| /// Transparent targets don't receive events within their bounds and permit | |
| /// targets visually behind them to receive events. | |
| transparent, | |
| } |
- "opaque" matches
pointer-events: allon the web. - "transparent" matches
pointer-events: noneon the web. - "translucent" (which is what you're describing) is not possible on web AFAICT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I updated the PR accordingly.
| /// | ||
| /// The decision follows a multi-tier policy: | ||
| /// | ||
| /// **Tier 1: Explicit Behaviors** - Behaviors attached to this role can |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Declaration should probably come first before this. Also I think you meant Implicit behaviors? since the behavior is inferred from semantics behavior/role
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also ideally we should infer the SemanticsHitTestBehavior from the framework side if not provided. That way the platform just need to deal with SemanticsHitTestBehavior
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing. I updated the PR accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Declaration should probably come first before this.
This part of the comment was not addressed. When the framework says the node is transparent, we should treat it as transparent. It becomes really confusing when users set a button to transparent and notice that the button is still receiving clicks and blocking hit testing.
If we think it's a bad idea to allow interactive nodes to be transparent, then we should make that state illegal at the framework level. IMO the engine should just follow what the framework dictates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I thought it is about code style. I updated the PR accordingly.
| /// [ui.SemanticsHitTestBehavior], it will be respected here. This allows | ||
| /// declarative control over pointer event handling from the framework layer. | ||
| /// | ||
| /// **Tier 3: Route-Scoped Containers** - Containers with [scopesRoute] set |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be handled in framework by wrapping ModalRoute with SemanticsHitTestBehavior
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right that framework should handle this. Our architecture fully supports that. When framework provides explicit values, engine just executes them (Tier 1). Engine inference is only a backward-compatible fallback (Tier 2) because popular packages like awesome_dialog don't know about SemanticsHitTestBehavior yet. Engine inference means they work immediately.
| /// preventing clicks from escaping to underlying modal barriers. This is | ||
| /// the current fix for issue #149001. | ||
| /// | ||
| /// **Tier 4: Default Transparent** - Leaf nodes without interactive behaviors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could also handle this on the framework side by inferring SemanticsHitTestBehavior if not provided
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right that framework should handle this. Our architecture fully supports that. When framework provides explicit values, engine just executes them (Tier 1). Engine inference is only a backward-compatible fallback (Tier 2) because popular packages like awesome_dialog don't know about SemanticsHitTestBehavior yet. Engine inference means they work immediately.
| /// Platform implementations: | ||
| /// * On the web, this results in `pointer-events: none` CSS property. | ||
| /// | ||
| /// This is the default behavior for non-interactive semantic nodes when the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this paragraph should probably be in defer enum instead, and also mention this is web's default behavior if we want to include this info. (we don't know what other platform will do yet)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestion. I updated the documentation.
| } | ||
|
|
||
| @override | ||
| bool get acceptsPointerEvents => true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unfortunate name collisions, should make it something like shouldAcceptsPointerEvents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
acceptsPointerEvents already exists in abstract class SemanticBehavior and abstract class SemanticBehavior. Please check https://github.com/flutter/flutter/blob/master/engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart. do we want to change one of them to shouldAcceptsPointerEvents?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should rename this getter for every classes, it shouldn't be a problem since these are not public
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation. I updated the code.
| /// - Route-scoped containers (dialogs, bottom sheets) | ||
| /// - Default transparent for non-interactive leaf nodes | ||
| /// | ||
| /// This approach allows framework full control when specified, with intelligent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// This approach allows framework full control when specified, with intelligent | |
| /// This approach allows framework full control when specified, with reasonable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should tune down the tone a bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestion. I updated the documentation.
| case ui.SemanticsHitTestBehavior.defer: | ||
| // This case should never be reached because defer is handled in | ||
| // acceptsPointerEvents before calling this method. | ||
| assert(false, 'defer should be handled by _inferAcceptsPointerEvents'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider inline this switch case directly in acceptsPointerEvents body so that we don't need this assert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestion. I updated the code.
|
|
||
| /// Infers whether pointer events should be accepted based on semantic properties. | ||
| /// | ||
| /// This method is called when [ui.SemanticsHitTestBehavior.defer] is set, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider remove this paragraph and use assert(hitTestBehavior == ui.SemanticsHitTestBehavior.defer) to explain the assumption
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestion. I updated the code.
| // from passing through to the modal barrier underneath. | ||
| if (semanticsObject.hasChildren) { | ||
| return false; | ||
| return semanticsObject.scopesRoute; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be set from the framework side instead of using inferring here. The reason being that we don't want every platform has to duplicate this logic. ideally, platform inferring should be as less as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The intention is to let packages like https://pub.dev/packages/awesome_dialog which has not implemented our change to have the fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, it will be their responsibility to opt in, but in this case as long as this is wrapped in
| _modalScope = OverlayEntry( |
All the route/dialog should get this automaticially
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation. I updated the code.
…vior naming collision
chunhtai
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| ui.SemanticsHitTestBehavior.opaque => true, | ||
| ui.SemanticsHitTestBehavior.transparent => false, | ||
| _ => true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ui.SemanticsHitTestBehavior.opaque => true, | |
| ui.SemanticsHitTestBehavior.transparent => false, | |
| _ => true, | |
| ui.SemanticsHitTestBehavior.transparent => false, | |
| _ => true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missed this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch. Updated.
Roll Flutter from 75004a639ae4 to cb18290fa45e (48 revisions) flutter/flutter@75004a6...cb18290 2025-10-24 [email protected] Remove unnecessary `deprecated` withOpacity in `text_button.0.dart` in examples (flutter/flutter#177374) 2025-10-24 [email protected] Roll Packages from 9ec29b6 to 53d6138 (3 revisions) (flutter/flutter#177502) 2025-10-24 [email protected] Roll Dart SDK from d3248b00f545 to a0480f399f8f (1 revision) (flutter/flutter#177498) 2025-10-24 [email protected] Roll Skia from a47931d09585 to 3ed332b77bec (3 revisions) (flutter/flutter#177487) 2025-10-24 [email protected] Roll Abseil to Chromium's 5b92b04a2e (based on Abseil commit fc4481e968) (flutter/flutter#177059) 2025-10-24 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Reverts "Enhance PR template with changelog and impact details (#177333)" (#177468)" (flutter/flutter#177499) 2025-10-24 [email protected] Document DropdownMenu showTrailingIcon and decorationBuilder interaction (flutter/flutter#177488) 2025-10-24 [email protected] Roll Dart SDK from 4a65fb890852 to d3248b00f545 (1 revision) (flutter/flutter#177486) 2025-10-24 [email protected] Fix bottom sheet Semantics route label for mismatched platforms (flutter/flutter#177094) 2025-10-24 [email protected] Roll Skia from eba11de00d5b to a47931d09585 (5 revisions) (flutter/flutter#177481) 2025-10-24 [email protected] Fix Dialog Semantics label and flags for mismatched platforms (flutter/flutter#176781) 2025-10-24 [email protected] Fix drawer Semantics for mismatched platforms (flutter/flutter#177095) 2025-10-24 [email protected] Roll Dart SDK from f7751ccea102 to 4a65fb890852 (2 revisions) (flutter/flutter#177480) 2025-10-23 [email protected] Change the root path of the license crawl to engine/src (flutter/flutter#177352) 2025-10-23 [email protected] [Material] Change default mouse cursor of buttons to basic arrow instead of click (except on web) (flutter/flutter#171796) 2025-10-23 [email protected] [Desktop] Propagate SemanticsNode::identifier to AXPlatformNodeDelegate::AuthorUniqueId (flutter/flutter#175405) 2025-10-23 [email protected] Roll Skia from 59ef57f4104e to eba11de00d5b (5 revisions) (flutter/flutter#177461) 2025-10-23 [email protected] Roll customer tests (flutter/flutter#177409) 2025-10-23 [email protected] Update CHANGELOG 3.35.7 notes (flutter/flutter#177463) 2025-10-23 [email protected] Marks Mac module_uiscene_test_ios to be unflaky (flutter/flutter#177378) 2025-10-23 [email protected] Allow empty dart defines in `flutter assemble` (flutter/flutter#177198) 2025-10-23 [email protected] Roll Packages from d113bbc to 9ec29b6 (12 revisions) (flutter/flutter#177455) 2025-10-23 [email protected] Implements engine-side declarative pointer event handling for semantics. (flutter/flutter#176974) 2025-10-23 [email protected] Fix the platform name of the windowing_test target for macOS in ci.yaml (flutter/flutter#177472) 2025-10-23 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Enhance PR template with changelog and impact details (#177333)" (flutter/flutter#177468) 2025-10-23 [email protected] Change Flutter APIs to use spans (flutter/flutter#177272) 2025-10-23 [email protected] Roll Dart SDK from 020988602772 to f7751ccea102 (4 revisions) (flutter/flutter#177449) 2025-10-23 [email protected] [macOS] Implement regular window (flutter/flutter#176361) 2025-10-23 [email protected] Enhance PR template with changelog and impact details (flutter/flutter#177333) 2025-10-23 [email protected] Roll Skia from 6e6acf6644ef to 59ef57f4104e (2 revisions) (flutter/flutter#177436) 2025-10-23 [email protected] Add directional static members to AlignmentGeometry. (flutter/flutter#176571) 2025-10-23 [email protected] Roll ICU from 1b2e3e8a421e to ff35c4f9df23 (5 revisions) (flutter/flutter#177434) 2025-10-23 [email protected] Adds a new CI build for Linux host DDM-enabled artifacts (flutter/flutter#177252) 2025-10-23 [email protected] Roll Skia from 920cdcadd74c to 6e6acf6644ef (1 revision) (flutter/flutter#177432) 2025-10-23 [email protected] Roll Skia from 8cd449e4953b to 920cdcadd74c (6 revisions) (flutter/flutter#177426) 2025-10-23 [email protected] Added ahem license (flutter/flutter#177423) 2025-10-23 [email protected] Roll Dart SDK from 75f6ccb9bdc5 to 020988602772 (1 revision) (flutter/flutter#177421) 2025-10-23 [email protected] [web] Set `pointer-events: none` for img-element-backed images (flutter/flutter#177418) 2025-10-22 [email protected] Remove the x64 version of build_ios_framework_module_test (flutter/flutter#177136) 2025-10-22 [email protected] Fix accessibility events not being correctly translated to ATK (flutter/flutter#176991) 2025-10-22 [email protected] Roll Skia from b55bd60ed95b to 8cd449e4953b (8 revisions) (flutter/flutter#177405) 2025-10-22 [email protected] Roll Dart SDK from c23010c4f9e6 to 75f6ccb9bdc5 (4 revisions) (flutter/flutter#177399) 2025-10-22 [email protected] Fixes crash when adding and removing mulitple page-based route (flutter/flutter#177338) 2025-10-22 [email protected] Move child parameter to end of RefreshIndicator constructor (flutter/flutter#177019) 2025-10-22 [email protected] refactor: migrate OpenUpwardsPageTransitionsBuilder to widgets (flutter/flutter#177080) 2025-10-22 [email protected] Delete stray 'text' file (flutter/flutter#177355) ...
…pply to ModalRoute (#177570) Fix premature dialog dismissal on Flutter Web when semantics are enabled by correctly propagating hitTestBehavior through the semantics pipeline and declaring modal routes as opaque to pointer events. Before change https://dialog-dismiss-before.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog being dismissed. After change https://dialog-dimiss-after.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog not dismissed. Fixes: #149001 Engine work: #176974
…get and apply to ModalRoute (#177570)" (#178744) <!-- start_original_pr_link --> Reverts: #177570 <!-- end_original_pr_link --> <!-- start_initiating_author --> Initiated by: chingjun <!-- end_initiating_author --> <!-- start_revert_reason --> Reason for reverting: Broke internal tests. <!-- end_revert_reason --> <!-- start_original_pr_author --> Original PR Author: flutter-zl <!-- end_original_pr_author --> <!-- start_reviewers --> Reviewed By: {chunhtai} <!-- end_reviewers --> <!-- start_revert_body --> This change reverts the following previous change: Fix premature dialog dismissal on Flutter Web when semantics are enabled by correctly propagating hitTestBehavior through the semantics pipeline and declaring modal routes as opaque to pointer events. Before change https://dialog-dismiss-before.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog being dismissed. After change https://dialog-dimiss-after.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog not dismissed. Fixes: #149001 Engine work: #176974 <!-- end_revert_body --> Co-authored-by: auto-submit[bot] <[email protected]>
…pply to ModalRoute (flutter#177570) Fix premature dialog dismissal on Flutter Web when semantics are enabled by correctly propagating hitTestBehavior through the semantics pipeline and declaring modal routes as opaque to pointer events. Before change https://dialog-dismiss-before.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog being dismissed. After change https://dialog-dimiss-after.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog not dismissed. Fixes: flutter#149001 Engine work: flutter#176974
…get and apply to ModalRoute (flutter#177570)" (flutter#178744) <!-- start_original_pr_link --> Reverts: flutter#177570 <!-- end_original_pr_link --> <!-- start_initiating_author --> Initiated by: chingjun <!-- end_initiating_author --> <!-- start_revert_reason --> Reason for reverting: Broke internal tests. <!-- end_revert_reason --> <!-- start_original_pr_author --> Original PR Author: flutter-zl <!-- end_original_pr_author --> <!-- start_reviewers --> Reviewed By: {chunhtai} <!-- end_reviewers --> <!-- start_revert_body --> This change reverts the following previous change: Fix premature dialog dismissal on Flutter Web when semantics are enabled by correctly propagating hitTestBehavior through the semantics pipeline and declaring modal routes as opaque to pointer events. Before change https://dialog-dismiss-before.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog being dismissed. After change https://dialog-dimiss-after.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog not dismissed. Fixes: flutter#149001 Engine work: flutter#176974 <!-- end_revert_body --> Co-authored-by: auto-submit[bot] <[email protected]>
…pply to ModalRoute (flutter#177570) Fix premature dialog dismissal on Flutter Web when semantics are enabled by correctly propagating hitTestBehavior through the semantics pipeline and declaring modal routes as opaque to pointer events. Before change https://dialog-dismiss-before.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog being dismissed. After change https://dialog-dimiss-after.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog not dismissed. Fixes: flutter#149001 Engine work: flutter#176974
…get and apply to ModalRoute (flutter#177570)" (flutter#178744) <!-- start_original_pr_link --> Reverts: flutter#177570 <!-- end_original_pr_link --> <!-- start_initiating_author --> Initiated by: chingjun <!-- end_initiating_author --> <!-- start_revert_reason --> Reason for reverting: Broke internal tests. <!-- end_revert_reason --> <!-- start_original_pr_author --> Original PR Author: flutter-zl <!-- end_original_pr_author --> <!-- start_reviewers --> Reviewed By: {chunhtai} <!-- end_reviewers --> <!-- start_revert_body --> This change reverts the following previous change: Fix premature dialog dismissal on Flutter Web when semantics are enabled by correctly propagating hitTestBehavior through the semantics pipeline and declaring modal routes as opaque to pointer events. Before change https://dialog-dismiss-before.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog being dismissed. After change https://dialog-dimiss-after.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog not dismissed. Fixes: flutter#149001 Engine work: flutter#176974 <!-- end_revert_body --> Co-authored-by: auto-submit[bot] <[email protected]>
…cs. (flutter#176974) Implements engine-side declarative pointer event handling for semantics. Framework-side to be implemented in next PR. Fixes flutter#149001. **Before change** https://dialog-dismiss-before.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog being dismissed. **After change** https://dialog-dimiss-after.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog not dismissed.
…pply to ModalRoute (flutter#177570) Fix premature dialog dismissal on Flutter Web when semantics are enabled by correctly propagating hitTestBehavior through the semantics pipeline and declaring modal routes as opaque to pointer events. Before change https://dialog-dismiss-before.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog being dismissed. After change https://dialog-dimiss-after.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog not dismissed. Fixes: flutter#149001 Engine work: flutter#176974
…get and apply to ModalRoute (flutter#177570)" (flutter#178744) <!-- start_original_pr_link --> Reverts: flutter#177570 <!-- end_original_pr_link --> <!-- start_initiating_author --> Initiated by: chingjun <!-- end_initiating_author --> <!-- start_revert_reason --> Reason for reverting: Broke internal tests. <!-- end_revert_reason --> <!-- start_original_pr_author --> Original PR Author: flutter-zl <!-- end_original_pr_author --> <!-- start_reviewers --> Reviewed By: {chunhtai} <!-- end_reviewers --> <!-- start_revert_body --> This change reverts the following previous change: Fix premature dialog dismissal on Flutter Web when semantics are enabled by correctly propagating hitTestBehavior through the semantics pipeline and declaring modal routes as opaque to pointer events. Before change https://dialog-dismiss-before.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog being dismissed. After change https://dialog-dimiss-after.web.app/ Click on the "Show Dialog" button. Click anywhere inside the dialog that is not a form field. Observe the dialog not dismissed. Fixes: flutter#149001 Engine work: flutter#176974 <!-- end_revert_body --> Co-authored-by: auto-submit[bot] <[email protected]>
Implements engine-side declarative pointer event handling for semantics.
Framework-side to be implemented in next PR.
Fixes #149001.
Before change
https://dialog-dismiss-before.web.app/
Click on the "Show Dialog" button.
Click anywhere inside the dialog that is not a form field.
Observe the dialog being dismissed.
After change
https://dialog-dimiss-after.web.app/
Click on the "Show Dialog" button.
Click anywhere inside the dialog that is not a form field.
Observe the dialog not dismissed.