CupertinoTextField accessibility behavior on Linux should match TextField (#159823)

While going through `TextField` and `CupertinoTextField` I noticed
https://github.com/flutter/flutter/pull/94898 and
https://github.com/flutter/flutter/pull/129652 did not make it over to
`CupertinoTextField`. This PR brings over those changes to
`CupertinoTextField`. On Linux after this change the
`CupertinoTextField` now focuses when gaining a11y focus, and unfocuses
when losing a11y focus.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

Co-authored-by: Renzo Olivares <roliv@google.com>
This commit is contained in:
Renzo Olivares 2024-12-10 12:32:45 -08:00 committed by GitHub
parent fe0e219b9e
commit 119f1707ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 26 additions and 8 deletions

View File

@ -1304,13 +1304,13 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
TextSelectionControls? textSelectionControls = widget.selectionControls;
VoidCallback? handleDidGainAccessibilityFocus;
VoidCallback? handleDidLoseAccessibilityFocus;
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
textSelectionControls ??= cupertinoTextSelectionHandleControls;
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
textSelectionControls ??= cupertinoDesktopTextSelectionHandleControls;
@ -1320,6 +1320,9 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
_effectiveFocusNode.requestFocus();
}
};
handleDidLoseAccessibilityFocus = () {
_effectiveFocusNode.unfocus();
};
}
final bool enabled = widget.enabled;
@ -1484,6 +1487,7 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
_requestKeyboard();
},
onDidGainAccessibilityFocus: handleDidGainAccessibilityFocus,
onDidLoseAccessibilityFocus: handleDidLoseAccessibilityFocus,
onFocus: enabled
? () {
assert(

View File

@ -503,7 +503,7 @@ void main() {
);
});
testWidgets('Activates the text field when receives semantics focus on Mac, Windows', (WidgetTester tester) async {
testWidgets('Activates the text field when receives semantics focus on desktops', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;
final FocusNode focusNode = FocusNode();
@ -538,6 +538,7 @@ void main() {
SemanticsAction.tap,
SemanticsAction.focus,
SemanticsAction.didGainAccessibilityFocus,
SemanticsAction.didLoseAccessibilityFocus,
],
textDirection: TextDirection.ltr,
),
@ -557,8 +558,11 @@ void main() {
semanticsOwner.performAction(4, SemanticsAction.didGainAccessibilityFocus);
await tester.pumpAndSettle();
expect(focusNode.hasFocus, isTrue);
semanticsOwner.performAction(4, SemanticsAction.didLoseAccessibilityFocus);
await tester.pumpAndSettle();
expect(focusNode.hasFocus, isFalse);
semantics.dispose();
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.windows }));
}, variant: TargetPlatformVariant.desktop());
testWidgets(
'takes available space horizontally and takes intrinsic space vertically no-strut',
@ -10458,8 +10462,13 @@ void main() {
actions: <SemanticsAction>[
SemanticsAction.tap,
SemanticsAction.focus,
if (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS)
SemanticsAction.didGainAccessibilityFocus,
if (defaultTargetPlatform == TargetPlatform.linux
|| defaultTargetPlatform == TargetPlatform.windows
|| defaultTargetPlatform == TargetPlatform.macOS)
...<SemanticsAction>[
SemanticsAction.didGainAccessibilityFocus,
SemanticsAction.didLoseAccessibilityFocus,
],
// TODO(gspencergoog): also test for the presence of SemanticsAction.focus when
// this iOS issue is addressed: https://github.com/flutter/flutter/issues/150030
],
@ -10515,8 +10524,13 @@ void main() {
SemanticsFlag.isReadOnly,
],
actions: <SemanticsAction>[
if (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS)
SemanticsAction.didGainAccessibilityFocus,
if (defaultTargetPlatform == TargetPlatform.linux
|| defaultTargetPlatform == TargetPlatform.windows
|| defaultTargetPlatform == TargetPlatform.macOS)
...<SemanticsAction>[
SemanticsAction.didGainAccessibilityFocus,
SemanticsAction.didLoseAccessibilityFocus,
],
],
),
],