-
Notifications
You must be signed in to change notification settings - Fork 27.4k
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
Implement SelectionArea triple click gestures #144563
Implement SelectionArea triple click gestures #144563
Conversation
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.
Looks good overall. This is another clear example of how we don't want to duplicate this kind of complex logic in editable text.
Is this triple click and triple click + drag behavior identical on all platforms?
@@ -424,6 +428,9 @@ class RenderParagraph extends RenderBox with ContainerRenderObjectMixin<RenderBo | |||
return result; | |||
} | |||
|
|||
/// The [Selectable]s created by this [RenderParagraph] instance. | |||
List<Selectable>? get selectables => _lastSelectableFragments; |
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.
Any reason we shouldn't expose this?
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 got around exposing this by instead exposing a method that returns a bool
. That keeps the actual Selectable
s private.
if (wordBoundary != null) { | ||
assert(wordBoundary.wordStart.offset >= range.start && wordBoundary.wordEnd.offset <= range.end); | ||
if (_selectableContainsOriginWord && existingSelectionStart != null && existingSelectionEnd != null) { | ||
if (textBoundary != null) { |
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 it possible to remove a layer of nesting by reversing this if
?:
if (textBoundary == null) {
return targetPosition ?? position;
}
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.
Here and in all the similar methods below.
} | ||
} | ||
} | ||
return targetPosition ?? position; | ||
} | ||
|
||
SelectionResult _updateSelectionEdgeByWord(Offset globalPosition, {required bool isEnd}) { | ||
TextPosition _updateSelectionEndEdgeByMultiSelectableTextBoundary( |
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: Just a drive by comment, but is there any code that could be shared between these 4 similar methods?
return _getResultBasedOnParagraphBoundary(positionInFullText); | ||
} | ||
|
||
final int _placeholderLength = 1; |
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 never changes I guess? Should it be static const
?
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.
Also maybe leave a comment explaining it.
@@ -713,3 +721,548 @@ class Text extends StatelessWidget { | |||
} | |||
} | |||
} | |||
|
|||
// In practice some selectables like widgetspan shift several pixels. So when |
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 didn't realize that, do you know why?
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.
Not exactly sure, but this was introduced in this change #130043 .
@@ -647,14 +650,16 @@ class Text extends StatelessWidget { | |||
effectiveTextStyle = effectiveTextStyle!.merge(const TextStyle(fontWeight: FontWeight.bold)); | |||
} | |||
final SelectionRegistrar? registrar = SelectionContainer.maybeOf(context); | |||
final GlobalKey? textKey = registrar == null ? null : GlobalKey(); | |||
final _SelectableTextContainerDelegate? selectionDelegate = registrar == null ? null : _SelectableTextContainerDelegate(textKey!); |
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.
When does it happen that there is no SelectionContainer above this, but we still need selectionDelegate?
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 would never happen, if I am understanding correctly. The delegate will be null
when there is no SelectionContainer
above this.
} | ||
} | ||
if (globalRectsContainsPosition) { | ||
if (paragraph.selectables != null && !paragraph.selectables!.contains(selectables[index])) { |
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.
Can you explain (to me) the difference between selectables
and paragraph.selectables
? This Text may just be a part of a greater paragraph above?
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.
Yeah, i'll try to explain in depth. So say we have the following Text
widget wrapped in a SelectionArea
.
Text.rich( // SelectionContainer
TextSpan(
children: <InlineSpan>[
TextSpan(text: 'This is some text before a widgetspan. '), // selectableA
WidgetSpan(
child: Text('This is some text in a widgetspan.'), // selectableC
), // SelectionContainer
TextSpan(text: ' This is some text after a widgetspan.'), // selectableB
],
),
),
Internally the RenderParagraph
of the root Text
widget will create 2 selectables, one belonging to the text before the WidgetSpan
, and the other belonging to the Text
after the WidgetSpan
. The root RenderParagraph
will not create a selectable for the inline WidgetSpan
because we explicitly skip placeholders when iterating through the text to create its selectables. These two selectables are registered to the SelectionContainer
belonging to that root Text
widget. The RenderParagraph
belonging to the Text
widget in the WidgetSpan
will create one selectable fragment representing its entire text. This selectable fragment is then registered to the SelectionContainer
belonging to the WidgetSpan
, and that container registers itself to the container of the root Text
widget above it. Then the root container registers itself to the root SelectionArea
s registrar.
This is how it ends up breaking down:
SelectionArea.selectables = [ RootTextWidgetSelectionContainer ]
RootTextWidgetSelectionContainer.selectables = [ selectableA, WidgetSpanSelectionContainer, selectableB ]
WidgetSpanSelectionContainer.selectables = [ selectableC ]
RootRenderParagraph.selectables = [ selectableA, selectableB ]
WidgetSpanRenderParagraph.selectables = [ selectableC ]
I use this breakdown to determine if a given selectable is a placeholder (WidgetSpan
), or if it belongs to the root text. Let me know if this was clear. Definitely open to alternatives to adding RenderParagraph.selectables
since it could potentially be used incorrectly.
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.
Thanks for the thorough explanation. Where does paragraph.selectables get populated? I'm not seeing it at first glance.
Also, why didn't we need this infrastructure before this PR? It seems like you would need this for selecting by line etc. also.
for (int index = 0; index < selectables.length; index += 1) { | ||
bool globalRectsContainsPosition = false; | ||
if (selectables[index].boundingBoxes.isNotEmpty) { | ||
for (final Rect rect in selectables[index].boundingBoxes) { |
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 method could be a performance bottleneck in a large document, but currently that's true of a lot of places, so probably not a big deal.
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.
Yeah, i'm also not the biggest fan of this, but couldn't come up with a better way to do this logic. What I might be able to do is instead of checking every selectable, I can check only the placeholders which are guaranteed to only have one item in their boundingBoxes
list because they are SelectionContainer
s
flutter/packages/flutter/lib/src/widgets/selection_container.dart
Lines 203 to 204 in 7482962
@override | |
List<Rect> get boundingBoxes => <Rect>[(context.findRenderObject()! as RenderBox).paintBounds]; |
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.
Adding onto my last comment, a placeholder is only guaranteed to have one item in their boundingBoxes
list if it is a SelectionContainer
which is only guaranteed when the placeholder is a Text
widget itself.
I just tried doing some QA work here. This one seems to be a bug: Screencast.from.2024-03-05.13-24-04.webmCodeconst SelectionArea(
child: Text.rich(
WidgetSpan(
child: Column(
children: <Widget>[
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
],
),
),
),
), And this one is a subtle difference between the native behavior on Linux as an FYI, but I think it's probably not worth fixing. It looks like this PR behaves correctly like Mac does natively, and that behavior seems more intuitive to me IMO. Screencast.from.2024-03-05.13-22-10.webmCodeconst SelectionArea(
child: Text.rich(
TextSpan(text: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
),
),
|
c227d3f
to
29e71b4
Compare
This is ready for another review. It fixes the case pointed out here #144563 (comment) . Regarding the linux behavior, I'll make a follow up PR for that. |
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'm still trying to break your PR in QA but the code is looking good.
I confirmed that my previous bug is fixed, thank you! I think this might be a bug when I triple click and drag into the long line at the top in this video. Notice how, especially towards the end of the video, the selection flashes and I'm sometimes able to get the selection to not span the whole line. Maybe it's just a weird case with what I'm doing...
Screencast.from.2024-03-18.14-47-16.webm
This one is probably unrelated to your PR, but notice how triple clicking to the side of the text on the short lines doesn't select the line, but on native it does:
Native Linux TextEdit | Flutter |
---|---|
Screencast.from.2024-03-18.14-45-35.webm |
Screencast.from.2024-03-18.14-43-47.webm |
Code in both cases
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
SelectionArea(
child: Text.rich(
WidgetSpan(
child: Column(
children: <Widget>[
Text('Text widget.I am a Text widget.I am a Text widget.I am a Text widget.I am a Text widget.I am a Text widget.I am a Text widget.I am a Text widget. Text widget.I am a Text widget.I am a Text widget.I am a Text widget.I am a Text widget.I am a Text widget.I am a Text widget.I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
Text('I am a Text widget.'),
],
),
),
),
),
],
),
),
);
}
}
} | ||
} | ||
|
||
class _SelectableTextContainer extends StatefulWidget { |
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: This makes me think of SelectableText the widget, should it be renamed? No worries if you disagree, "selectable text" is a pretty generic term, it's fine either way.
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.
We might want to move this out of here eventually, and put it with SelectableText
. But I think its fine for now since its private. Something to think about for later might be whether we want Text
to be completely un-selectable in all cases even when under a SelectionArea
, and then SelectableText
will be the text component that is selectable. Having them both selectable, makes me wonder why they both should exist besides historical reasons/breaking changes.
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.
Not to start an unrelated naming debate in this comment thread, but I worry about the existing problem where users (especially on the web) use Text widgets expecting them to be selectable when they're not... Not sure exactly how we should organize/name this though. I agree this PR is fine as-is since it's private.
If we do keep both Text and SelectableText though, it would be cool to implement SelectableText simply as a wrapper of Text and SelectionArea.
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 think that's still the plan for SelectableText
with #104547 (Using Text
and SelectionArea
). I think at that time we should evaluate whether we should move this _SelectableTextContainer
to SelectableText
. I agree though it is a bit confusing for someone that is going to dig into this code.
@justinmc Thanks for the review! The first bug you pointed out looks like i'm not handling some edge case. I'll check it out, as well as the second bug! |
62461ba
to
3f83bea
Compare
@justinmc #144563 (review) the first issue you described is now fixed. The second issue doesn't seem related to this PR so i'll make an issue and look into it more later. Most of the failing tests are a result of the this commit b8d118e. I'm still investigating why this is the case. |
I looked into the broken tests caused by b8d118e, they turned out being expected since the test checks the widget tree structure, and the
|
5d546fa
to
2af554a
Compare
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 with nits 👍
I tried QA'ing this again and I thought I had found a bug similar to the flashy one I mentioned last time, then I realized I hadn't pulled your latest changes 😀 . After I did that it seems rock solid. No flashiness or partial selection like I saw before at all, seems to work great.
} | ||
} | ||
|
||
class _SelectableTextContainer extends StatefulWidget { |
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.
Not to start an unrelated naming debate in this comment thread, but I worry about the existing problem where users (especially on the web) use Text widgets expecting them to be selectable when they're not... Not sure exactly how we should organize/name this though. I agree this PR is fine as-is since it's private.
If we do keep both Text and SelectableText though, it would be cool to implement SelectableText simply as a wrapper of Text and SelectionArea.
@override | ||
Comparator<Selectable> get compareOrder => _compareScreenOrder; | ||
|
||
int _compareScreenOrder(Selectable a, Selectable b) { |
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.
Could this also be static?
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.
Also, how is it that we didn't have logic like this up until this PR? Is there any place to share this logic, especially since it's pretty isolated in static methods?
Anyway, thanks for putting in all of the effort required to get this to work. I think it's not clearly evident that something that sounds simple like adding triple tap support involves bringing all of this massive selection infrastructure to Text as well.
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.
It can be static. If you are referring to _adjustSelection
and _initSelection
, I am using different implementations compared to the one in the base class
abstract class MultiSelectableSelectionContainerDelegate extends SelectionContainerDelegate with ChangeNotifier { |
compare*
methods those are also slightly different besides the horizontal and vertical comparison. Also anything below // From [SelectableRegion].
comes from class _SelectableRegionContainerDelegate extends MultiSelectableSelectionContainerDelegate { |
final RenderParagraph paragraph2 = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('Item 1'), matching: find.byType(RichText))); | ||
expect(paragraph2.selections.isEmpty, isTrue); | ||
await gesture.moveTo(textOffsetToPosition(paragraph2, 5) + const Offset(0, 50)); | ||
// Should select paragraph 2. |
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.
So even though these paragraphs might be in the same horizontal row, triple tap drag still selects them one by one. Tricky but I think that's correct 👍
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.
Renewing my LGTM after the recent changes, thanks!
This reverts commit ea37f5cb01c670b6edbfd2b52003338c66ca98ed.
62b593e
to
4f0c7a2
Compare
auto label is removed for flutter/flutter/144563, due to - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label. |
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 👍
Would it be possible to add a test where this kind of bug can be caught in a more straightforward way than the obscure image diff tests?
This reverts commit f1e32aa.
Roll Flutter from a418568 to e868e2b (34 revisions) flutter/flutter@a418568...e868e2b 2024-04-03 [email protected] Add SegmentedButton expand feature (flutter/flutter#142804) 2024-04-03 [email protected] Roll Flutter Engine from e36b9b10c36f to 56fa2c33a5f7 (1 revision) (flutter/flutter#146205) 2024-04-03 [email protected] Roll Packages from 83f3842 to 0e848fa (3 revisions) (flutter/flutter#146201) 2024-04-03 [email protected] Enhance ColorScheme.fromSeed with a new `variant` parameter (flutter/flutter#144805) 2024-04-03 [email protected] Roll Flutter Engine from 0280de5be276 to e36b9b10c36f (1 revision) (flutter/flutter#146200) 2024-04-03 [email protected] Fix typos in bottom_sheet.dart (flutter/flutter#146188) 2024-04-03 [email protected] Roll Flutter Engine from 979030d81f8d to 0280de5be276 (2 revisions) (flutter/flutter#146199) 2024-04-03 [email protected] Roll Flutter Engine from bef3bbe3f74e to 979030d81f8d (1 revision) (flutter/flutter#146186) 2024-04-03 [email protected] Roll Flutter Engine from 5fc83bc24b2e to bef3bbe3f74e (1 revision) (flutter/flutter#146183) 2024-04-03 [email protected] Roll Flutter Engine from 0da1b2eb370a to 5fc83bc24b2e (1 revision) (flutter/flutter#146180) 2024-04-03 [email protected] Avoid calling `TextPainter.plainText` for simple static text (flutter/flutter#146084) 2024-04-03 [email protected] Roll Flutter Engine from e603f89844a9 to 0da1b2eb370a (2 revisions) (flutter/flutter#146179) 2024-04-03 [email protected] Roll Flutter Engine from ef60a95d78c1 to e603f89844a9 (3 revisions) (flutter/flutter#146177) 2024-04-03 [email protected] Fix chip baseline implementation (flutter/flutter#146162) 2024-04-03 [email protected] Roll Flutter Engine from bb4ec2d7eb39 to ef60a95d78c1 (1 revision) (flutter/flutter#146176) 2024-04-03 [email protected] Add tests for material_state_mouse_cursor.0.dart API example. (flutter/flutter#145987) 2024-04-03 [email protected] Update material_color_utilities package version to latest 0.11.1 (flutter/flutter#145959) 2024-04-03 [email protected] Roll Flutter Engine from 5f6dec8bd877 to bb4ec2d7eb39 (4 revisions) (flutter/flutter#146169) 2024-04-03 [email protected] Roll Flutter Engine from 5dbcfdc2a456 to 5f6dec8bd877 (1 revision) (flutter/flutter#146163) 2024-04-02 [email protected] Dispose FocusNode in tests. (flutter/flutter#146161) 2024-04-02 [email protected] Add `none` language strings to code blocks. (flutter/flutter#146154) 2024-04-02 [email protected] Refactor docs (flutter/flutter#145998) 2024-04-02 [email protected] Roll Flutter Engine from c60b00a20fc3 to 5dbcfdc2a456 (3 revisions) (flutter/flutter#146159) 2024-04-02 [email protected] Marks Linux_pixel_7pro complex_layout_scroll_perf_impeller__timeline_summary to be unflaky (flutter/flutter#140038) 2024-04-02 [email protected] Roll Flutter Engine from 5bf8b94505a4 to c60b00a20fc3 (2 revisions) (flutter/flutter#146157) 2024-04-02 [email protected] Refactor analyze (flutter/flutter#146138) 2024-04-02 [email protected] Implement SelectionArea triple click gestures (flutter/flutter#144563) 2024-04-02 [email protected] Roll Flutter Engine from 6883f7313da0 to 5bf8b94505a4 (2 revisions) (flutter/flutter#146152) 2024-04-02 [email protected] Fix border color is wrong for a focused and hovered TextField (flutter/flutter#146127) 2024-04-02 [email protected] Sync lints and enable `annotate_redeclares` (flutter/flutter#146144) 2024-04-02 [email protected] Implements `RenderBox.computeDryBaseline` for material render boxes (flutter/flutter#146027) 2024-04-02 [email protected] Roll Flutter Engine from 523fc953ebc8 to 6883f7313da0 (2 revisions) (flutter/flutter#146140) 2024-04-02 [email protected] Fix `MenuItemButton` overflow (flutter/flutter#143932) 2024-04-02 [email protected] Roll Packages from d5aff19 to 83f3842 (4 revisions) (flutter/flutter#146134) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 ...
Roll Flutter from a418568 to e868e2b (34 revisions) flutter/flutter@a418568...e868e2b 2024-04-03 [email protected] Add SegmentedButton expand feature (flutter/flutter#142804) 2024-04-03 [email protected] Roll Flutter Engine from e36b9b10c36f to 56fa2c33a5f7 (1 revision) (flutter/flutter#146205) 2024-04-03 [email protected] Roll Packages from 83f3842 to 0e848fa (3 revisions) (flutter/flutter#146201) 2024-04-03 [email protected] Enhance ColorScheme.fromSeed with a new `variant` parameter (flutter/flutter#144805) 2024-04-03 [email protected] Roll Flutter Engine from 0280de5be276 to e36b9b10c36f (1 revision) (flutter/flutter#146200) 2024-04-03 [email protected] Fix typos in bottom_sheet.dart (flutter/flutter#146188) 2024-04-03 [email protected] Roll Flutter Engine from 979030d81f8d to 0280de5be276 (2 revisions) (flutter/flutter#146199) 2024-04-03 [email protected] Roll Flutter Engine from bef3bbe3f74e to 979030d81f8d (1 revision) (flutter/flutter#146186) 2024-04-03 [email protected] Roll Flutter Engine from 5fc83bc24b2e to bef3bbe3f74e (1 revision) (flutter/flutter#146183) 2024-04-03 [email protected] Roll Flutter Engine from 0da1b2eb370a to 5fc83bc24b2e (1 revision) (flutter/flutter#146180) 2024-04-03 [email protected] Avoid calling `TextPainter.plainText` for simple static text (flutter/flutter#146084) 2024-04-03 [email protected] Roll Flutter Engine from e603f89844a9 to 0da1b2eb370a (2 revisions) (flutter/flutter#146179) 2024-04-03 [email protected] Roll Flutter Engine from ef60a95d78c1 to e603f89844a9 (3 revisions) (flutter/flutter#146177) 2024-04-03 [email protected] Fix chip baseline implementation (flutter/flutter#146162) 2024-04-03 [email protected] Roll Flutter Engine from bb4ec2d7eb39 to ef60a95d78c1 (1 revision) (flutter/flutter#146176) 2024-04-03 [email protected] Add tests for material_state_mouse_cursor.0.dart API example. (flutter/flutter#145987) 2024-04-03 [email protected] Update material_color_utilities package version to latest 0.11.1 (flutter/flutter#145959) 2024-04-03 [email protected] Roll Flutter Engine from 5f6dec8bd877 to bb4ec2d7eb39 (4 revisions) (flutter/flutter#146169) 2024-04-03 [email protected] Roll Flutter Engine from 5dbcfdc2a456 to 5f6dec8bd877 (1 revision) (flutter/flutter#146163) 2024-04-02 [email protected] Dispose FocusNode in tests. (flutter/flutter#146161) 2024-04-02 [email protected] Add `none` language strings to code blocks. (flutter/flutter#146154) 2024-04-02 [email protected] Refactor docs (flutter/flutter#145998) 2024-04-02 [email protected] Roll Flutter Engine from c60b00a20fc3 to 5dbcfdc2a456 (3 revisions) (flutter/flutter#146159) 2024-04-02 [email protected] Marks Linux_pixel_7pro complex_layout_scroll_perf_impeller__timeline_summary to be unflaky (flutter/flutter#140038) 2024-04-02 [email protected] Roll Flutter Engine from 5bf8b94505a4 to c60b00a20fc3 (2 revisions) (flutter/flutter#146157) 2024-04-02 [email protected] Refactor analyze (flutter/flutter#146138) 2024-04-02 [email protected] Implement SelectionArea triple click gestures (flutter/flutter#144563) 2024-04-02 [email protected] Roll Flutter Engine from 6883f7313da0 to 5bf8b94505a4 (2 revisions) (flutter/flutter#146152) 2024-04-02 [email protected] Fix border color is wrong for a focused and hovered TextField (flutter/flutter#146127) 2024-04-02 [email protected] Sync lints and enable `annotate_redeclares` (flutter/flutter#146144) 2024-04-02 [email protected] Implements `RenderBox.computeDryBaseline` for material render boxes (flutter/flutter#146027) 2024-04-02 [email protected] Roll Flutter Engine from 523fc953ebc8 to 6883f7313da0 (2 revisions) (flutter/flutter#146140) 2024-04-02 [email protected] Fix `MenuItemButton` overflow (flutter/flutter#143932) 2024-04-02 [email protected] Roll Packages from d5aff19 to 83f3842 (4 revisions) (flutter/flutter#146134) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 ...
Roll Flutter from a418568 to e868e2b (34 revisions) flutter/flutter@a418568...e868e2b 2024-04-03 [email protected] Add SegmentedButton expand feature (flutter/flutter#142804) 2024-04-03 [email protected] Roll Flutter Engine from e36b9b10c36f to 56fa2c33a5f7 (1 revision) (flutter/flutter#146205) 2024-04-03 [email protected] Roll Packages from 83f3842 to 0e848fa (3 revisions) (flutter/flutter#146201) 2024-04-03 [email protected] Enhance ColorScheme.fromSeed with a new `variant` parameter (flutter/flutter#144805) 2024-04-03 [email protected] Roll Flutter Engine from 0280de5be276 to e36b9b10c36f (1 revision) (flutter/flutter#146200) 2024-04-03 [email protected] Fix typos in bottom_sheet.dart (flutter/flutter#146188) 2024-04-03 [email protected] Roll Flutter Engine from 979030d81f8d to 0280de5be276 (2 revisions) (flutter/flutter#146199) 2024-04-03 [email protected] Roll Flutter Engine from bef3bbe3f74e to 979030d81f8d (1 revision) (flutter/flutter#146186) 2024-04-03 [email protected] Roll Flutter Engine from 5fc83bc24b2e to bef3bbe3f74e (1 revision) (flutter/flutter#146183) 2024-04-03 [email protected] Roll Flutter Engine from 0da1b2eb370a to 5fc83bc24b2e (1 revision) (flutter/flutter#146180) 2024-04-03 [email protected] Avoid calling `TextPainter.plainText` for simple static text (flutter/flutter#146084) 2024-04-03 [email protected] Roll Flutter Engine from e603f89844a9 to 0da1b2eb370a (2 revisions) (flutter/flutter#146179) 2024-04-03 [email protected] Roll Flutter Engine from ef60a95d78c1 to e603f89844a9 (3 revisions) (flutter/flutter#146177) 2024-04-03 [email protected] Fix chip baseline implementation (flutter/flutter#146162) 2024-04-03 [email protected] Roll Flutter Engine from bb4ec2d7eb39 to ef60a95d78c1 (1 revision) (flutter/flutter#146176) 2024-04-03 [email protected] Add tests for material_state_mouse_cursor.0.dart API example. (flutter/flutter#145987) 2024-04-03 [email protected] Update material_color_utilities package version to latest 0.11.1 (flutter/flutter#145959) 2024-04-03 [email protected] Roll Flutter Engine from 5f6dec8bd877 to bb4ec2d7eb39 (4 revisions) (flutter/flutter#146169) 2024-04-03 [email protected] Roll Flutter Engine from 5dbcfdc2a456 to 5f6dec8bd877 (1 revision) (flutter/flutter#146163) 2024-04-02 [email protected] Dispose FocusNode in tests. (flutter/flutter#146161) 2024-04-02 [email protected] Add `none` language strings to code blocks. (flutter/flutter#146154) 2024-04-02 [email protected] Refactor docs (flutter/flutter#145998) 2024-04-02 [email protected] Roll Flutter Engine from c60b00a20fc3 to 5dbcfdc2a456 (3 revisions) (flutter/flutter#146159) 2024-04-02 [email protected] Marks Linux_pixel_7pro complex_layout_scroll_perf_impeller__timeline_summary to be unflaky (flutter/flutter#140038) 2024-04-02 [email protected] Roll Flutter Engine from 5bf8b94505a4 to c60b00a20fc3 (2 revisions) (flutter/flutter#146157) 2024-04-02 [email protected] Refactor analyze (flutter/flutter#146138) 2024-04-02 [email protected] Implement SelectionArea triple click gestures (flutter/flutter#144563) 2024-04-02 [email protected] Roll Flutter Engine from 6883f7313da0 to 5bf8b94505a4 (2 revisions) (flutter/flutter#146152) 2024-04-02 [email protected] Fix border color is wrong for a focused and hovered TextField (flutter/flutter#146127) 2024-04-02 [email protected] Sync lints and enable `annotate_redeclares` (flutter/flutter#146144) 2024-04-02 [email protected] Implements `RenderBox.computeDryBaseline` for material render boxes (flutter/flutter#146027) 2024-04-02 [email protected] Roll Flutter Engine from 523fc953ebc8 to 6883f7313da0 (2 revisions) (flutter/flutter#146140) 2024-04-02 [email protected] Fix `MenuItemButton` overflow (flutter/flutter#143932) 2024-04-02 [email protected] Roll Packages from d5aff19 to 83f3842 (4 revisions) (flutter/flutter#146134) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 ...
This change adds support for triple click to select a paragraph at the clicked position and triple click + drag to extend the selection paragraph-by-paragraph when using the SelectionArea widget.
This PR also:
Text
widgets aSelectionContainer
if a parentSelectionRegistrar
exists.WidgetSpan
s.Fixes: #104552
Pre-launch Checklist
///
).