-
Notifications
You must be signed in to change notification settings - Fork 29.8k
[TextSelectionControls] move the tap gesture callback into _TextSelectionHandlePainter, remove _TransparentTapGestureRecognizer.
#83639
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
_TransparentTapGestureRecognizer.
| await tester.tap(find.byKey(icon)); | ||
| await tester.pump(); | ||
| expect(controller.text, ''); | ||
| expect(controller.selection, const TextSelection.collapsed(offset: 0, affinity: TextAffinity.upstream)); |
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 this change?
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 before the change the tap event actually altered the selection. Now it's only hitting the button and not the text field so that should be expected.
| MaterialApp( | ||
| home: Scaffold( | ||
| body: TextField( | ||
| //focusNode: focusNode, |
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.
remove?
| /// | ||
| /// Both regular taps and long presses invoke this callback, but a drag | ||
| /// gesture won't. | ||
| /// A callback that's optionally invoked when a selection handle is tapped. |
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.
| /// A callback that's optionally invoked when a selection handle is tapped. | |
| /// A callback that's optionally invoked based on platforms when a selection handle is tapped. |
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 ultimately this depends on what kind of selection control you're using, so it's not really platform-dependant. Even in TextField's implementation you can override textSelectionControl so it's still up to the developer.
Anyways IMO we should deprecate this callback and let the TextSelectionControl implementation decides how the handles should be built and what interactions it should support. Currently it does not have enough information (as it doesn't have access to the EditableTextState that builds the selection overlay).
| /// large for tapping (as it's not meant to be tapped) so it does not call | ||
| /// [onSelectionHandleTapped] even when tapped. | ||
| /// {@endtemplate} | ||
| // See https://github.com/flutter/flutter/issues/39376#issuecomment-848406415 |
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 avoid pointing to a github link in API doc
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 last 2 lines are prefixed by "//".
| /// The top left corner of this widget is positioned at the bottom of the | ||
| /// selection position. | ||
| Widget buildHandle(BuildContext context, TextSelectionHandleType type, double textLineHeight); | ||
| Widget buildHandle(BuildContext context, TextSelectionHandleType type, double textLineHeight, VoidCallback? onTap); |
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.
document what onTap is
| bottom: padding.bottom, | ||
| ), | ||
| child: widget.selectionControls!.buildHandle( | ||
| child: widget.selectionControls.buildHandle( |
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 it possible we wraps the widget from the buildhandle with the gesturedetector here? It feels weird that we ask the widget to build the gestureDetector.
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.
It's the selection control of the user's choice that builds the handle right? The selection control decides the style of the handles and the types of interactions it suppoorts.
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.
It's a bit subtle that onTap should only work on the "knob" , while drag gestures should work on both the knob and the rectangle attached to the knob.
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.
That is an unfortunate how onSelectionHandleTapped behave differently based on the implementation of TextSelectionControls.
I am ok with this approach if we can deprecate the onSelectionHandleTapped at some point....
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
| bottom: padding.bottom, | ||
| ), | ||
| child: widget.selectionControls!.buildHandle( | ||
| child: widget.selectionControls.buildHandle( |
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.
That is an unfortunate how onSelectionHandleTapped behave differently based on the implementation of TextSelectionControls.
I am ok with this approach if we can deprecate the onSelectionHandleTapped at some point....
| Widget buildHandle(BuildContext context, TextSelectionHandleType type, double textLineHeight); | ||
| /// | ||
| /// The supplied [onTap] should be invoked when the handle is tapped, if such | ||
| /// interaction is allowed. As a counterexample, the default selection handle | ||
| /// on iOS [cupertinoTextSelectionControls] does not call [onTap] at all, | ||
| /// since its handles are not meant to be tapped. | ||
| Widget buildHandle(BuildContext context, TextSelectionHandleType type, double textLineHeight, VoidCallback? onTap); |
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.
@LongCatIsLooong This is a breaking change 😓 How are we supposed to deal with packages that should work with multiple versions of Flutter that call buildHandle.
https://pub.dev/packages/flutter_math_fork is such a package and now it cannot work.
The change should have been [VoidCallback? onTap], otherwise it is breaking. Should I make a PR and we cherry pick a hot fix for the dev channel?
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.
So beta and stable have 3 positional parameters and dev has 4 positional parameters...
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.
Yeah the proposed change sounds good to me. Sorry for the breakage!
Per the breaking change policy this is not a breaking change so I'd recommend contributing tests to flutter/tests to prevent future breakage.
I'm not sure we have a process for cherry-picking a commit to the dev channel. See https://github.com/flutter/flutter/wiki/Flutter-Cherrypick-Process. Maybe we should add that dev build to https://github.com/flutter/flutter/wiki/Bad-Builds.
|
@LongCatIsLooong This is how I tried to fix it: simpleclub/flutter_math@7c13f1e#diff-0cee011dc67be19dc0c38a0f8a915554273b9f7f1b4c38402db2112d16a7d596R175 |
|
Thanks for fixing this @LongCatIsLooong! Good straightforward idea. This bug has been coming up over and over for 2 years. |
For iOS/Android behaviors see #39376 (comment)
Fixes #39376.
If you had to change anything in the flutter/tests repo, include a link to the migration guide as per the breaking change policy.
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.