Unverified Commit 36f73cf6 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Disable context menu (#128365)

## Description

Changes the context menu example for `MenuAnchor` so that it uses right-click, or (on macOS and iOS only) ctrl-left-click, for the context menu. Also disables the browser context menu on web platforms.

## Tests
 - Updated test to reflect new triggers.
parent 5328bd9a
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
......@@ -41,6 +42,7 @@ class _MyContextMenuState extends State<MyContextMenu> {
final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Menu Button');
final MenuController _menuController = MenuController();
ShortcutRegistryEntry? _shortcutsEntry;
bool _menuWasEnabled = false;
Color get backgroundColor => _backgroundColor;
Color _backgroundColor = Colors.red;
......@@ -62,6 +64,12 @@ class _MyContextMenuState extends State<MyContextMenu> {
}
}
@override
void initState() {
super.initState();
_disableContextMenu();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
......@@ -84,15 +92,38 @@ class _MyContextMenuState extends State<MyContextMenu> {
void dispose() {
_shortcutsEntry?.dispose();
_buttonFocusNode.dispose();
_reenableContextMenu();
super.dispose();
}
Future<void> _disableContextMenu() async {
if (!kIsWeb) {
// Does nothing on non-web platforms.
return;
}
_menuWasEnabled = BrowserContextMenu.enabled;
if (_menuWasEnabled) {
await BrowserContextMenu.disableContextMenu();
}
}
void _reenableContextMenu() {
if (!kIsWeb) {
// Does nothing on non-web platforms.
return;
}
if (_menuWasEnabled && !BrowserContextMenu.enabled) {
BrowserContextMenu.enableContextMenu();
}
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(50),
child: GestureDetector(
onTapDown: _handleTapDown,
onSecondaryTapDown: _handleSecondaryTapDown,
child: MenuAnchor(
controller: _menuController,
anchorTapClosesMenu: true,
......@@ -142,7 +173,7 @@ class _MyContextMenuState extends State<MyContextMenu> {
children: <Widget>[
const Padding(
padding: EdgeInsets.all(8.0),
child: Text('Ctrl-click anywhere on the background to show the menu.'),
child: Text('Right-click anywhere on the background to show the menu.'),
),
Padding(
padding: const EdgeInsets.all(12.0),
......@@ -185,12 +216,28 @@ class _MyContextMenuState extends State<MyContextMenu> {
}
}
void _handleSecondaryTapDown(TapDownDetails details) {
_menuController.open(position: details.localPosition);
}
void _handleTapDown(TapDownDetails details) {
if (!HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.controlLeft) &&
!HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.controlRight)) {
return;
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
// Don't open the menu on these platforms with a Ctrl-tap (or a
// tap).
break;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
// Only open the menu on these platforms if the control button is down
// when the tap occurs.
if (HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.controlLeft) ||
HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.controlRight)) {
_menuController.open(position: details.localPosition);
}
}
_menuController.open(position: details.localPosition);
}
}
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_api_samples/material/menu_anchor/menu_anchor.1.dart' as example;
......@@ -18,15 +19,13 @@ void main() {
await tester.pumpWidget(const example.ContextMenuApp());
await tester.sendKeyDownEvent(LogicalKeyboardKey.controlRight);
await tester.tapAt(const Offset(100, 200));
await tester.tapAt(const Offset(100, 200), buttons: kSecondaryButton);
await tester.pump();
expect(tester.getRect(findMenu()), equals(const Rect.fromLTRB(100.0, 200.0, 433.0, 360.0)));
// Make sure tapping in a different place causes the menu to move.
await tester.tapAt(const Offset(200, 100));
await tester.tapAt(const Offset(200, 100), buttons: kSecondaryButton);
await tester.pump();
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlRight);
expect(tester.getRect(findMenu()), equals(const Rect.fromLTRB(200.0, 100.0, 533.0, 260.0)));
......@@ -67,8 +66,7 @@ void main() {
);
// Open the menu so we can look for state changes reflected in the menu.
await tester.sendKeyDownEvent(LogicalKeyboardKey.controlRight);
await tester.tapAt(const Offset(100, 200));
await tester.tapAt(const Offset(100, 200), buttons: kSecondaryButton);
await tester.pump();
expect(find.text(example.MenuEntry.showMessage.label), findsOneWidget);
......
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