Skip to content

Add TextField triple tap/click gestures - #119046

Merged
auto-submit[bot] merged 50 commits into
flutter:masterfrom
Renzo-Olivares:triple-tap-select
Mar 27, 2023
Merged

auto-submit[bot] merged 50 commits into
flutter:masterfrom
Renzo-Olivares:triple-tap-select

Conversation

@Renzo-Olivares

@Renzo-Olivares Renzo-Olivares commented Jan 24, 2023 •

Copy link
Copy Markdown
Contributor

This PR adds the following triple tap/click gestures to select text in a TextField to match the native platform behavior.

  • Triple tap/click to select a paragraph in multi-line text fields. (Windows/Android/Fuchsia/iOS/macOS)
  • Triple tap/click to select a line in multi-line text fields. (Linux)
  • Triple tap/click to select all text in single-line text fields. (All)
  • Triple click + drag to select text in paragraph blocks. (Windows/Android/Fuchsia/iOS/macOS)
  • Triple click + drag to select text in line blocks. (Linux)

Fixes #63576

  • 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 this PR is [test-exempt].
  • All existing and new tests are passing.

@flutter-dashboard flutter-dashboard Bot added a: text input Entering text in a text field or keyboard related problems p: cupertino_ui cupertino_ui package in flutter/packages p: material_ui material_ui package in flutter/packages framework flutter/packages/flutter repository. See also f: labels. labels Jan 24, 2023

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.

Perhaps remove the doc comment reference to [int] as it's a generic type? Can follow the style of TextBoundary (or even CharacterBoundary which only has class level doc comments...).

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 guess these magic numbers could be avoided with constants (also needed in isLineTerminator).

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.

Same as above on 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.

Looking at TextPainter, the list of what's considered a newline is different: no 0xD on its own, plus 0x2028/0x2029.

  static bool _isNewline(int codePoint) {
    switch (codePoint) {
      case 0x000A:
      case 0x0085:
      case 0x000B:
      case 0x000C:
      case 0x2028:
      case 0x2029:
        return true;
      default:
        return false;
    }
  }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hmm I got the list from here https://www.unicode.org/standard/reports/tr13/tr13-5.html. I added 0x2028 and 0x2029 I had left out.

Comment thread packages/flutter/lib/src/services/text_boundary.dart Outdated
Comment thread packages/flutter/lib/src/widgets/editable_text.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_editing_intents.dart Outdated
@Renzo-Olivares

Copy link
Copy Markdown
Contributor Author

@tgucio sorry this wasn't ready for review. This depends on another PR so some files are not related to this one. Appreciate the feedback nonetheless :)

@tgucio

tgucio commented Jan 25, 2023

Copy link
Copy Markdown
Contributor

@Renzo-Olivares this is a very welcome PR so I thought I'd share review comments early but it looks like I missed the "Draft" status :).

@Renzo-Olivares
Renzo-Olivares marked this pull request as ready for review February 4, 2023 00:26
@Renzo-Olivares

Renzo-Olivares commented Feb 4, 2023 •

Copy link
Copy Markdown
Contributor Author

This is ready for an initial review with a caveat: I'm still addressing an edge case where the CupertinoTextSelectionControls selection handles blocks the TextSelectionGestureDetector below it. This will happen when the tap begins at a word edge, on double tap the selection handles will pop up and block the gesture detector below it, so the triple tap is never registered.

@Renzo-Olivares Renzo-Olivares changed the title Add TextField triple tap gestures Add TextField triple tap/click gestures Feb 4, 2023
@Renzo-Olivares
Renzo-Olivares requested a review from tgucio February 4, 2023 01:08

@justinmc justinmc 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 with nits 👍

The main thing is just a TODO that I commented on, not sure if you plan to do that in this PR or a new one.

It's really great that this PR is so straightforward with the addition of your paragraph boundary work and refactoring. Before that it was such a mess trying to support triple tap!

Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated

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.

Why do iOS and Mac fall through to the same behavior as Windows if the comments above seem to describe their behavior differently?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

To me it looked like iOS/macOS/Windows increased their tap count infinitely but they handled taps past 3 differently.

iOS and macOS don't handle anything past a third tap. The selection is retained at the paragraph that was selected on the triple tap.

Windows alternates between double click and triple click when going past the third tap. Alternating between selecting the word or paragraph at the position.

Let me know if I can clarify this further.

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's ok as-is. I looked through the code to see how consecutiveTapCount is used and it makes sense that these all return null but later have different behavior.

@Renzo-Olivares Renzo-Olivares Feb 10, 2023 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think it makes more sense now after introducing an effectiveConsecutiveTapCount.

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.

Ah I guess some tests that previously tapped very soon after a double tap might behave differently now. We should watch out for this breaking Google tests or anything else. Though it looks like Google tests are currently passing 👍

@Renzo-Olivares Renzo-Olivares Feb 6, 2023 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, how it worked previously is that the double tap timer on TextSelectionGestureDetector would reset the count to 0 after every double tap for every platform. So some test behavior changed a bit, but google tests look good so far.

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.

Is your plan to do this in another PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm hoping that I can fix it in this one. But if the fix becomes overly complex then I'll probably make it into another PR.

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.

Just wanted to draw attention to this again in case you forgot about 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.

It's a bummer that we have to duplicate all of these tests for Cupertino and Material, but I guess they won't work on EditableText because of the code changes in text_selection.dart.

Someday we need to make it easier to share these kinds of tests!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, it would definitely help with velocity if we only had to write these tests once.

Comment thread packages/flutter/test/widgets/text_selection_test.dart Outdated

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's nice that this test still works (with minor changes) and makes a lot of sense with the addition of triple tap.

Comment thread packages/flutter/lib/src/widgets/editable_text.dart Outdated
Comment thread packages/flutter/lib/src/widgets/editable_text.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated

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.

nit: maybe it's easier to write the if clauses, if the local variable is for "effective tap count".

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.

or maybe move the logic to the static method you created later in this file that turns the raw tap count to the effective tap count.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sorry i'm not sure I follow, can you elaborate? The static method I created later in the file is meant to tell the gesture recognizer what its ceiling is for the consecutive tap count before it resets it to 0.

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.

is it possible to repurpose _getDefaultMaxConsecutiveTap so it takes the raw consecutive tap count and returns the "effective" tap count? For instance for windows the conversion would look like input < 2 ? input : 2 + input % 2 and for other platforms it's max(input, 3).

@Renzo-Olivares Renzo-Olivares Feb 9, 2023 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In this scenario if we are repurposing _getDefaultMaxConsecutiveTap are we then setting the ceiling for consecutive tap count on the recognizer to null for all platforms?

In that case I think we can do this.

  static int _getEffectiveConsecutiveTapCount(int rawCount) {
    switch(defaultTargetPlatform) {
      case TargetPlatform.android:
      case TargetPlatform.fuchsia:
      case TargetPlatform.linux:
        return rawCount <= 3 ? rawCount : 0 + (rawCount % 3 == 0 ? 3 : rawCount % 3);
      case TargetPlatform.iOS:
      case TargetPlatform.macOS:
        return math.min(rawCount, 3);
      case TargetPlatform.windows:
        return rawCount < 2 ? rawCount : 2 + rawCount % 2;
    }
  }

Definitely makes the if cases much better! Thanks for the code and suggestion!

Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated

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 selectParagraph API simply calls selectParagraphsInRange API then I think we should have just one method exposed doing both, unless one of them does something specific using a private field like selectWord / selectWordsInRange in editable.dart.

Also, shouldn't this be in editable.dart together with other select* methods?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think I want to avoid adding more methods to RenderEditable that mutate the selection, and instead have it provide selection calculations that EditableText uses to mutate its selection.

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.

For design clarity they should all be in a single place I think. It makes sense to move the selection modifying methods to EditableText but it looks like they were in RenderEditable for years so it'd be a breaking change. Wondering if @LongCatIsLooong or @justinmc may have some thoughts?

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 really like the idea of separating the calculation of text related stuff from its mutation. I hope we can get to where we have a clear place for each. For example, if some Flutter dev wants to create a button that selects the nearest 3 paragraphs or something, it would be nice to be able to give them access to our paragraph selection logic without making them actually make a change to an EditableText.

For now though it looks like Renzo has made selectParagraphsInRange and selectParagraph private and moved them to text_selection.dart. That's definitely fine for now since we can always change it later.

Comment thread packages/flutter/lib/src/widgets/editable_text.dart Outdated
Comment thread packages/flutter/test/material/text_field_test.dart Outdated
@Renzo-Olivares

Copy link
Copy Markdown
Contributor Author

Tests currently failing due to #120629

@Renzo-Olivares

Renzo-Olivares commented Feb 17, 2023 •

Copy link
Copy Markdown
Contributor Author

Friendly bump, still looking for a review. The failing tests should clear up when flutter-team-archive/engine#39693 is merged.

Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated

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.

Nit: maybe a bit easier to understand like this:

    final TextSelection newSelection = isFromParagraphBeforeToParagraph
        ? TextSelection(baseOffset: fromRange.start, extentOffset: toRange.end),
        : TextSelection(baseOffset: fromRange.end, extentOffset: toRange.start);

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.

Also, wondering if we may ever get weird cases here e.g. both ranges starting at the same offset but with different lengths, overlapping ranges, empty ranges etc.

@justinmc justinmc 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 with nits.

I left one comment about _getEffectiveConsecutiveTapCount.

Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated
Comment thread packages/flutter/lib/src/widgets/text_selection.dart Outdated

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.

Would it make sense to put the logic in _getEffectiveConsecutiveTapCount on the Details classes directly somehow? Looking at these calls, I'm thinking that it would be easy for someone to introduce a bug in the future by forgetting about _getEffectiveConsecutiveTapCount and using consecutiveTapCount directly.

However, if it doesn't make sense for the details to be concerned about this kind of stuff, then I agree with how it is now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I can add some comments about this but I think the details classes are platform agnostic at the moment and this particular use of _getEffectiveConsecutiveTapCount is only for text selection gestures.

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.

Ok that sounds good 👍

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.

Just wanted to draw attention to this again in case you forgot about it.

Comment thread packages/flutter/test/cupertino/text_field_test.dart Outdated

@tgucio tgucio 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

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.

indentation nit: tab == 2 spaces I think?

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.

Is this kind of ternary supposed to be indented 2 or 4 spaces? I think I've done both on different occasions because I wasn't sure...

@Renzo-Olivares Renzo-Olivares Mar 16, 2023 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm actually not too sure, but I just followed the convention used in this file which seems to be 4 spaces.

final TextSelection? fromSelection = renderEditable.hasFocus
? null
: const TextSelection.collapsed(offset: 0);

final TextSelection? fromSelection = renderEditable.hasFocus
? null

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 do you mean by this line?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Similar explanation here: #119046 (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.

Ah sorry.

@LongCatIsLooong LongCatIsLooong Mar 10, 2023 •

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.

nit: !delegate.selectionEnabled to avoid nested ifs (so readers don't have to find the closing bracket).

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.

Do touch devices work on these platforms?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not aware of any touch devices on macOS, but there definitely is on Windows.

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 you remove the 0 + ....? Or maybe 1 + (rawCount - 1) % 3?

@Renzo-Olivares Renzo-Olivares Mar 14, 2023 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think I can remove this 0, I'll check on 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.

Is that because the selection control has a tap recognizer? Can you triple tap recognizer declare victory immediately?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It could but the recognizer never receives the third tap because the selection handles overlay absorb the pointer immediately when they pop up.

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.

absorb the pointer immediately

Do you mean the text field's hitTest method won't be called, or it will be called, but the selection handle will declare victory immediately in the arena?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I mean it won't be called, so TextSelectionGestureDetector does not get to participate in the arena at all.

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.

Were you able to fix this? hitTest should be called for the selection gesture recognizers right?

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

Can you explain again (or link me) why hiding the handles until kDoubleTapTimeout after the double tap wasn't viable? I think this solution is pretty clean, but I want to make sure if we're going to be adding new public API to support it.

Otherwise my comments are pretty small stuff.

Comment on lines +3347 to +3345
void toggleSelectionHandleOverlayGestureHandling() {
_selectionOverlay ??= _createSelectionOverlay();
_selectionOverlay!.handlesAllowPointers = !_selectionOverlay!.handlesAllowPointers;
_selectionOverlay!.rebuildHandles();
}

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.

Nit: Maybe _selectionOverlay should call rebuildHandles itself when handlesAllowPointers changes? I'm thinking about how to best architect this to avoid problems like forgetting to call rebuild in the future.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That makes sense to me since this method won't really work without a rebuild.

// The consecutive tap tracker has reset.
//
// This triggers when the timer between two taps has elapsed, or when
// the previous pointers buttons does not match the most recent pointers

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.

"does" => "do" I think.

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.

Also should "pointers" be "pointers'" (apostrophe for possession)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think it might actually be "pointer's" I think "pointers'" implies multiple pointers buttons? Not 100% sure though.

// tracked in [addAllowedPointer].
double? get slopTolerance;

// The consecutive tap tracker has reset.

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.

Nit: Maybe "Called when the consecutive..."

SchedulerBinding.instance.addPostFrameCallback((Duration duration) {
_buildScheduled = false;
// If the current editableText state is not available we should
// exit out. This can occur at the end of tests, or when the

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.

Nit: "exit out" => "return".

}

/// {@macro flutter.widgets.SelectionOverlay.rebuildHandles}
void rebuildHandles() {

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.

Above I suggested maybe calling this on a setter instead of from EditableText. If so, then maybe we wouldn't have to expose this new method at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point!

}
_buildScheduled = true;
SchedulerBinding.instance.addPostFrameCallback((Duration duration) {
_buildScheduled = false;

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.

Is there any need to check if you've been disposed here in this callback too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm unsure about this. I added an assert(context.mounted) in _rebuildHandles. I see that's what done in some methods like showToolbar.

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.

Is this kind of ternary supposed to be indented 2 or 4 spaces? I think I've done both on different occasions because I wasn't sure...

@Renzo-Olivares

Renzo-Olivares commented Mar 16, 2023 •

Copy link
Copy Markdown
Contributor Author

Can you explain again (or link me) why hiding the handles until kDoubleTapTimeout after the double tap wasn't viable? I think this solution is pretty clean, but I want to make sure if we're going to be adding new public API to support it.

Otherwise my comments are pretty small stuff.

I thought the delay was a bit too noticeable, especially since the highlight pops up on double tap as well. Here is the repo with how that would look like https://github.com/Renzo-Olivares/flutter/commits/triple-tap-select-delay-handles, this might require some more specifics but this was a quick POC. It's on top of this PR but I disabled all of the ignore-pointer related functionality.

The delay is not noticeable on subsequent double taps.

Delay No Delay
Screen.Recording.2023-03-15.at.7.33.11.PM.mov
Screen.Recording.2023-03-15.at.7.36.46.PM.mov

@justinmc justinmc 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 👍

@Renzo-Olivares Renzo-Olivares added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 27, 2023
@auto-submit
auto-submit Bot merged commit 04f6acd into flutter:master Mar 27, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 28, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 28, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 28, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 28, 2023
@reidbaker reidbaker mentioned this pull request Mar 28, 2023
8 tasks done
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 10, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: text input Entering text in a text field or keyboard related problems autosubmit Merge PR when tree becomes green via auto submit App 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.

Support selecting all text on triple click

4 participants