-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Text Selection Overflow (Android) #49391
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
|
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. Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
27b127b to
4d245cd
Compare
d9ee2af to
8159345
Compare
2b785ec to
5367704
Compare
|
Golden file changes remain available for triage from new commit, Click here to view. Changes reported for pull request #49391 at sha 5340d2128b82fa100165da8b26ff6e0773a51783 |
5340d21 to
bd7f9b4
Compare
|
Golden file changes remain available for triage from new commit, Click here to view. |
|
Breaking change email:
|
|
Golden file changes remain available for triage from new commit, Click here to view. |
goderbauer
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 after i18n issue is resolved.
| || ((widget.handleSelectAll == null) != (oldWidget.handleSelectAll == null))) { | ||
| // Change _TextSelectionToolbarContainer's key when the menu changes in | ||
| // order to cause it to rebuild. This lets it recalculate its | ||
| // saved width for the new set of children. |
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.
... and also avoids animating any changes in size (or something like that)?
| // saved width for the new set of children. | ||
| _containerKey = UniqueKey(); | ||
| // If the menu items change, make sure the overflow menu is closed. This | ||
| // prevents an empty overflow menu and an incorrect saved width. |
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 incorrect saved width" part is now handled by the key above. Maybe remove that here?
| _overflowOpen = !_overflowOpen; | ||
| }); | ||
| }, | ||
| tooltip: _overflowOpen ? 'Back' : '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.
These strings need to be internationalized.
|
|
||
| // Save the width when the menu is closed. If the menu changes, this width | ||
| // is invalid, so it's important that this RenderBox be recreated in that | ||
| // case. |
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.
Maybe mention that we achieve this by providing a new key to the corresponding widget.
| } | ||
|
|
||
| class _ToolbarParentData extends ContainerBoxParentData<RenderBox> { | ||
| // Whether or not this child is painted. |
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.
nit: use /// instead of // (this is a doc-quality comment).
| } | ||
| } | ||
|
|
||
| class _TextSelectionToolbarItemsRenderBox extends RenderBox with ContainerRenderObjectMixin<RenderBox, _ToolbarParentData>, RenderBoxContainerDefaultsMixin<RenderBox, _ToolbarParentData> { |
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.
Maybe I missed it, but do you actually use anything from RenderBoxContainerDefaultsMixin?
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.
Nope not anymore it looks like, good catch!
| nextSize = Size(nextSize.width + navButton.size.width, nextSize.height); | ||
| } | ||
| } else { | ||
| navButtonParentData.shouldPaint = false; |
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.
Didn't you already do this above in line 435? Maybe change line 435 to just be:
if (renderObjectChild == firstChild) {
// Deal with the navigation button later.
return;
}
... and then figure out what to do with the nav button right here.
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.
Will do. I agree this way is misleading now that I look at it.
|
|
||
| // The navigation button is placed after iterating all children, and there | ||
| // is no need to place children that won't be painted. | ||
| if (renderObjectChild == firstChild |
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.
compare this to navButton instead of firstChild to make the code slightly more readable?
| handleCopy: canCopy(delegate) ? () => handleCopy(delegate) : null, | ||
| handlePaste: canPaste(delegate) ? () => handlePaste(delegate) : null, | ||
| handleSelectAll: canSelectAll(delegate) ? () => handleSelectAll(delegate) : null, | ||
| isAbove: fitsAbove, |
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.
How is fitsAbove updated when the textfield is in a scrollable and I scroll while the toolbar is shown? Is that even possible? What does native do?
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 noticed a couple of problems while looking into this. I'm going to create two new issues and defer them until after this PR, if that's alright with you. I checked and the behavior was the same before this PR.
- ✅ Scrolling a multiline text field properly updates fitsAbove immediately. The position of the menu changes as well as the orientation of the back button.
- ❌ Scrolling the entire TextField as an item in a ListView does not update fitsAbove. In a ListView, the text selection menu doesn't update its orientation during scrolling. #52426
- ❌ On native Android, the menu fades out during scrolling and back in afterwards, but Flutter doesn't do this. Text selection menu should fade during scroll #52425
|
Looks like cirrus is unhappy, though. |
| return FlatButton( | ||
| child: Text(label), | ||
| onPressed: () { | ||
| setState(() { |
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 there a use case that we want to close the overflow when we select a button? If i remember correctly, the callback will remove the overlay entry anyway?
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.
You're right, the overlay entry appears to be closed in all current cases. Also maybe in the future when we've got more/custom selection menu buttons, users will want to handle that themselves. I'll remove this setState.
|
Gold has detected one or more untriaged digests on patchset 28. |
1 similar comment
|
Gold has detected one or more untriaged digests on patchset 28. |
|
Golden file changes remain available for triage from new commit, Click here to view. Changes reported for pull request #49391 at sha 1f681e1b2359d2cbb6bfe4cecdbf544d958ceb5c |
1f681e1 to
9606e62
Compare
|
Gold has detected one or more untriaged digests on patchset 28. |
Description
The text selection menu overflows in some fairly common cases. This PR will fix it by handling it the same way that native does.
This PR is only for Android, and we'll need to do a similar approach for iOS.
Related Issues
#35826
Closes #50935
Tests
In material/text_selection_test.dart, I tested various overflow cases and the position of the menu above and below the anchor. I also noticed an edge case in showing the menu when a large block of text was selected, and I wrote a test for that too.
Breaking change
This is a breaking change, see the design doc.