Skip to content

Commit d74a1bb

Browse files
authored
Fix off-screen selected text throws exception (#123595)
Fix off-screen selected text throws exception
1 parent 47c92c0 commit d74a1bb

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ class TextSelectionToolbarAnchors {
3434
renderBox.localToGlobal(Offset.zero),
3535
renderBox.localToGlobal(renderBox.size.bottomRight(Offset.zero)),
3636
);
37+
38+
if (editingRegion.left.isNaN || editingRegion.top.isNaN
39+
|| editingRegion.right.isNaN || editingRegion.bottom.isNaN) {
40+
return const TextSelectionToolbarAnchors(primaryAnchor: Offset.zero);
41+
}
42+
3743
final bool isMultiline = selectionEndpoints.last.point.dy - selectionEndpoints.first.point.dy >
3844
endGlyphHeight / 2;
3945

packages/flutter/test/widgets/selectable_text_test.dart

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5399,4 +5399,59 @@ void main() {
53995399
);
54005400
expect(count, 1); // The `onSelectionChanged` will not be triggered.
54015401
});
5402+
5403+
testWidgets("Off-screen selected text doesn't throw exception", (WidgetTester tester) async {
5404+
// This is a regression test for https://github.com/flutter/flutter/issues/123527
5405+
5406+
TextSelection? selection;
5407+
await tester.pumpWidget(
5408+
MaterialApp(
5409+
home: Material(
5410+
child: Builder(
5411+
builder: (BuildContext context) {
5412+
return Column(
5413+
children: <Widget>[
5414+
Expanded(
5415+
child: ListView.builder(
5416+
itemCount: 100,
5417+
itemBuilder: (BuildContext context, int index) {
5418+
return SelectableText(
5419+
'I love Flutter! $index',
5420+
onSelectionChanged: (TextSelection s, _) {
5421+
selection = s;
5422+
},
5423+
);
5424+
},
5425+
),
5426+
),
5427+
TextButton(
5428+
onPressed: () {
5429+
Navigator.pop(context);
5430+
},
5431+
child: const Text('Pop'),
5432+
),
5433+
],
5434+
);
5435+
}
5436+
),
5437+
),
5438+
));
5439+
5440+
expect(selection, null);
5441+
5442+
final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText).first);
5443+
final TestGesture gesture = await tester.startGesture(selectableTextStart + const Offset(50, 5));
5444+
await tester.pump(const Duration(milliseconds: 500));
5445+
await gesture.up();
5446+
5447+
expect(selection, isNotNull);
5448+
5449+
await tester.drag(find.byType(ListView), const Offset(0.0, -3000.0));
5450+
await tester.pumpAndSettle();
5451+
5452+
await tester.tap(find.text('Pop'));
5453+
await tester.pumpAndSettle();
5454+
5455+
expect(tester.takeException(), isNull);
5456+
});
54025457
}

0 commit comments

Comments
 (0)