mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Use SystemContextMenu by default on iOS (#165354)
With this change, widgets based on EditableText will show the system context menu by default on iOS. Anyone with a custom contextMenuBuilder will not be affected and will have to opt-in to using SystemContextMenu. Also, this does not affect SelectionArea, which can't receive paste. Fixes https://github.com/flutter/flutter/issues/163067
This commit is contained in:
parent
f236af4975
commit
8128f08603
@ -808,6 +808,9 @@ class CupertinoTextField extends StatefulWidget {
|
||||
BuildContext context,
|
||||
EditableTextState editableTextState,
|
||||
) {
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS && SystemContextMenu.isSupported(context)) {
|
||||
return SystemContextMenu.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
return CupertinoAdaptiveTextSelectionToolbar.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
|
||||
|
||||
@ -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/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
@ -271,6 +272,9 @@ class CupertinoTextFormFieldRow extends FormField<String> {
|
||||
BuildContext context,
|
||||
EditableTextState editableTextState,
|
||||
) {
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS && SystemContextMenu.isSupported(context)) {
|
||||
return SystemContextMenu.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
return CupertinoAdaptiveTextSelectionToolbar.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
@ -1536,6 +1537,9 @@ class SearchBar extends StatefulWidget {
|
||||
BuildContext context,
|
||||
EditableTextState editableTextState,
|
||||
) {
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS && SystemContextMenu.isSupported(context)) {
|
||||
return SystemContextMenu.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
return AdaptiveTextSelectionToolbar.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
|
||||
|
||||
@ -447,6 +447,9 @@ class SelectableText extends StatefulWidget {
|
||||
BuildContext context,
|
||||
EditableTextState editableTextState,
|
||||
) {
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS && SystemContextMenu.isSupported(context)) {
|
||||
return SystemContextMenu.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
return AdaptiveTextSelectionToolbar.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
|
||||
|
||||
@ -849,6 +849,9 @@ class TextField extends StatefulWidget {
|
||||
BuildContext context,
|
||||
EditableTextState editableTextState,
|
||||
) {
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS && SystemContextMenu.isSupported(context)) {
|
||||
return SystemContextMenu.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
return AdaptiveTextSelectionToolbar.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@ -326,6 +327,9 @@ class TextFormField extends FormField<String> {
|
||||
BuildContext context,
|
||||
EditableTextState editableTextState,
|
||||
) {
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS && SystemContextMenu.isSupported(context)) {
|
||||
return SystemContextMenu.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
return AdaptiveTextSelectionToolbar.editableText(editableTextState: editableTextState);
|
||||
}
|
||||
|
||||
|
||||
@ -25,8 +25,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../widgets/clipboard_utils.dart';
|
||||
import '../widgets/editable_text_utils.dart'
|
||||
show OverflowWidgetTextEditingController, isContextMenuProvidedByPlatform;
|
||||
import '../widgets/editable_text_utils.dart';
|
||||
import '../widgets/live_text_utils.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
import '../widgets/text_selection_toolbar_utils.dart';
|
||||
@ -238,10 +237,6 @@ void main() {
|
||||
return endpoints[0].point;
|
||||
}
|
||||
|
||||
// Web has a less threshold for downstream/upstream text position.
|
||||
Offset textOffsetToPosition(WidgetTester tester, int offset) =>
|
||||
textOffsetToBottomLeftPosition(tester, offset) + const Offset(kIsWeb ? 1 : 0, -2);
|
||||
|
||||
setUp(() async {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(
|
||||
SystemChannels.platform,
|
||||
@ -8840,6 +8835,39 @@ void main() {
|
||||
},
|
||||
skip: kIsWeb, // [intended] on web the browser handles the context menu.
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'iOS uses the system context menu by default if supported',
|
||||
(WidgetTester tester) async {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher.supportsShowingSystemContextMenu =
|
||||
true;
|
||||
_updateMediaQueryFromView(tester);
|
||||
addTearDown(() {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher
|
||||
.resetSupportsShowingSystemContextMenu();
|
||||
_updateMediaQueryFromView(tester);
|
||||
});
|
||||
|
||||
final TextEditingController controller = TextEditingController(text: 'one two three');
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(CupertinoApp(home: CupertinoTextField(controller: controller)));
|
||||
|
||||
// No context menu shown.
|
||||
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsNothing);
|
||||
|
||||
// Double tap to select the first word and show the menu.
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(SelectionOverlay.fadeDuration);
|
||||
|
||||
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsOneWidget);
|
||||
},
|
||||
skip: kIsWeb, // [intended] on web the browser handles the context menu.
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.iOS),
|
||||
);
|
||||
});
|
||||
|
||||
group('magnifier', () {
|
||||
@ -9880,3 +9908,23 @@ void main() {
|
||||
variant: TargetPlatformVariant.all(),
|
||||
);
|
||||
}
|
||||
|
||||
// Trigger MediaQuery to update itself based on the View, which is not
|
||||
// recreated between tests. This is necessary when changing something on
|
||||
// TestPlatformDispatcher and expecting it to be picked up by MediaQuery.
|
||||
// TODO(justinmc): This hack can be removed if
|
||||
// https://github.com/flutter/flutter/issues/165519 is fixed.
|
||||
void _updateMediaQueryFromView(WidgetTester tester) {
|
||||
expect(find.byType(MediaQuery), findsOneWidget);
|
||||
final WidgetsBindingObserver widgetsBindingObserver =
|
||||
tester.state(
|
||||
find.ancestor(
|
||||
of: find.byType(MediaQuery),
|
||||
matching: find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MediaQueryFromView',
|
||||
),
|
||||
),
|
||||
)
|
||||
as WidgetsBindingObserver;
|
||||
widgetsBindingObserver.didChangeMetrics();
|
||||
}
|
||||
|
||||
@ -3,10 +3,13 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/src/services/spell_check.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../widgets/editable_text_utils.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Passes textAlign to underlying CupertinoTextField', (WidgetTester tester) async {
|
||||
const TextAlign alignment = TextAlign.center;
|
||||
@ -518,4 +521,59 @@ void main() {
|
||||
expect(stateKey.currentState!.value, 'initialValue');
|
||||
expect(value, 'initialValue');
|
||||
});
|
||||
|
||||
group('context menu', () {
|
||||
testWidgets(
|
||||
'iOS uses the system context menu by default if supported',
|
||||
(WidgetTester tester) async {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher.supportsShowingSystemContextMenu =
|
||||
true;
|
||||
_updateMediaQueryFromView(tester);
|
||||
addTearDown(() {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher
|
||||
.resetSupportsShowingSystemContextMenu();
|
||||
_updateMediaQueryFromView(tester);
|
||||
});
|
||||
|
||||
final TextEditingController controller = TextEditingController(text: 'one two three');
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(CupertinoApp(home: CupertinoTextField(controller: controller)));
|
||||
|
||||
// No context menu shown.
|
||||
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsNothing);
|
||||
|
||||
// Double tap to select the first word and show the menu.
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(SelectionOverlay.fadeDuration);
|
||||
|
||||
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsOneWidget);
|
||||
},
|
||||
skip: kIsWeb, // [intended] on web the browser handles the context menu.
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.iOS),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger MediaQuery to update itself based on the View, which is not
|
||||
// recreated between tests. This is necessary when changing something on
|
||||
// TestPlatformDispatcher and expecting it to be picked up by MediaQuery.
|
||||
// TODO(justinmc): This hack can be removed if
|
||||
// https://github.com/flutter/flutter/issues/165519 is fixed.
|
||||
void _updateMediaQueryFromView(WidgetTester tester) {
|
||||
expect(find.byType(MediaQuery), findsOneWidget);
|
||||
final WidgetsBindingObserver widgetsBindingObserver =
|
||||
tester.state(
|
||||
find.ancestor(
|
||||
of: find.byType(MediaQuery),
|
||||
matching: find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MediaQueryFromView',
|
||||
),
|
||||
),
|
||||
)
|
||||
as WidgetsBindingObserver;
|
||||
widgetsBindingObserver.didChangeMetrics();
|
||||
}
|
||||
|
||||
@ -3687,6 +3687,41 @@ void main() {
|
||||
|
||||
expect(find.byType(Placeholder), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'iOS uses the system context menu by default if supported',
|
||||
(WidgetTester tester) async {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher.supportsShowingSystemContextMenu =
|
||||
true;
|
||||
_updateMediaQueryFromView(tester);
|
||||
addTearDown(() {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher
|
||||
.resetSupportsShowingSystemContextMenu();
|
||||
_updateMediaQueryFromView(tester);
|
||||
});
|
||||
|
||||
final TextEditingController controller = TextEditingController(text: 'one two three');
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: Material(child: TextField(controller: controller))),
|
||||
);
|
||||
|
||||
// No context menu shown.
|
||||
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsNothing);
|
||||
|
||||
// Double tap to select the first word and show the menu.
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(SelectionOverlay.fadeDuration);
|
||||
|
||||
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsOneWidget);
|
||||
},
|
||||
skip: kIsWeb, // [intended] on web the browser handles the context menu.
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.iOS),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('SearchAnchor does not dispose external SearchController', (
|
||||
@ -4107,3 +4142,23 @@ Material getSearchViewMaterial(WidgetTester tester) {
|
||||
find.descendant(of: findViewContent(), matching: find.byType(Material)).first,
|
||||
);
|
||||
}
|
||||
|
||||
// Trigger MediaQuery to update itself based on the View, which is not
|
||||
// recreated between tests. This is necessary when changing something on
|
||||
// TestPlatformDispatcher and expecting it to be picked up by MediaQuery.
|
||||
// TODO(justinmc): This hack can be removed if
|
||||
// https://github.com/flutter/flutter/issues/165519 is fixed.
|
||||
void _updateMediaQueryFromView(WidgetTester tester) {
|
||||
expect(find.byType(MediaQuery), findsOneWidget);
|
||||
final WidgetsBindingObserver widgetsBindingObserver =
|
||||
tester.state(
|
||||
find.ancestor(
|
||||
of: find.byType(MediaQuery),
|
||||
matching: find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MediaQueryFromView',
|
||||
),
|
||||
),
|
||||
)
|
||||
as WidgetsBindingObserver;
|
||||
widgetsBindingObserver.didChangeMetrics();
|
||||
}
|
||||
|
||||
@ -16147,6 +16147,43 @@ void main() {
|
||||
},
|
||||
skip: kIsWeb, // [intended] on web the browser handles the context menu.
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'iOS uses the system context menu by default if supported',
|
||||
(WidgetTester tester) async {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher.supportsShowingSystemContextMenu =
|
||||
true;
|
||||
_updateMediaQueryFromView(tester);
|
||||
addTearDown(() {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher
|
||||
.resetSupportsShowingSystemContextMenu();
|
||||
_updateMediaQueryFromView(tester);
|
||||
});
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: TextField(controller: _textEditingController(text: 'one two three')),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// No context menu shown.
|
||||
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsNothing);
|
||||
|
||||
// Double tap to select the first word and show the menu.
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(SelectionOverlay.fadeDuration);
|
||||
|
||||
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsOneWidget);
|
||||
},
|
||||
skip: kIsWeb, // [intended] on web the browser handles the context menu.
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.iOS),
|
||||
);
|
||||
});
|
||||
|
||||
group('magnifier builder', () {
|
||||
@ -17668,3 +17705,23 @@ TextEditingController _textEditingController({String text = ''}) {
|
||||
addTearDown(result.dispose);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Trigger MediaQuery to update itself based on the View, which is not
|
||||
// recreated between tests. This is necessary when changing something on
|
||||
// TestPlatformDispatcher and expecting it to be picked up by MediaQuery.
|
||||
// TODO(justinmc): This hack can be removed if
|
||||
// https://github.com/flutter/flutter/issues/165519 is fixed.
|
||||
void _updateMediaQueryFromView(WidgetTester tester) {
|
||||
expect(find.byType(MediaQuery), findsOneWidget);
|
||||
final WidgetsBindingObserver widgetsBindingObserver =
|
||||
tester.state(
|
||||
find.ancestor(
|
||||
of: find.byType(MediaQuery),
|
||||
matching: find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MediaQueryFromView',
|
||||
),
|
||||
),
|
||||
)
|
||||
as WidgetsBindingObserver;
|
||||
widgetsBindingObserver.didChangeMetrics();
|
||||
}
|
||||
|
||||
@ -1651,4 +1651,61 @@ void main() {
|
||||
|
||||
expect(find.text('**validation error**'), findsOneWidget);
|
||||
});
|
||||
|
||||
group('context menu', () {
|
||||
testWidgets(
|
||||
'iOS uses the system context menu by default if supported',
|
||||
(WidgetTester tester) async {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher.supportsShowingSystemContextMenu =
|
||||
true;
|
||||
_updateMediaQueryFromView(tester);
|
||||
addTearDown(() {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher
|
||||
.resetSupportsShowingSystemContextMenu();
|
||||
_updateMediaQueryFromView(tester);
|
||||
});
|
||||
|
||||
final TextEditingController controller = TextEditingController(text: 'one two three');
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: Material(child: TextField(controller: controller))),
|
||||
);
|
||||
|
||||
// No context menu shown.
|
||||
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsNothing);
|
||||
|
||||
// Double tap to select the first word and show the menu.
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(SelectionOverlay.fadeDuration);
|
||||
|
||||
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsOneWidget);
|
||||
},
|
||||
skip: kIsWeb, // [intended] on web the browser handles the context menu.
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.iOS),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger MediaQuery to update itself based on the View, which is not
|
||||
// recreated between tests. This is necessary when changing something on
|
||||
// TestPlatformDispatcher and expecting it to be picked up by MediaQuery.
|
||||
// TODO(justinmc): This hack can be removed if
|
||||
// https://github.com/flutter/flutter/issues/165519 is fixed.
|
||||
void _updateMediaQueryFromView(WidgetTester tester) {
|
||||
expect(find.byType(MediaQuery), findsOneWidget);
|
||||
final WidgetsBindingObserver widgetsBindingObserver =
|
||||
tester.state(
|
||||
find.ancestor(
|
||||
of: find.byType(MediaQuery),
|
||||
matching: find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MediaQueryFromView',
|
||||
),
|
||||
),
|
||||
)
|
||||
as WidgetsBindingObserver;
|
||||
widgetsBindingObserver.didChangeMetrics();
|
||||
}
|
||||
|
||||
@ -5567,4 +5567,61 @@ void main() {
|
||||
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
group('context menu', () {
|
||||
testWidgets(
|
||||
'iOS uses the system context menu by default if supported',
|
||||
(WidgetTester tester) async {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher.supportsShowingSystemContextMenu =
|
||||
true;
|
||||
_updateMediaQueryFromView(tester);
|
||||
addTearDown(() {
|
||||
TestWidgetsFlutterBinding.instance.platformDispatcher
|
||||
.resetSupportsShowingSystemContextMenu();
|
||||
_updateMediaQueryFromView(tester);
|
||||
});
|
||||
|
||||
final TextEditingController controller = TextEditingController(text: 'one two three');
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: Material(child: TextField(controller: controller))),
|
||||
);
|
||||
|
||||
// No context menu shown.
|
||||
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsNothing);
|
||||
|
||||
// Double tap to select the first word and show the menu.
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.tapAt(textOffsetToPosition(tester, 1));
|
||||
await tester.pump(SelectionOverlay.fadeDuration);
|
||||
|
||||
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsNothing);
|
||||
expect(find.byType(SystemContextMenu), findsOneWidget);
|
||||
},
|
||||
skip: kIsWeb, // [intended] on web the browser handles the context menu.
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.iOS),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger MediaQuery to update itself based on the View, which is not
|
||||
// recreated between tests. This is necessary when changing something on
|
||||
// TestPlatformDispatcher and expecting it to be picked up by MediaQuery.
|
||||
// TODO(justinmc): This hack can be removed if
|
||||
// https://github.com/flutter/flutter/issues/165519 is fixed.
|
||||
void _updateMediaQueryFromView(WidgetTester tester) {
|
||||
expect(find.byType(MediaQuery), findsOneWidget);
|
||||
final WidgetsBindingObserver widgetsBindingObserver =
|
||||
tester.state(
|
||||
find.ancestor(
|
||||
of: find.byType(MediaQuery),
|
||||
matching: find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MediaQueryFromView',
|
||||
),
|
||||
),
|
||||
)
|
||||
as WidgetsBindingObserver;
|
||||
widgetsBindingObserver.didChangeMetrics();
|
||||
}
|
||||
|
||||
@ -83,6 +83,21 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('TestPlatformDispatcher can fake supportsShowingSystemContextMenu', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
verifyPropertyFaked<bool>(
|
||||
tester: tester,
|
||||
realValue: PlatformDispatcher.instance.supportsShowingSystemContextMenu,
|
||||
fakeValue: !PlatformDispatcher.instance.supportsShowingSystemContextMenu,
|
||||
propertyRetriever:
|
||||
() => WidgetsBinding.instance.platformDispatcher.supportsShowingSystemContextMenu,
|
||||
propertyFaker: (TestWidgetsFlutterBinding binding, bool fakeValue) {
|
||||
binding.platformDispatcher.supportsShowingSystemContextMenu = fakeValue;
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('TestPlatformDispatcher can fake brieflyShowPassword', (WidgetTester tester) async {
|
||||
verifyPropertyFaked<bool>(
|
||||
tester: tester,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user