Unverified Commit 01564c64 authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Windows: Focus text field on gaining a11y focus (#94898)

parent f704b0d7
...@@ -1160,15 +1160,14 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio ...@@ -1160,15 +1160,14 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
case TargetPlatform.android: case TargetPlatform.android:
case TargetPlatform.fuchsia: case TargetPlatform.fuchsia:
case TargetPlatform.linux: case TargetPlatform.linux:
case TargetPlatform.windows:
textSelectionControls ??= cupertinoTextSelectionControls; textSelectionControls ??= cupertinoTextSelectionControls;
break; break;
case TargetPlatform.macOS: case TargetPlatform.macOS:
case TargetPlatform.windows:
textSelectionControls ??= cupertinoDesktopTextSelectionControls; textSelectionControls ??= cupertinoDesktopTextSelectionControls;
handleDidGainAccessibilityFocus = () { handleDidGainAccessibilityFocus = () {
// macOS automatically activated the TextField when it receives // Automatically activate the TextField when it receives accessibility focus.
// accessibility focus.
if (!_effectiveFocusNode.hasFocus && _effectiveFocusNode.canRequestFocus) { if (!_effectiveFocusNode.hasFocus && _effectiveFocusNode.canRequestFocus) {
_effectiveFocusNode.requestFocus(); _effectiveFocusNode.requestFocus();
} }
......
...@@ -1197,8 +1197,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements ...@@ -1197,8 +1197,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
cursorRadius ??= const Radius.circular(2.0); cursorRadius ??= const Radius.circular(2.0);
cursorOffset = Offset(iOSHorizontalOffset / MediaQuery.of(context).devicePixelRatio, 0); cursorOffset = Offset(iOSHorizontalOffset / MediaQuery.of(context).devicePixelRatio, 0);
handleDidGainAccessibilityFocus = () { handleDidGainAccessibilityFocus = () {
// macOS automatically activated the TextField when it receives // Automatically activate the TextField when it receives accessibility focus.
// accessibility focus.
if (!_effectiveFocusNode.hasFocus && _effectiveFocusNode.canRequestFocus) { if (!_effectiveFocusNode.hasFocus && _effectiveFocusNode.canRequestFocus) {
_effectiveFocusNode.requestFocus(); _effectiveFocusNode.requestFocus();
} }
...@@ -1216,6 +1215,14 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements ...@@ -1216,6 +1215,14 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
break; break;
case TargetPlatform.linux: case TargetPlatform.linux:
forcePressEnabled = false;
textSelectionControls ??= desktopTextSelectionControls;
paintCursorAboveText = false;
cursorOpacityAnimates = false;
cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary;
selectionColor = selectionTheme.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
break;
case TargetPlatform.windows: case TargetPlatform.windows:
forcePressEnabled = false; forcePressEnabled = false;
textSelectionControls ??= desktopTextSelectionControls; textSelectionControls ??= desktopTextSelectionControls;
...@@ -1223,6 +1230,12 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements ...@@ -1223,6 +1230,12 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
cursorOpacityAnimates = false; cursorOpacityAnimates = false;
cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary; cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary;
selectionColor = selectionTheme.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40); selectionColor = selectionTheme.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
handleDidGainAccessibilityFocus = () {
// Automatically activate the TextField when it receives accessibility focus.
if (!_effectiveFocusNode.hasFocus && _effectiveFocusNode.canRequestFocus) {
_effectiveFocusNode.requestFocus();
}
};
break; break;
} }
......
...@@ -314,7 +314,7 @@ void main() { ...@@ -314,7 +314,7 @@ void main() {
); );
}); });
testWidgets('Activates the text field when receives semantics focus on Mac', (WidgetTester tester) async { testWidgets('Activates the text field when receives semantics focus on Mac, Windows', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!; final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
...@@ -362,7 +362,7 @@ void main() { ...@@ -362,7 +362,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(focusNode.hasFocus, isTrue); expect(focusNode.hasFocus, isTrue);
semantics.dispose(); semantics.dispose();
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.windows }));
testWidgets( testWidgets(
'takes available space horizontally and takes intrinsic space vertically no-strut', 'takes available space horizontally and takes intrinsic space vertically no-strut',
......
...@@ -629,7 +629,8 @@ void main() { ...@@ -629,7 +629,8 @@ void main() {
debugDefaultTargetPlatformOverride != TargetPlatform.macOS) SemanticsFlag.namesRoute, debugDefaultTargetPlatformOverride != TargetPlatform.macOS) SemanticsFlag.namesRoute,
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
if (debugDefaultTargetPlatformOverride == TargetPlatform.macOS) if (debugDefaultTargetPlatformOverride == TargetPlatform.macOS ||
debugDefaultTargetPlatformOverride == TargetPlatform.windows)
SemanticsAction.didGainAccessibilityFocus, SemanticsAction.didGainAccessibilityFocus,
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.setSelection, SemanticsAction.setSelection,
......
...@@ -286,7 +286,7 @@ void main() { ...@@ -286,7 +286,7 @@ void main() {
skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu. skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
); );
testWidgets('Activates the text field when receives semantics focus on Mac', (WidgetTester tester) async { testWidgets('Activates the text field when receives semantics focus on Mac, Windows', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!; final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
...@@ -337,7 +337,7 @@ void main() { ...@@ -337,7 +337,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(focusNode.hasFocus, isTrue); expect(focusNode.hasFocus, isTrue);
semantics.dispose(); semantics.dispose();
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.windows }));
testWidgets('TextField passes onEditingComplete to EditableText', (WidgetTester tester) async { testWidgets('TextField passes onEditingComplete to EditableText', (WidgetTester tester) async {
void onEditingComplete() { } void onEditingComplete() { }
......
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