Skip to content

Conversation

@LongCatIsLooong
Copy link
Contributor

@LongCatIsLooong LongCatIsLooong commented May 31, 2021

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

  • 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 feature I am adding, or Hixie said the PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard flutter-dashboard bot added f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. labels May 31, 2021
@google-cla google-cla bot added the cla: yes label May 31, 2021
@LongCatIsLooong LongCatIsLooong changed the title Deprecate handle tap callback [TextSelectionControls] move the tap gesture callback into _TextSelectionHandlePainter, remove _TransparentTapGestureRecognizer. May 31, 2021
@LongCatIsLooong LongCatIsLooong requested a review from chunhtai June 4, 2021 04:25
await tester.tap(find.byKey(icon));
await tester.pump();
expect(controller.text, '');
expect(controller.selection, const TextSelection.collapsed(offset: 0, affinity: TextAffinity.upstream));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Contributor Author

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,
Copy link
Contributor

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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.

Copy link
Contributor Author

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
Copy link
Contributor

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

Copy link
Contributor Author

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);
Copy link
Contributor

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(
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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....

Copy link
Contributor

@chunhtai chunhtai left a 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(
Copy link
Contributor

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....

@fluttergithubbot fluttergithubbot merged commit 21273fd into flutter:master Jun 8, 2021
@LongCatIsLooong LongCatIsLooong deleted the deprecate-handle-tap-callback branch June 8, 2021 02:21
Comment on lines -117 to +122
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);
Copy link
Contributor

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?

Copy link
Contributor

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...

Copy link
Contributor Author

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.

@creativecreatorormaybenot
Copy link
Contributor

@justinmc
Copy link
Contributor

Thanks for fixing this @LongCatIsLooong! Good straightforward idea. This bug has been coming up over and over for 2 years.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Taps on TextField prefix/suffix

5 participants