Skip to content

Commit 3c2f500

Browse files
Fix edge scrolling on platforms that select word by word on long press move (#113128)
1 parent 2dd87fb commit 3c2f500

File tree

6 files changed

+626
-91
lines changed

6 files changed

+626
-91
lines changed

packages/flutter/lib/src/cupertino/text_field.dart

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,16 +1035,12 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
10351035
switch (defaultTargetPlatform) {
10361036
case TargetPlatform.iOS:
10371037
case TargetPlatform.macOS:
1038-
if (cause == SelectionChangedCause.longPress
1039-
|| cause == SelectionChangedCause.drag) {
1040-
_editableText.bringIntoView(selection.extent);
1041-
}
1042-
break;
10431038
case TargetPlatform.linux:
10441039
case TargetPlatform.windows:
10451040
case TargetPlatform.fuchsia:
10461041
case TargetPlatform.android:
1047-
if (cause == SelectionChangedCause.drag) {
1042+
if (cause == SelectionChangedCause.longPress
1043+
|| cause == SelectionChangedCause.drag) {
10481044
_editableText.bringIntoView(selection.extent);
10491045
}
10501046
break;

packages/flutter/lib/src/material/text_field.dart

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -62,45 +62,6 @@ class _TextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDete
6262
// Not required.
6363
}
6464

65-
@override
66-
void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) {
67-
if (delegate.selectionEnabled) {
68-
final TargetPlatform targetPlatform = Theme.of(_state.context).platform;
69-
70-
switch (targetPlatform) {
71-
case TargetPlatform.iOS:
72-
case TargetPlatform.macOS:
73-
renderEditable.selectPositionAt(
74-
from: details.globalPosition,
75-
cause: SelectionChangedCause.longPress,
76-
);
77-
break;
78-
case TargetPlatform.android:
79-
case TargetPlatform.fuchsia:
80-
case TargetPlatform.linux:
81-
case TargetPlatform.windows:
82-
renderEditable.selectWordsInRange(
83-
from: details.globalPosition - details.offsetFromOrigin,
84-
to: details.globalPosition,
85-
cause: SelectionChangedCause.longPress,
86-
);
87-
break;
88-
}
89-
90-
switch (targetPlatform) {
91-
case TargetPlatform.android:
92-
case TargetPlatform.iOS:
93-
editableText.showMagnifier(details.globalPosition);
94-
break;
95-
case TargetPlatform.fuchsia:
96-
case TargetPlatform.linux:
97-
case TargetPlatform.macOS:
98-
case TargetPlatform.windows:
99-
break;
100-
}
101-
}
102-
}
103-
10465
@override
10566
void onSingleTapUp(TapUpDetails details) {
10667
super.onSingleTapUp(details);
@@ -110,37 +71,19 @@ class _TextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDete
11071

11172
@override
11273
void onSingleLongTapStart(LongPressStartDetails details) {
74+
super.onSingleLongTapStart(details);
11375
if (delegate.selectionEnabled) {
114-
final TargetPlatform targetPlatform = Theme.of(_state.context).platform;
115-
116-
switch (targetPlatform) {
76+
switch (Theme.of(_state.context).platform) {
11777
case TargetPlatform.iOS:
11878
case TargetPlatform.macOS:
119-
renderEditable.selectPositionAt(
120-
from: details.globalPosition,
121-
cause: SelectionChangedCause.longPress,
122-
);
12379
break;
12480
case TargetPlatform.android:
12581
case TargetPlatform.fuchsia:
12682
case TargetPlatform.linux:
12783
case TargetPlatform.windows:
128-
renderEditable.selectWord(cause: SelectionChangedCause.longPress);
12984
Feedback.forLongPress(_state.context);
13085
break;
13186
}
132-
133-
switch (targetPlatform) {
134-
case TargetPlatform.android:
135-
case TargetPlatform.iOS:
136-
editableText.showMagnifier(details.globalPosition);
137-
break;
138-
case TargetPlatform.fuchsia:
139-
case TargetPlatform.linux:
140-
case TargetPlatform.macOS:
141-
case TargetPlatform.windows:
142-
break;
143-
}
14487
}
14588
}
14689
}
@@ -1150,16 +1093,12 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
11501093
switch (Theme.of(context).platform) {
11511094
case TargetPlatform.iOS:
11521095
case TargetPlatform.macOS:
1153-
if (cause == SelectionChangedCause.longPress
1154-
|| cause == SelectionChangedCause.drag) {
1155-
_editableText?.bringIntoView(selection.extent);
1156-
}
1157-
break;
11581096
case TargetPlatform.linux:
11591097
case TargetPlatform.windows:
11601098
case TargetPlatform.fuchsia:
11611099
case TargetPlatform.android:
1162-
if (cause == SelectionChangedCause.drag) {
1100+
if (cause == SelectionChangedCause.longPress
1101+
|| cause == SelectionChangedCause.drag) {
11631102
_editableText?.bringIntoView(selection.extent);
11641103
}
11651104
break;

packages/flutter/lib/src/widgets/text_selection.dart

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1996,10 +1996,21 @@ class TextSelectionGestureDetectorBuilder {
19961996
@protected
19971997
void onSingleLongTapStart(LongPressStartDetails details) {
19981998
if (delegate.selectionEnabled) {
1999-
renderEditable.selectPositionAt(
2000-
from: details.globalPosition,
2001-
cause: SelectionChangedCause.longPress,
2002-
);
1999+
switch (defaultTargetPlatform) {
2000+
case TargetPlatform.iOS:
2001+
case TargetPlatform.macOS:
2002+
renderEditable.selectPositionAt(
2003+
from: details.globalPosition,
2004+
cause: SelectionChangedCause.longPress,
2005+
);
2006+
break;
2007+
case TargetPlatform.android:
2008+
case TargetPlatform.fuchsia:
2009+
case TargetPlatform.linux:
2010+
case TargetPlatform.windows:
2011+
renderEditable.selectWord(cause: SelectionChangedCause.longPress);
2012+
break;
2013+
}
20032014

20042015
switch (defaultTargetPlatform) {
20052016
case TargetPlatform.android:
@@ -2012,6 +2023,9 @@ class TextSelectionGestureDetectorBuilder {
20122023
case TargetPlatform.windows:
20132024
break;
20142025
}
2026+
2027+
_dragStartViewportOffset = renderEditable.offset.pixels;
2028+
_dragStartScrollOffset = _scrollPosition;
20152029
}
20162030
}
20172031

@@ -2027,11 +2041,35 @@ class TextSelectionGestureDetectorBuilder {
20272041
@protected
20282042
void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) {
20292043
if (delegate.selectionEnabled) {
2030-
renderEditable.selectPositionAt(
2031-
from: details.globalPosition,
2032-
cause: SelectionChangedCause.longPress,
2044+
// Adjust the drag start offset for possible viewport offset changes.
2045+
final Offset editableOffset = renderEditable.maxLines == 1
2046+
? Offset(renderEditable.offset.pixels - _dragStartViewportOffset, 0.0)
2047+
: Offset(0.0, renderEditable.offset.pixels - _dragStartViewportOffset);
2048+
final Offset scrollableOffset = Offset(
2049+
0.0,
2050+
_scrollPosition - _dragStartScrollOffset,
20332051
);
20342052

2053+
switch (defaultTargetPlatform) {
2054+
case TargetPlatform.iOS:
2055+
case TargetPlatform.macOS:
2056+
renderEditable.selectPositionAt(
2057+
from: details.globalPosition,
2058+
cause: SelectionChangedCause.longPress,
2059+
);
2060+
break;
2061+
case TargetPlatform.android:
2062+
case TargetPlatform.fuchsia:
2063+
case TargetPlatform.linux:
2064+
case TargetPlatform.windows:
2065+
renderEditable.selectWordsInRange(
2066+
from: details.globalPosition - details.offsetFromOrigin - editableOffset - scrollableOffset,
2067+
to: details.globalPosition,
2068+
cause: SelectionChangedCause.longPress,
2069+
);
2070+
break;
2071+
}
2072+
20352073
switch (defaultTargetPlatform) {
20362074
case TargetPlatform.android:
20372075
case TargetPlatform.iOS:
@@ -2070,6 +2108,8 @@ class TextSelectionGestureDetectorBuilder {
20702108
if (shouldShowSelectionToolbar) {
20712109
editableText.showToolbar();
20722110
}
2111+
_dragStartViewportOffset = 0.0;
2112+
_dragStartScrollOffset = 0.0;
20732113
}
20742114

20752115
/// Handler for [TextSelectionGestureDetector.onSecondaryTap].

0 commit comments

Comments
 (0)