Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions lib/web_ui/lib/src/engine/text_editing/text_editing.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1415,9 +1415,12 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements

/// Prevent default behavior for mouse down, up and move.
///
/// When normal mouse events are not prevented, in desktop browsers, mouse
/// selection conflicts with selection sent from the framework, which creates
/// When normal mouse events are not prevented, mouse selection
/// conflicts with selection sent from the framework, which creates
/// flickering during selection by mouse.
///
/// On mobile browsers, mouse events are sent after a touch event,
/// see: https://bugs.chromium.org/p/chromium/issues/detail?id=119216#c11.
void preventDefaultForMouseEvents() {
subscriptions.add(
DomSubscription(activeDomElement, 'mousedown', (_) {
Expand Down Expand Up @@ -1704,6 +1707,8 @@ class AndroidTextEditingStrategy extends GloballyPositionedTextEditingStrategy {
owner.sendTextConnectionClosedToFrameworkIfAny();
}
}));

preventDefaultForMouseEvents();
}

@override
Expand Down
54 changes: 54 additions & 0 deletions lib/web_ui/test/engine/text_editing_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1896,6 +1896,60 @@ Future<void> testMain() async {
hideKeyboard();
});

test('prevent mouse events on Android', () {
// Regression test for https://github.com/flutter/flutter/issues/124483.
debugOperatingSystemOverride = OperatingSystem.android;
debugBrowserEngineOverride = BrowserEngine.blink;

/// During initialization [HybridTextEditing] will pick the correct
/// text editing strategy for [OperatingSystem.android].
textEditing = HybridTextEditing();

final MethodCall setClient = MethodCall(
'TextInput.setClient',
<dynamic>[123, flutterMultilineConfig],
);
sendFrameworkMessage(codec.encodeMethodCall(setClient));

// Editing shouldn't have started yet.
expect(defaultTextEditingRoot.ownerDocument?.activeElement, domDocument.body);

const MethodCall show = MethodCall('TextInput.show');
sendFrameworkMessage(codec.encodeMethodCall(show));

// The "setSizeAndTransform" message has to be here before we call
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
// we don't put the input element into the DOM until we get its correct
// dimensions from the framework.
final List<double> transform = Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList();
final MethodCall setSizeAndTransform = configureSetSizeAndTransformMethodCall(150, 50, transform);
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));

final DomHTMLTextAreaElement textarea = textEditing!.strategy.domElement! as DomHTMLTextAreaElement;
checkTextAreaEditingState(textarea, '', 0, 0);

// Can set editing state and preserve new lines.
const MethodCall setEditingState = MethodCall(
'TextInput.setEditingState',
<String, dynamic>{
'text': '1\n2\n3\n4\n',
'selectionBase': 8,
'selectionExtent': 8,
'composingBase': null,
'composingExtent': null,
},
);
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
checkTextAreaEditingState(textarea, '1\n2\n3\n4\n', 8, 8);

// 'mousedown' event should be prevented.
final DomEvent event = createDomEvent('Event', 'mousedown');
textarea.dispatchEvent(event);
expect(event.defaultPrevented, isTrue);

hideKeyboard();
});

test('sets correct input type in iOS', () {
// Test on ios-safari only.
if (browserEngine == BrowserEngine.webkit &&
Expand Down