Unverified Commit 803c07fe authored by J-P Nurmi's avatar J-P Nurmi Committed by GitHub

Fix EditableText.enableInteractiveSelection on desktop & web (#70972)

selectionEnabled was not taken into account in:

key movement handling in RenderEditable
mouse drag handling in TextSelectionGestureDetectorBuilder
parent 26ccbd9f
...@@ -743,8 +743,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -743,8 +743,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
} }
// Just place the collapsed selection at the end or beginning of the region // Just place the collapsed selection at the end or beginning of the region
// if shift isn't down. // if shift isn't down or selection isn't enabled.
if (!shift) { if (!shift || !selectionEnabled) {
// We want to put the cursor at the correct location depending on which // We want to put the cursor at the correct location depending on which
// arrow is used while there is a selection. // arrow is used while there is a selection.
int newOffset = newSelection.extentOffset; int newOffset = newSelection.extentOffset;
......
...@@ -1084,6 +1084,8 @@ class TextSelectionGestureDetectorBuilder { ...@@ -1084,6 +1084,8 @@ class TextSelectionGestureDetectorBuilder {
/// this callback. /// this callback.
@protected @protected
void onDragSelectionStart(DragStartDetails details) { void onDragSelectionStart(DragStartDetails details) {
if (!delegate.selectionEnabled)
return;
final PointerDeviceKind? kind = details.kind; final PointerDeviceKind? kind = details.kind;
_shouldShowSelectionToolbar = kind == null _shouldShowSelectionToolbar = kind == null
|| kind == PointerDeviceKind.touch || kind == PointerDeviceKind.touch
...@@ -1106,6 +1108,8 @@ class TextSelectionGestureDetectorBuilder { ...@@ -1106,6 +1108,8 @@ class TextSelectionGestureDetectorBuilder {
/// this callback./lib/src/material/text_field.dart /// this callback./lib/src/material/text_field.dart
@protected @protected
void onDragSelectionUpdate(DragStartDetails startDetails, DragUpdateDetails updateDetails) { void onDragSelectionUpdate(DragStartDetails startDetails, DragUpdateDetails updateDetails) {
if (!delegate.selectionEnabled)
return;
renderEditable.selectPositionAt( renderEditable.selectPositionAt(
from: startDetails.globalPosition, from: startDetails.globalPosition,
to: updateDetails.globalPosition, to: updateDetails.globalPosition,
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:io' show Platform;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
...@@ -1081,6 +1083,73 @@ void main() { ...@@ -1081,6 +1083,73 @@ void main() {
expect(currentSelection.extentOffset, 1); expect(currentSelection.extentOffset, 1);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/58068 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/58068
test('respects enableInteractiveSelection', () async {
final TextSelectionDelegate delegate = FakeEditableTextState();
final ViewportOffset viewportOffset = ViewportOffset.zero();
late TextSelection currentSelection;
final RenderEditable editable = RenderEditable(
backgroundCursorColor: Colors.grey,
selectionColor: Colors.black,
textDirection: TextDirection.ltr,
cursorColor: Colors.red,
offset: viewportOffset,
textSelectionDelegate: delegate,
onSelectionChanged: (TextSelection selection, RenderEditable renderObject, SelectionChangedCause cause) {
currentSelection = selection;
},
startHandleLayerLink: LayerLink(),
endHandleLayerLink: LayerLink(),
text: const TextSpan(
text: '012345', // Thumbs up
style: TextStyle(height: 1.0, fontSize: 10.0, fontFamily: 'Ahem'),
),
selection: const TextSelection.collapsed(
offset: 0,
),
enableInteractiveSelection: false,
);
layout(editable);
editable.hasFocus = true;
editable.selection = const TextSelection.collapsed(offset: 2);
pumpFrame();
await simulateKeyDownEvent(LogicalKeyboardKey.shift);
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowRight);
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 3);
editable.selection = currentSelection;
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 2);
editable.selection = currentSelection;
final LogicalKeyboardKey wordModifier =
Platform.isMacOS ? LogicalKeyboardKey.alt : LogicalKeyboardKey.control;
await simulateKeyDownEvent(wordModifier);
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowRight);
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 6);
editable.selection = currentSelection;
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 0);
editable.selection = currentSelection;
await simulateKeyUpEvent(wordModifier);
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/58068
group('delete', () { group('delete', () {
test('handles selection', () async { test('handles selection', () async {
final TextSelectionDelegate delegate = FakeEditableTextState() final TextSelectionDelegate delegate = FakeEditableTextState()
......
...@@ -600,6 +600,23 @@ void main() { ...@@ -600,6 +600,23 @@ void main() {
expect(renderEditable.selectWordsInRangeCalled, isFalse); expect(renderEditable.selectWordsInRangeCalled, isFalse);
}); });
testWidgets('test TextSelectionGestureDetectorBuilder mouse drag disabled', (WidgetTester tester) async {
await pumpTextSelectionGestureDetectorBuilder(tester, selectionEnabled: false);
final TestGesture gesture = await tester.startGesture(
const Offset(0.0, 0.0),
kind: PointerDeviceKind.mouse,
);
addTearDown(gesture.removePointer);
await tester.pump();
await gesture.moveTo(const Offset(50.0, 0));
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
final FakeRenderEditable renderEditable = tester.renderObject(find.byType(FakeEditable));
expect(renderEditable.selectPositionAtCalled, isFalse);
});
testWidgets('test TextSelectionGestureDetectorBuilder forcePress disabled', (WidgetTester tester) async { testWidgets('test TextSelectionGestureDetectorBuilder forcePress disabled', (WidgetTester tester) async {
await pumpTextSelectionGestureDetectorBuilder(tester, forcePressEnabled: false); await pumpTextSelectionGestureDetectorBuilder(tester, forcePressEnabled: false);
final TestGesture gesture = await tester.createGesture(); final TestGesture gesture = await tester.createGesture();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment