-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Add support for separators in text copied from SelectableRegion
#121112
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
separator field to SelectionAreaseparator field to SelectionArea and allow composition of SelectableRegions
|
It wasn't sitting well with me that nested With composition it is now possible to have the following widget tree import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: SelectionArea(
separator: '\n',
child: Column(
children: <Widget>[
Text('How are you?'),
SelectionArea(
separator: ' ',
child: Row(
children: <Widget>[
Text('Good, and you?'),
Text('Fine, thank you.'),
],
),
),
],
),
),
),
),
);
}
copy/paste this |
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.
This API will hardcode the behavior for entire selection area which is not something we want to do. I think the separator should be added into MultiSelectableSelectionContainerDelegate and then each multichild widget such as Row or column should wrap its own selection container and set the separate accordingly.
Another thing to consider is whether we should convert to copy html text instead, some desktop platforms can store html into clipboard, but i have not tested them all.
|
This behavior should definitely be developer configurable. I don't think we should do anything web-specific here such as copying html. I'll look into doing something with rows/columns. |
|
Actually, I think these changes already handle that issue. You can now nest I'm not sure touching anything else makes sense. |
|
If we did go the route of MultiChild widgets handling the separation, we would probably need to create |
I have not looked into this in more detail but I think you can store html into clipboard in macos https://developer.apple.com/documentation/appkit/nspasteboardtypehtml?language=objc This will be useful to store rich text and be able to reuse in other application that can handle pasting html |
No, The Flex can wrap the subtree with a selection container similar to how scrollable does that. It conditionally wrap the selection container only if there is another selection container above. |
I think you meant SelectionContainer, I don't think we have good support for nesting SelectionArea. |
|
I made nesting |
|
An issue I'm seeing with that approach is |
|
What exactly is the issue if this code works? import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: SelectionArea(
separator: '\n',
child: Column(
children: <Widget>[
Text('How are you?'),
SelectionArea(
separator: ' ',
child: Row(
children: <Widget>[
Text('Good, and you?'),
Text('Fine, thank you.'),
],
),
),
],
),
),
),
),
);
} |
You can make column and row a statelessWidget and in the build method wrapps SelectionContainer.
there are two issues:
|
|
Thank you for explaining. This is my first PR on the flutter framework itself so I'm very new to understanding how all these pieces fit together. I wasn't sure if changing the inheritance of |
|
I don't think so, as long as the customer tests do not fail, we don't consider it a breaking change. Also I don't think we promise the type of a widget to stay the same as long as it is a still a |
|
Although it looks like Google testing is passing now??? |
|
Have we run benchmarks on this? Making Row and Column into stateful widgets seems like a really expensive change that will have huge impact across the board on Flutter apps. I would expect this to increase build times and increase memory usage. These are really basic widgets used all over the place. |
|
@Hixie Yeah I wasn't too sure about making |
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 don't think we should directly make Column into StatefulWidget, You can create a wrapper widget maybe call _SelectedTextSeparator, which is a statefulwidget. the Column should remain a stateless widget and only wrap the _FlexBase with _SelectedTextSeparator if there is a selectionContainer
|
I'm very skeptical about any changes to Row or Column at all here. These are really core widgets that should not need to know about text selection at all, IMHO. They're just ways to configure the RenderFlex render object. |
|
I agree with column should be simple, but that means people would have to do something extra to make column work correctly when selected. think people would likely ignored it and make app with bad user experience. Another way to solve this is to make the selection container smart enough to know whether to add a |
|
That might be more reliable than having to teach every render object (or widget that wraps a render object) how to handle selection though. For example, how would we make it work for |
|
Should we just go back to what I had before where the |
|
I assume you meant adding an API in MultiSelectableSelectionContainerDelegate to customize how separator are inserted? I think this is what we can do, in MultiSelectableSelectionContainerDelegate.getSelectedContent when we concatenate SelectedContent, we should compare the coordinate of each selectable and add '\n' or '\t'. I think this should be enough for fixing most of the use cases. If people really want to change the separator their way, we can expose an API in MultiSelectableSelectionContainerDelegate that takes a list of Selectables and return a SelectedContent. This API will be called in getSelectedContent to get the result. |
|
Comparing coordinates seems fragile and like it might have a bunch of edge cases. What I meant is just doing what the original PR did which let you do this: import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: SelectionArea(
separator: '\n',
child: Column(
children: <Widget>[
Text('How are you?'),
SelectionArea(
separator: ' ',
child: Row(
children: <Widget>[
Text('Good, and you?'),
Text('Fine, thank you.'),
],
),
),
],
),
),
),
),
);
} |
|
This proposal would require people to manually wraps the widget. I think we should at least have some solution that would automatically do that for most of the case. Based on the discussion so far it seems comparing the rect seems to be a more reliable solution |
|
Users already have to wrap the widgets in |
|
Do we even have access to the information we need to make the separator logic automatic in |
|
There is a size https://api.flutter.dev/flutter/rendering/Selectable/size.html |
|
@Rexios80 @chunhtai @Hixie In the interests of doing the simplest thing possible to address #104548. I think we should implement @Rexios80 's very first commit fff1cae. This implements the separator, is minimally invasive, is backwards compatible, and we could get it in now. Doing something more sophisticated obviously requires more thought and is more involved. A more sophisticated solution could also be in the API when the time comes. For us, it's really important to fix #104548, otherwise copying a region of text and pasting it somewhere is nearly useless because the text is jammed together. |
|
@dsyrstad What about everything up to bece955? That would be these changes: https://github.com/flutter/flutter/pull/121112/files/bece9551b235253d69d4c35875706d95a41f954d |
@Rexios80 I'm not sure what the |
|
That makes nested |
@Rexios80 Great, that looks good to me! |
|
Closing this PR in favor of #126835 |
Right now, copying text in a
SelectionAreacopies it with no separation. SinceSelectionAreais very useful with vertical lists ofTextwidgets this is not ideal. This PR adds aseparatorfield toSelectionAreaso that developers can add separators such as newlines between selectedTextwidgets.#104548
I added a new test for this
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.