Unverified Commit 15ceca93 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Enable contextMenuBuilder in the absence of selectionControls (#141810)

parent 38be1376
...@@ -39,7 +39,7 @@ const int kPrimaryButton = 0x01; ...@@ -39,7 +39,7 @@ const int kPrimaryButton = 0x01;
/// ///
/// It is equivalent to: /// It is equivalent to:
/// ///
/// * [kPrimaryStylusButton]: The stylus contacts the screen. /// * [kPrimaryStylusButton]: The stylus' primary button.
/// * [kSecondaryMouseButton]: The secondary mouse button. /// * [kSecondaryMouseButton]: The secondary mouse button.
/// ///
/// See also: /// See also:
...@@ -97,7 +97,7 @@ const int kPrimaryStylusButton = kSecondaryButton; ...@@ -97,7 +97,7 @@ const int kPrimaryStylusButton = kSecondaryButton;
/// ///
/// It is equivalent to: /// It is equivalent to:
/// ///
/// * [kMiddleMouseButton]: The tertiary mouseButton. /// * [kMiddleMouseButton]: The tertiary mouse button.
/// * [kSecondaryStylusButton]: The secondary button on a stylus. This is considered /// * [kSecondaryStylusButton]: The secondary button on a stylus. This is considered
/// a tertiary button as the primary button of a stylus already corresponds to a /// a tertiary button as the primary button of a stylus already corresponds to a
/// "secondary operation" (where stylus contact is the primary operation). /// "secondary operation" (where stylus contact is the primary operation).
......
...@@ -4320,7 +4320,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -4320,7 +4320,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
/// Toggles the visibility of the toolbar. /// Toggles the visibility of the toolbar.
void toggleToolbar([bool hideHandles = true]) { void toggleToolbar([bool hideHandles = true]) {
final TextSelectionOverlay selectionOverlay = _selectionOverlay ??= _createSelectionOverlay(); final TextSelectionOverlay selectionOverlay = _selectionOverlay ??= _createSelectionOverlay();
if (selectionOverlay.toolbarIsVisible) { if (selectionOverlay.toolbarIsVisible) {
hideToolbar(hideHandles); hideToolbar(hideHandles);
} else { } else {
......
...@@ -448,7 +448,7 @@ class TextSelectionOverlay { ...@@ -448,7 +448,7 @@ class TextSelectionOverlay {
void showToolbar() { void showToolbar() {
_updateSelectionOverlay(); _updateSelectionOverlay();
if (selectionControls is! TextSelectionHandleControls) { if (selectionControls != null && selectionControls is! TextSelectionHandleControls) {
_selectionOverlay.showToolbar(); _selectionOverlay.showToolbar();
return; return;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// 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 'package:flutter/foundation.dart' show ValueListenable, defaultTargetPlatform; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
...@@ -1781,6 +1781,51 @@ void main() { ...@@ -1781,6 +1781,51 @@ void main() {
); );
}); });
}); });
testWidgets('Context menus', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'You make wine from sour grapes',
);
addTearDown(controller.dispose);
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
final FakeTextSelectionGestureDetectorBuilderDelegate delegate = FakeTextSelectionGestureDetectorBuilderDelegate(
editableTextKey: editableTextKey,
forcePressEnabled: false,
selectionEnabled: true,
);
final TextSelectionGestureDetectorBuilder provider =
TextSelectionGestureDetectorBuilder(delegate: delegate);
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget(
MaterialApp(
home: provider.buildGestureDetector(
behavior: HitTestBehavior.translucent,
child: EditableText(
key: editableTextKey,
controller: controller,
focusNode: focusNode,
backgroundCursorColor: Colors.white,
cursorColor: Colors.white,
style: const TextStyle(),
contextMenuBuilder: (
BuildContext context,
EditableTextState editableTextState,
) {
return const Placeholder();
},
),
),
),
);
final Offset position = textOffsetToPosition(tester, 0);
expect(find.byType(Placeholder), findsNothing);
await tester.tapAt(position, buttons: kSecondaryMouseButton, kind: PointerDeviceKind.mouse);
await tester.pump();
expect(find.byType(Placeholder), findsOneWidget);
}, skip: kIsWeb); // [intended] On web, we use native context menus for text fields.
} }
class FakeTextSelectionGestureDetectorBuilderDelegate implements TextSelectionGestureDetectorBuilderDelegate { class FakeTextSelectionGestureDetectorBuilderDelegate implements TextSelectionGestureDetectorBuilderDelegate {
......
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