Skip to content

Revise Android and iOS gestures on Material TextField - #24457

Merged
xster merged 10 commits into
flutter:masterfrom
xster:material-ios-tap
Dec 21, 2018
Merged

xster merged 10 commits into
flutter:masterfrom
xster:material-ios-tap

Conversation

@xster

@xster xster commented Nov 17, 2018

Copy link
Copy Markdown
Member

Fixes #23972

@xster
xster requested a review from HansMuller November 17, 2018 01:52
@zoechi zoechi added a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages p: cupertino_ui cupertino_ui package in flutter/packages labels Nov 28, 2018
@xster

xster commented Nov 30, 2018

Copy link
Copy Markdown
Member Author

Gentle ping

@HansMuller HansMuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems like a good overall approach. The semantics of the new gesture detector need to be better defined and tested.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure that "concurrent" is the best way to describe the events this widget recognizes. The next paragraph calls them event chains, maybe: A gesture detector that recognizes all of the individual tap up/down and double tap down events in a chain of events.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Reworded

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This widget is unlike a plain [GestureDetector] which only recognizes one tap or double tap in a chain of events.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

tweaked it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Key key, and pass the key along via a super call

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah thanks, I always forget it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure what the difference between "tap was held momentarily" and "a short tap" is.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Reworded this part

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it would be better to explain when this is called. I assume it's called because a tap down occurred - and onTapDown was called, and the pointer only moved a little and was held down long enough to qualify as a "long tap down".

Also: there's no shame in mentioning kDoubleTapTimeout and kDoubleTapSlop

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added some more details. It's not really related to those 2 constants.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This makes the semantics of this widget rather complicated. Where do we define the semantics of a GestureDetector that's a TextSelectionGestureDetector descendant? Or a TextSelectionGestureDetector that's a TextSelectionGestureDetector descendant? It wasn't necessary to explain this kind of thing when the translucent gesture detector was a TextField implementation detail, but now...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Can you elaborate? I'm not sure I understand. The widget structure should be more or less the same as before.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That's right, it is the same as before. But now this is a public class and so it's necessary to explain its semantics.

What happens when a TextSelectionGestureDetector has a GestureDetector descendant? Similarly what does it mean to have a TextSelectionGestureDetector with a TextSelectionGestureDetector descendant?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Did what you suggested last week. Thanks for the tip!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this means: not called if it follows a "tap up" within kDoubleTapTimeout?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We don't necessarily need to be too specific and redefine a double click in word. There's other little things like not being too far from the previous tap etc.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If the double tap timer is running, then upon seeing the second tap down, I think it should always be reset. Otherwise we could recognize an arbitrarily long sequence of taps as a double tap, so long as the intermediate ones were outside kDoubleTapSlop.

if (_doubleTapTimer != null) {
  if (widget.onDoubleTapDown != null && _isWithinDoubleTapTolerance(details.globalPosition)) {
     widget.onDoubleTapDown(details);
  }
  ...
}

Also: this logic seems like it would map a sequence of 4 quick taps to a 3 double taps? Doesn't seem right.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We talked about this offline. Also added test

@xster

xster commented Dec 12, 2018

Copy link
Copy Markdown
Member Author

Added more tests to the gesture detector

@xster

xster commented Dec 12, 2018

Copy link
Copy Markdown
Member Author

Rebased again

@HansMuller HansMuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This all looks good, mostly just some doc wordsmithing and small potatoes. We do need to sort out what it means to nest a GestureDetector or a TextSelectionGestureDetector within a TextSelectionGestureDetector

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This isn't wrong but we usually just look up the Theme as needed. InheritedWidget lookups are very cheap. Binding the theme to a final var at the top of a build method is probably the closest conventional way to do this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yup, removed this

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

An ordinary [GestureDetector] configured to handle events like tap and double tap will only recognize one or the other. This widget detects both: first the tap and then, if another tap down occurs within a time limit, the double tap.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Took your wording

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can be called for one sequence input gestures.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

but except touches that are quickly => except touches that include enough movement to not qualify as taps (e.g. ...)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Called for each distinct tap except for the second tap down of a double tap. For example, if the detector was configured [onSingleTapDown] and [onDoubleTapDown], three quick taps would be recognized as a single tap down, followed by a double tap down, followed by a single tap down.

[I hope I've gotten that right!]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Mostly took your wording. Tweaked the first sentence.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That's right, it is the same as before. But now this is a public class and so it's necessary to explain its semantics.

What happens when a TextSelectionGestureDetector has a GestureDetector descendant? Similarly what does it mean to have a TextSelectionGestureDetector with a TextSelectionGestureDetector descendant?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think what you mean is that slow double tap doesn't trigger a word selection.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

sure. Changed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not clear what this tap is for? Aren't we just checking a double tap?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Unfortunately the rebase broke the github comment. I can't figure out which line you commented on anymore

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What's the tapAt on line 3695 for? It doesn't seem to be needed for the test.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As before, what's this tap for?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This functions look like one liners that return an int. Maybe:

void _handleTapDown(TapDownDetails details) { tapCount += 1; }

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

@xster
xster force-pushed the material-ios-tap branch 3 times, most recently from f91466d to 9b92ceb Compare December 20, 2018 02:34
@xster

xster commented Dec 20, 2018

Copy link
Copy Markdown
Member Author

Rebased again

@HansMuller HansMuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. There are still two open questions about what looked to me like unnecessary test taps.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems odd to say a "gesture detector to detect". Maybe: "A gesture detector that matches non-exclusive ...".

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Changed to respond which is a fairly standard word

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Need to update this because child is required to be non-null.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah, big catch. Thanks!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A comment that explained the significance of 300ms would be helpful (I assume 300ms > double tap interval).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

two slow taps do not ...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What's the tapAt on line 3695 for? It doesn't seem to be needed for the test.

@xster
xster merged commit b3b764c into flutter:master Dec 21, 2018
@xster
xster deleted the material-ios-tap branch December 21, 2018 00:54
@sdolski

sdolski commented Jan 15, 2019

Copy link
Copy Markdown

@xster This pull request destroys the material search functionality.
After displaying a search result, it is not possible to select the search input field.

Steps to reproduce:

  1. start flutter_gallery from the master branch
  2. Open material search demo
  3. Find and select an integer => the result is shown
  4. Try to change the search query => Input field is not focusable

Would be great if this would be fixed.

@sdolski

sdolski commented Jan 15, 2019

Copy link
Copy Markdown

After further analysis it seems like not only the material search is broken. This affects all textfields.
I can not select any textfield.

Steps to reproduce:

  1. start flutter_gallery from the master branch
  2. Open material text fields demo
  3. Try to select any textfield => No text fields is focusable

@zoechi

zoechi commented Jan 16, 2019

Copy link
Copy Markdown
Contributor

@sdolski #26624 with reference to #26628 might be related

@xster

xster commented Jan 16, 2019 •

Copy link
Copy Markdown
Member Author

Sorry for the breakage. For posterity, this PR is unrelated. Please follow along in #26563.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Aug 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. p: cupertino_ui cupertino_ui package in flutter/packages p: material_ui material_ui package in flutter/packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Double-tap to select word on Material TextField

5 participants