-
Notifications
You must be signed in to change notification settings - Fork 6k
[web] Fix event offset for transformed widgets (and text input nodes). #41870
Conversation
| ui.Offset _computeOffsetForInputs(DomMouseEvent event) { | ||
| final Float32List matrix = textEditing.strategy.geometry!.globalTransform; | ||
| final FastMatrix32 fastMatrix = FastMatrix32(matrix); | ||
| fastMatrix.transform(event.offsetX, event.offsetY); |
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.
@yjbanov, fastMatrix.transform works pretty well for this use case (scaling and translation). Are there any limitations to this? Scaling and translation are probably the most commonly applied transforms to inputs, but this still work for rotation and skew, or is that something we need to account for?
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.
If this is performance-critical, I'd first check if the matrix is within the limits that FastMatrix32 can deal with and only use it then, and fallback to full matrix otherwise. I thinktransformKindOf should give you the right info.
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.
Why not https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrixReadOnly / DOMMatrix?
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.
@ditman DOMMatrixReadOnly and its instance method transformPoint could certainly work, although it's missing documentation on MDN. But the API seems well supported across different browsers. We can also init it with globalTransform which should be a 16 length array. Do you think there would be significant advantages to using the browser API? Maybe their transformPoint is more optimized?
@yjbanov I don't see any docs outlining the limitations of the FastMatrix32, do you mean it only support matrices that perform simple 2D transforms and Matrix4 should be used for 3D transforms?
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.
(@yjbanov mentioned offline that DOMMatrix might not be fully supported everywhere, so I guess we're sticking to our own implementation!)
mdebbar
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.
Thanks for putting a fix together!
lib/web_ui/lib/src/engine/pointer_binding/event_position_helper.dart
Outdated
Show resolved
Hide resolved
lib/web_ui/lib/src/engine/pointer_binding/event_position_helper.dart
Outdated
Show resolved
Hide resolved
lib/web_ui/lib/src/engine/pointer_binding/event_position_helper.dart
Outdated
Show resolved
Hide resolved
lib/web_ui/lib/src/engine/pointer_binding/event_position_helper.dart
Outdated
Show resolved
Hide resolved
| final FastMatrix32 fastMatrix = FastMatrix32(matrix); | ||
| fastMatrix.transform(event.offsetX, event.offsetY); |
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.
@yjbanov is this the right API to use for transforming an offset?
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.
I think we want to support the general case. See my comment above for more details.
| assert(targetElement == domElement, 'The targeted input element must be the active input element'); | ||
| final Float32List transformValues = inputGeometry.globalTransform; | ||
| assert(transformValues.length == 16); | ||
| final Matrix4 transform = Matrix4( |
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.
Since the transform is applied once per DOM event no extra optimization is necessary. The default transform should be fast enough.
yjbanov
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 if LGT @ditman
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
lib/web_ui/lib/src/engine/pointer_binding/event_position_helper.dart
Outdated
Show resolved
Hide resolved
ditman
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.
Can you give this a quick test with this with this app:
And see if the input is still working as expected when the glassPane is being transformed too? (for example when the app is rotated a few degrees!)
Other than that, this is similar to what we discussed. That globalTransform matrix looks HANDY! 🙏
Just tested with your demo and added an input and it works well. I actually noticed an issue on the demo (without these changes) where if the embedded app is rotated at a steep angle, clicking anywhere in a focused input blurs it. This also seems to be fixed with these changes! |
Add TODO in the place where we need to compute 3D transforms.
yjbanov
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.
mdebbar
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.
* git cherry-pick 4f3f7bb (+ conflict fixes) This cherry-pick backports flutter#41870 to Flutter 3.10. Original commit message below: [web] Fix event offset for transformed widgets (and text input nodes). (flutter#41870) Text inputs have moved outside of the shadowDOM and are now using the pointer event offset calculation algorithm that platform views use. However, transforms (e.g. scaling) applied to the input element aren't currently accounted for, which leads to incorrect offsets and clicks being registered inaccurately. This PR attempts to transform those offset coordinates using the transform matrix data that is included in the geometry information sent over to `text_editing.dart` from the framework. * Fixes flutter/flutter#125948 (text editing) * Fixes flutter/flutter#126661 (platform view scaling) * Fixes flutter/flutter#126754
* git cherry-pick 4f3f7bb (+ conflict fixes) This cherry-pick backports flutter#41870 to Flutter 3.10. Original commit message below: [web] Fix event offset for transformed widgets (and text input nodes). (flutter#41870) Text inputs have moved outside of the shadowDOM and are now using the pointer event offset calculation algorithm that platform views use. However, transforms (e.g. scaling) applied to the input element aren't currently accounted for, which leads to incorrect offsets and clicks being registered inaccurately. This PR attempts to transform those offset coordinates using the transform matrix data that is included in the geometry information sent over to `text_editing.dart` from the framework. * Fixes flutter/flutter#125948 (text editing) * Fixes flutter/flutter#126661 (platform view scaling) * Fixes flutter/flutter#126754
…127233) flutter/engine@3267fa2...f0c02ae 2023-05-19 [email protected] Roll Fuchsia Linux SDK from eal6a4HeaQon_Y4ml... to TWjmvLCOnYAUgAzvT... (flutter/engine#42168) 2023-05-19 [email protected] [macOS] Extract PlatformView mutator clip updating (flutter/engine#42164) 2023-05-19 [email protected] [web] Fix event offset for transformed widgets (and text input nodes). (flutter/engine#41870) 2023-05-19 [email protected] Roll goldctl to f808dcff91b221ae313e540c09d79696cd08b8de (flutter/engine#42166) Also rolling transitive DEPS: fuchsia/sdk/core/linux-amd64 from eal6a4HeaQon to TWjmvLCOnYAU If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
This cherry-pick backports #41870 to Flutter 3.10. * git cherry-pick 4f3f7bb (+ conflict fixes) Original commit message below: [web] Fix event offset for transformed widgets (and text input nodes). (#41870) Text inputs have moved outside of the shadowDOM and are now using the pointer event offset calculation algorithm that platform views use. However, transforms (e.g. scaling) applied to the input element aren't currently accounted for, which leads to incorrect offsets and clicks being registered inaccurately. This PR attempts to transform those offset coordinates using the transform matrix data that is included in the geometry information sent over to `text_editing.dart` from the framework. * Fixes flutter/flutter#125948 (text editing) * Fixes flutter/flutter#126661 (platform view scaling) * Fixes flutter/flutter#126754 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
…lutter#127233) flutter/engine@3267fa2...f0c02ae 2023-05-19 [email protected] Roll Fuchsia Linux SDK from eal6a4HeaQon_Y4ml... to TWjmvLCOnYAUgAzvT... (flutter/engine#42168) 2023-05-19 [email protected] [macOS] Extract PlatformView mutator clip updating (flutter/engine#42164) 2023-05-19 [email protected] [web] Fix event offset for transformed widgets (and text input nodes). (flutter/engine#41870) 2023-05-19 [email protected] Roll goldctl to f808dcff91b221ae313e540c09d79696cd08b8de (flutter/engine#42166) Also rolling transitive DEPS: fuchsia/sdk/core/linux-amd64 from eal6a4HeaQon to TWjmvLCOnYAU If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md

Text inputs have moved outside of the shadowDOM and are now using the pointer event offset calculation algorithm that platform views use. However, transforms (e.g. scaling) applied to the input element aren't currently accounted for, which leads to incorrect offsets and clicks being registered inaccurately.
This PR attempts to transform those offset coordinates using the transform matrix data that is included in the geometry information sent over to
text_editing.dartfrom the framework.Issues
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.