Request focus if SemanticsAction.focus is sent to a focusable widget (#142942)

## Description

This causes the `Focus` widget to request focus on its focus node if the accessibility system (screen reader) focuses a widget via the `SemanticsAction.focus` action.

## Related Issues
 - https://github.com/flutter/flutter/issues/83809

## Tests
 - Added a test to make sure that focus is requested when `SemanticsAction.focus` is sent by the engine.
This commit is contained in:
Greg Spencer 2024-06-04 17:42:59 -07:00 committed by GitHub
parent 4d21d2dd5f
commit dd700e6d7c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
58 changed files with 281 additions and 70 deletions

View File

@ -20,6 +20,7 @@ void main() {
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
label: 'Update border shape', label: 'Update border shape',
)); ));
@ -29,6 +30,7 @@ void main() {
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
label: 'Reset chips', label: 'Reset chips',
)); ));

View File

@ -671,6 +671,14 @@ class _FocusState extends State<Focus> {
Widget child = widget.child; Widget child = widget.child;
if (widget.includeSemantics) { if (widget.includeSemantics) {
child = Semantics( child = Semantics(
// Automatically request the focus for a focusable widget when it
// receives an input focus action from the semantics. Nothing is needed
// for losing the focus because if focus is lost, that means another
// node will gain focus and take focus from this widget.
onFocus:
_couldRequestFocus
? focusNode.requestFocus
: null,
focusable: _couldRequestFocus, focusable: _couldRequestFocus,
focused: _hadPrimaryFocus, focused: _hadPrimaryFocus,
child: widget.child, child: widget.child,

View File

@ -34,6 +34,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
@ -54,6 +55,7 @@ void main() {
isChecked: true, isChecked: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
@ -73,6 +75,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
// isFocusable is delayed by 1 frame. // isFocusable is delayed by 1 frame.
isFocusable: true, isFocusable: true,
hasFocusAction: true,
)); ));
await tester.pump(); await tester.pump();
@ -178,6 +181,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
handle.dispose(); handle.dispose();
@ -247,7 +251,7 @@ void main() {
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
SemanticsFlag.isCheckStateMixed, SemanticsFlag.isCheckStateMixed,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), hasLength(1)); ), hasLength(1));
await tester.pumpWidget( await tester.pumpWidget(
@ -268,7 +272,7 @@ void main() {
SemanticsFlag.isChecked, SemanticsFlag.isChecked,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), hasLength(1)); ), hasLength(1));
await tester.pumpWidget( await tester.pumpWidget(
@ -288,7 +292,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), hasLength(1)); ), hasLength(1));
semantics.dispose(); semantics.dispose();

View File

@ -147,6 +147,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
); );
@ -171,6 +172,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
isInMutuallyExclusiveGroup: true, isInMutuallyExclusiveGroup: true,
)); ));
@ -190,6 +192,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
isInMutuallyExclusiveGroup: true, isInMutuallyExclusiveGroup: true,
isChecked: true, isChecked: true,
@ -210,6 +213,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isFocusable: true, isFocusable: true,
isInMutuallyExclusiveGroup: true, isInMutuallyExclusiveGroup: true,
hasFocusAction: true,
)); ));
await tester.pump(); await tester.pump();

View File

@ -1945,7 +1945,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(semantics, isNot(includesNodeWith( expect(semantics, isNot(includesNodeWith(
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Dismiss', label: 'Dismiss',
))); )));
debugDefaultTargetPlatformOverride = null; debugDefaultTargetPlatformOverride = null;

View File

@ -2621,7 +2621,7 @@ void main() {
), ),
); );
expect(semantics, isNot(includesNodeWith(actions: <SemanticsAction>[SemanticsAction.tap]))); expect(semantics, isNot(includesNodeWith(actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus])));
semantics.dispose(); semantics.dispose();
}); });

View File

@ -215,6 +215,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
handle.dispose(); handle.dispose();
@ -258,6 +259,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
handle.dispose(); handle.dispose();

View File

@ -2111,6 +2111,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -2120,6 +2121,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -2129,6 +2131,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
}); });
@ -2165,6 +2168,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -2174,6 +2178,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -2183,6 +2188,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
}); });
@ -2515,6 +2521,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -2524,6 +2531,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
}); });
@ -2558,6 +2566,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -2567,6 +2576,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
}); });
@ -2747,13 +2757,13 @@ void main() {
SemanticsFlag.isSelected, SemanticsFlag.isSelected,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'A\nTab 1 of 2', label: 'A\nTab 1 of 2',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
TestSemantics( TestSemantics(
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'B\nTab 2 of 2', label: 'B\nTab 2 of 2',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),

View File

@ -864,6 +864,7 @@ void main() {
tooltip: 'Previous month', tooltip: 'Previous month',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isEnabled: true, isEnabled: true,
hasEnabledState: true, hasEnabledState: true,
isFocusable: true, isFocusable: true,
@ -872,6 +873,7 @@ void main() {
tooltip: 'Next month', tooltip: 'Next month',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isEnabled: true, isEnabled: true,
hasEnabledState: true, hasEnabledState: true,
isFocusable: true, isFocusable: true,
@ -882,90 +884,105 @@ void main() {
label: '1, Friday, January 1, 2016', label: '1, Friday, January 1, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('2')), matchesSemantics( expect(tester.getSemantics(find.text('2')), matchesSemantics(
label: '2, Saturday, January 2, 2016', label: '2, Saturday, January 2, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('3')), matchesSemantics( expect(tester.getSemantics(find.text('3')), matchesSemantics(
label: '3, Sunday, January 3, 2016, Today', label: '3, Sunday, January 3, 2016, Today',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('4')), matchesSemantics( expect(tester.getSemantics(find.text('4')), matchesSemantics(
label: '4, Monday, January 4, 2016', label: '4, Monday, January 4, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('5')), matchesSemantics( expect(tester.getSemantics(find.text('5')), matchesSemantics(
label: '5, Tuesday, January 5, 2016', label: '5, Tuesday, January 5, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('6')), matchesSemantics( expect(tester.getSemantics(find.text('6')), matchesSemantics(
label: '6, Wednesday, January 6, 2016', label: '6, Wednesday, January 6, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('7')), matchesSemantics( expect(tester.getSemantics(find.text('7')), matchesSemantics(
label: '7, Thursday, January 7, 2016', label: '7, Thursday, January 7, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('8')), matchesSemantics( expect(tester.getSemantics(find.text('8')), matchesSemantics(
label: '8, Friday, January 8, 2016', label: '8, Friday, January 8, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('9')), matchesSemantics( expect(tester.getSemantics(find.text('9')), matchesSemantics(
label: '9, Saturday, January 9, 2016', label: '9, Saturday, January 9, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('10')), matchesSemantics( expect(tester.getSemantics(find.text('10')), matchesSemantics(
label: '10, Sunday, January 10, 2016', label: '10, Sunday, January 10, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('11')), matchesSemantics( expect(tester.getSemantics(find.text('11')), matchesSemantics(
label: '11, Monday, January 11, 2016', label: '11, Monday, January 11, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('12')), matchesSemantics( expect(tester.getSemantics(find.text('12')), matchesSemantics(
label: '12, Tuesday, January 12, 2016', label: '12, Tuesday, January 12, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('13')), matchesSemantics( expect(tester.getSemantics(find.text('13')), matchesSemantics(
label: '13, Wednesday, January 13, 2016', label: '13, Wednesday, January 13, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('14')), matchesSemantics( expect(tester.getSemantics(find.text('14')), matchesSemantics(
label: '14, Thursday, January 14, 2016', label: '14, Thursday, January 14, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('15')), matchesSemantics( expect(tester.getSemantics(find.text('15')), matchesSemantics(
label: '15, Friday, January 15, 2016', label: '15, Friday, January 15, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isSelected: true, isSelected: true,
isFocusable: true, isFocusable: true,
)); ));
@ -973,90 +990,105 @@ void main() {
label: '16, Saturday, January 16, 2016', label: '16, Saturday, January 16, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('17')), matchesSemantics( expect(tester.getSemantics(find.text('17')), matchesSemantics(
label: '17, Sunday, January 17, 2016', label: '17, Sunday, January 17, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('18')), matchesSemantics( expect(tester.getSemantics(find.text('18')), matchesSemantics(
label: '18, Monday, January 18, 2016', label: '18, Monday, January 18, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('19')), matchesSemantics( expect(tester.getSemantics(find.text('19')), matchesSemantics(
label: '19, Tuesday, January 19, 2016', label: '19, Tuesday, January 19, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('20')), matchesSemantics( expect(tester.getSemantics(find.text('20')), matchesSemantics(
label: '20, Wednesday, January 20, 2016', label: '20, Wednesday, January 20, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('21')), matchesSemantics( expect(tester.getSemantics(find.text('21')), matchesSemantics(
label: '21, Thursday, January 21, 2016', label: '21, Thursday, January 21, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('22')), matchesSemantics( expect(tester.getSemantics(find.text('22')), matchesSemantics(
label: '22, Friday, January 22, 2016', label: '22, Friday, January 22, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('23')), matchesSemantics( expect(tester.getSemantics(find.text('23')), matchesSemantics(
label: '23, Saturday, January 23, 2016', label: '23, Saturday, January 23, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('24')), matchesSemantics( expect(tester.getSemantics(find.text('24')), matchesSemantics(
label: '24, Sunday, January 24, 2016', label: '24, Sunday, January 24, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('25')), matchesSemantics( expect(tester.getSemantics(find.text('25')), matchesSemantics(
label: '25, Monday, January 25, 2016', label: '25, Monday, January 25, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('26')), matchesSemantics( expect(tester.getSemantics(find.text('26')), matchesSemantics(
label: '26, Tuesday, January 26, 2016', label: '26, Tuesday, January 26, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('27')), matchesSemantics( expect(tester.getSemantics(find.text('27')), matchesSemantics(
label: '27, Wednesday, January 27, 2016', label: '27, Wednesday, January 27, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('28')), matchesSemantics( expect(tester.getSemantics(find.text('28')), matchesSemantics(
label: '28, Thursday, January 28, 2016', label: '28, Thursday, January 28, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('29')), matchesSemantics( expect(tester.getSemantics(find.text('29')), matchesSemantics(
label: '29, Friday, January 29, 2016', label: '29, Friday, January 29, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
expect(tester.getSemantics(find.text('30')), matchesSemantics( expect(tester.getSemantics(find.text('30')), matchesSemantics(
label: '30, Saturday, January 30, 2016', label: '30, Saturday, January 30, 2016',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
semantics.dispose(); semantics.dispose();
@ -1081,6 +1113,7 @@ void main() {
expect(tester.getSemantics(find.text('$year')), matchesSemantics( expect(tester.getSemantics(find.text('$year')), matchesSemantics(
label: '$year', label: '$year',
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isSelected: year == 2016, isSelected: year == 2016,
isFocusable: true, isFocusable: true,
isButton: true, isButton: true,

View File

@ -130,6 +130,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.hasEnabledState, SemanticsFlag.hasEnabledState,

View File

@ -1189,6 +1189,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
label: 'Hello\nthere', label: 'Hello\nthere',
)); ));

View File

@ -78,6 +78,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
@ -97,6 +98,7 @@ void main() {
isChecked: true, isChecked: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
@ -115,6 +117,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
// isFocusable is delayed by 1 frame. // isFocusable is delayed by 1 frame.
isFocusable: true, isFocusable: true,
hasFocusAction: true,
)); ));
await tester.pump(); await tester.pump();
@ -213,6 +216,7 @@ void main() {
isChecked: true, isChecked: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
handle.dispose(); handle.dispose();
@ -242,6 +246,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
handle.dispose(); handle.dispose();
@ -317,7 +322,7 @@ void main() {
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
SemanticsFlag.isCheckStateMixed, SemanticsFlag.isCheckStateMixed,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), hasLength(1)); ), hasLength(1));
await tester.pumpWidget( await tester.pumpWidget(
@ -341,7 +346,7 @@ void main() {
SemanticsFlag.isChecked, SemanticsFlag.isChecked,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), hasLength(1)); ), hasLength(1));
await tester.pumpWidget( await tester.pumpWidget(
@ -364,7 +369,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), hasLength(1)); ), hasLength(1));
semantics.dispose(); semantics.dispose();

View File

@ -2971,7 +2971,7 @@ void main() {
children: <TestSemantics>[ children: <TestSemantics>[
TestSemantics( TestSemantics(
tooltip: 'Delete', tooltip: 'Delete',
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.isButton, SemanticsFlag.isButton,
@ -3030,7 +3030,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
], ],
), ),
@ -3088,7 +3088,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
], ],
), ),
@ -3141,7 +3141,7 @@ void main() {
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
SemanticsFlag.isSelected, SemanticsFlag.isSelected,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
], ],
), ),
@ -3295,7 +3295,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
], ],
), ),

View File

@ -1545,6 +1545,7 @@ void main() {
label: '3, Sunday, January 3, 2016, Today', label: '3, Sunday, January 3, 2016, Today',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
@ -1553,6 +1554,7 @@ void main() {
tooltip: 'Switch to input', tooltip: 'Switch to input',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isEnabled: true, isEnabled: true,
hasEnabledState: true, hasEnabledState: true,
isFocusable: true, isFocusable: true,
@ -1565,6 +1567,7 @@ void main() {
label: 'OK', label: 'OK',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isEnabled: true, isEnabled: true,
hasEnabledState: true, hasEnabledState: true,
isFocusable: true, isFocusable: true,
@ -1573,6 +1576,7 @@ void main() {
label: 'CANCEL', label: 'CANCEL',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isEnabled: true, isEnabled: true,
hasEnabledState: true, hasEnabledState: true,
isFocusable: true, isFocusable: true,
@ -1603,6 +1607,7 @@ void main() {
tooltip: 'Switch to calendar', tooltip: 'Switch to calendar',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isEnabled: true, isEnabled: true,
hasEnabledState: true, hasEnabledState: true,
isFocusable: true, isFocusable: true,
@ -1630,6 +1635,7 @@ void main() {
label: 'OK', label: 'OK',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isEnabled: true, isEnabled: true,
hasEnabledState: true, hasEnabledState: true,
isFocusable: true, isFocusable: true,
@ -1638,6 +1644,7 @@ void main() {
label: 'CANCEL', label: 'CANCEL',
isButton: true, isButton: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isEnabled: true, isEnabled: true,
hasEnabledState: true, hasEnabledState: true,
isFocusable: true, isFocusable: true,

View File

@ -1319,6 +1319,7 @@ void main() {
matchesSemantics( matchesSemantics(
label: '30, Saturday, January 30, 2016, Today', label: '30, Saturday, January 30, 2016, Today',
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
), ),
); );

View File

@ -182,6 +182,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
handle.dispose(); handle.dispose();
@ -239,6 +240,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
handle.dispose(); handle.dispose();

View File

@ -147,7 +147,7 @@ void main() {
expect(semantics, isNot(includesNodeWith( expect(semantics, isNot(includesNodeWith(
label: const DefaultMaterialLocalizations().modalBarrierDismissLabel, label: const DefaultMaterialLocalizations().modalBarrierDismissLabel,
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
))); )));
semantics.dispose(); semantics.dispose();

View File

@ -1300,6 +1300,7 @@ void main() {
isButton: true, isButton: true,
label: 'test', label: 'test',
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
@ -1315,6 +1316,7 @@ void main() {
isButton: true, isButton: true,
label: 'three', label: 'three',
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isFocusable: true, isFocusable: true,
)); ));
handle.dispose(); handle.dispose();
@ -1360,28 +1362,28 @@ void main() {
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')], tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
TestSemantics( TestSemantics(
label: 'two', label: 'two',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')], tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
TestSemantics( TestSemantics(
label: 'three', label: 'three',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')], tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
TestSemantics( TestSemantics(
label: 'four', label: 'four',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')], tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
], ],
), ),

View File

@ -819,6 +819,7 @@ void main() {
TestSemantics.rootChild( TestSemantics.rootChild(
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
label: 'ABC', label: 'ABC',
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),

View File

@ -217,6 +217,7 @@ void main() {
expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics( expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
@ -233,6 +234,7 @@ void main() {
expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics( expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
@ -258,6 +260,7 @@ void main() {
children: <Matcher>[ children: <Matcher>[
matchesSemantics( matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
@ -277,6 +280,7 @@ void main() {
children: <Matcher>[ children: <Matcher>[
matchesSemantics( matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,

View File

@ -211,6 +211,7 @@ void main() {
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
)); ));
// Check custom header widget semantics is preserved. // Check custom header widget semantics is preserved.
@ -261,6 +262,7 @@ void main() {
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
], ],
)); ));
@ -1099,6 +1101,7 @@ void main() {
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
onTapHint: localizations.expandedIconTapHint, onTapHint: localizations.expandedIconTapHint,
)); ));
@ -1123,6 +1126,7 @@ void main() {
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
onTapHint: localizations.collapsedIconTapHint, onTapHint: localizations.collapsedIconTapHint,
)); ));
@ -1187,6 +1191,7 @@ void main() {
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
], ],
)); ));
@ -1215,6 +1220,7 @@ void main() {
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
], ],
)); ));
@ -1268,6 +1274,7 @@ void main() {
isFocusable: true, isFocusable: true,
hasEnabledState: true, hasEnabledState: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
)); ));
expect(tester.getSemantics(find.byKey(collapsedKey)), matchesSemantics( expect(tester.getSemantics(find.byKey(collapsedKey)), matchesSemantics(
@ -1276,6 +1283,7 @@ void main() {
isFocusable: true, isFocusable: true,
hasEnabledState: true, hasEnabledState: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
)); ));
handle.dispose(); handle.dispose();

View File

@ -728,6 +728,7 @@ void main() {
tester.getSemantics(find.byType(ListTile).first), tester.getSemantics(find.byType(ListTile).first),
matchesSemantics( matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
isFocused: true, isFocused: true,
@ -742,6 +743,7 @@ void main() {
tester.getSemantics(find.byType(ListTile).last), tester.getSemantics(find.byType(ListTile).last),
matchesSemantics( matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
isFocusable: true, isFocusable: true,

View File

@ -1004,6 +1004,7 @@ void main() {
TestSemantics.rootChild( TestSemantics.rootChild(
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
label: 'ABC', label: 'ABC',
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),

View File

@ -631,6 +631,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
], ],
@ -699,6 +700,7 @@ void main() {
tooltip: 'Add Photo', tooltip: 'Add Photo',
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.hasEnabledState, SemanticsFlag.hasEnabledState,
@ -922,6 +924,7 @@ void main() {
tester.getSemantics(find.byType(FloatingActionButton)), tester.getSemantics(find.byType(FloatingActionButton)),
matchesSemantics( matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
hasEnabledState: true, hasEnabledState: true,
isButton: true, isButton: true,
isEnabled: true, isEnabled: true,

View File

@ -616,6 +616,7 @@ void main() {
rect: const Rect.fromLTRB(0.0, 0.0, 48.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 48.0, 48.0),
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.hasEnabledState, SemanticsFlag.hasEnabledState,
@ -690,6 +691,7 @@ void main() {
TestSemantics( TestSemantics(
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.hasEnabledState, SemanticsFlag.hasEnabledState,
@ -2177,6 +2179,7 @@ void main() {
TestSemantics.rootChild( TestSemantics.rootChild(
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),
transform: Matrix4.translationValues(356.0, 276.0, 0.0), transform: Matrix4.translationValues(356.0, 276.0, 0.0),

View File

@ -1178,7 +1178,7 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async {
), ),
), ),
)); ));
expect(semantics, includesNodeWith(label: 'Button', actions: <SemanticsAction>[SemanticsAction.tap])); expect(semantics, includesNodeWith(label: 'Button', actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus]));
await tester.pumpWidget(Directionality( await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
@ -1190,7 +1190,7 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async {
), ),
), ),
)); ));
expect(semantics, isNot(includesNodeWith(label: 'Button', actions: <SemanticsAction>[SemanticsAction.tap]))); expect(semantics, isNot(includesNodeWith(label: 'Button', actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus])));
semantics.dispose(); semantics.dispose();
}); });
@ -1983,6 +1983,7 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async {
label: 'Foo', label: 'Foo',
hasLongPressAction: true, hasLongPressAction: true,
isFocusable: true, isFocusable: true,
hasFocusAction: true,
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
)); ));
@ -2003,6 +2004,7 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async {
expect(tester.getSemantics(find.bySemanticsLabel('Foo')), matchesSemantics( expect(tester.getSemantics(find.bySemanticsLabel('Foo')), matchesSemantics(
label: 'Foo', label: 'Foo',
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
hasLongPressAction: true, hasLongPressAction: true,
isFocusable: true, isFocusable: true,
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,

View File

@ -308,7 +308,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'two', label: 'two',
), ),
TestSemantics.rootChild( TestSemantics.rootChild(

View File

@ -620,6 +620,7 @@ void main() {
label: 'Button', label: 'Button',
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.hasEnabledState, SemanticsFlag.hasEnabledState,
@ -661,6 +662,7 @@ void main() {
SemanticsFlag.isButton, SemanticsFlag.isButton,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.focus],
), ),
], ],
), ),

View File

@ -3421,6 +3421,7 @@ void main() {
TestSemantics.rootChild( TestSemantics.rootChild(
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
label: 'ABC', label: 'ABC',
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),
@ -3551,7 +3552,7 @@ void main() {
SemanticsFlag.hasExpandedState, SemanticsFlag.hasExpandedState,
SemanticsFlag.isExpanded, SemanticsFlag.isExpanded,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'ABC', label: 'ABC',
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),
), ),
@ -3573,7 +3574,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
], ],
), ),
@ -3621,7 +3622,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'ABC', label: 'ABC',
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),
), ),

View File

@ -559,6 +559,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -568,6 +569,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
@ -580,6 +582,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -590,6 +593,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
}); });
@ -624,6 +628,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -633,6 +638,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
@ -645,6 +651,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -655,6 +662,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
}); });

View File

@ -324,6 +324,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -333,6 +334,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
@ -345,6 +347,7 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
isFocusable: true, isFocusable: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
expect( expect(
@ -355,6 +358,7 @@ void main() {
isFocusable: true, isFocusable: true,
isSelected: true, isSelected: true,
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
), ),
); );
}); });

View File

@ -5513,25 +5513,25 @@ TestSemantics _expectedSemantics() {
SemanticsFlag.isSelected, SemanticsFlag.isSelected,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Abc\nTab 1 of 4', label: 'Abc\nTab 1 of 4',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
TestSemantics( TestSemantics(
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Def\nTab 2 of 4', label: 'Def\nTab 2 of 4',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
TestSemantics( TestSemantics(
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Ghi\nTab 3 of 4', label: 'Ghi\nTab 3 of 4',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
TestSemantics( TestSemantics(
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Jkl\nTab 4 of 4', label: 'Jkl\nTab 4 of 4',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),

View File

@ -1073,6 +1073,7 @@ void main() {
TestSemantics.rootChild( TestSemantics.rootChild(
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
label: 'ABC', label: 'ABC',
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),

View File

@ -1219,7 +1219,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: '1', label: '1',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -1230,7 +1230,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: '2', label: '2',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -1241,7 +1241,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: '3', label: '3',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -1252,7 +1252,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: '4', label: '4',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -1263,7 +1263,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: '5', label: '5',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -1351,7 +1351,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'test1\ntest2', label: 'test1\ntest2',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -1432,7 +1432,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: '1', label: '1',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -1452,7 +1452,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: '3', label: '3',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -1463,7 +1463,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: '4', label: '4',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -1474,7 +1474,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: '5', label: '5',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),

View File

@ -411,7 +411,7 @@ void main() {
SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isInMutuallyExclusiveGroup,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Title', label: 'Title',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -448,7 +448,7 @@ void main() {
SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isInMutuallyExclusiveGroup,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Title', label: 'Title',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -483,6 +483,7 @@ void main() {
SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isInMutuallyExclusiveGroup,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.focus],
label: 'Title', label: 'Title',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),

View File

@ -221,6 +221,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
); );
@ -254,6 +255,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
], ],
@ -284,6 +286,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
], ],
@ -310,6 +313,7 @@ void main() {
SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isInMutuallyExclusiveGroup,
SemanticsFlag.isFocusable, // This flag is delayed by 1 frame. SemanticsFlag.isFocusable, // This flag is delayed by 1 frame.
], ],
actions: <SemanticsAction>[SemanticsAction.focus],
), ),
], ],
), ignoreRect: true, ignoreTransform: true)); ), ignoreRect: true, ignoreTransform: true));

View File

@ -160,6 +160,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
label: '+', label: '+',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,

View File

@ -751,6 +751,7 @@ void main() {
hasEnabledState: true, hasEnabledState: true,
label: 'Switch tile', label: 'Switch tile',
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
)); ));
handle.dispose(); handle.dispose();
}); });

View File

@ -662,7 +662,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
tooltip: 'Back', tooltip: 'Back',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -718,7 +718,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Suggestions', label: 'Suggestions',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -812,7 +812,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
tooltip: 'Back', tooltip: 'Back',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),
@ -856,7 +856,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Suggestions', label: 'Suggestions',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),

View File

@ -449,6 +449,7 @@ void main() {
label: '1', label: '1',
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
@ -466,6 +467,7 @@ void main() {
label: '2', label: '2',
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
@ -529,6 +531,7 @@ void main() {
label: '1', label: '1',
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
@ -544,6 +547,7 @@ void main() {
label: '2', label: '2',
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),

View File

@ -1292,6 +1292,7 @@ void main() {
SemanticsFlag.isSlider, SemanticsFlag.isSlider,
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.focus,
SemanticsAction.increase, SemanticsAction.increase,
SemanticsAction.decrease, SemanticsAction.decrease,
], ],
@ -1350,6 +1351,7 @@ void main() {
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
SemanticsFlag.isSlider, SemanticsFlag.isSlider,
], ],
actions: <SemanticsAction>[SemanticsAction.focus],
value: '50%', value: '50%',
increasedValue: '55%', increasedValue: '55%',
decreasedValue: '45%', decreasedValue: '45%',
@ -1452,7 +1454,7 @@ void main() {
TestSemantics( TestSemantics(
id: 4, id: 4,
flags: <SemanticsFlag>[SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider], flags: <SemanticsFlag>[SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider],
actions: <SemanticsAction>[SemanticsAction.increase, SemanticsAction.decrease], actions: <SemanticsAction>[SemanticsAction.focus, SemanticsAction.increase, SemanticsAction.decrease],
value: '50%', value: '50%',
increasedValue: '60%', increasedValue: '60%',
decreasedValue: '40%', decreasedValue: '40%',
@ -1565,6 +1567,7 @@ void main() {
SemanticsFlag.isSlider, SemanticsFlag.isSlider,
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.focus,
SemanticsAction.increase, SemanticsAction.increase,
SemanticsAction.decrease, SemanticsAction.decrease,
SemanticsAction.didGainAccessibilityFocus, SemanticsAction.didGainAccessibilityFocus,
@ -1625,6 +1628,7 @@ void main() {
SemanticsFlag.isSlider, SemanticsFlag.isSlider,
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.focus,
SemanticsAction.didGainAccessibilityFocus, SemanticsAction.didGainAccessibilityFocus,
], ],
value: '50%', value: '50%',
@ -1729,7 +1733,7 @@ void main() {
TestSemantics( TestSemantics(
id: 4, id: 4,
flags: <SemanticsFlag>[SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider], flags: <SemanticsFlag>[SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider],
actions: <SemanticsAction>[SemanticsAction.increase, SemanticsAction.decrease], actions: <SemanticsAction>[SemanticsAction.focus, SemanticsAction.increase, SemanticsAction.decrease],
value: '40', value: '40',
increasedValue: '60', increasedValue: '60',
decreasedValue: '20', decreasedValue: '20',
@ -1789,7 +1793,7 @@ void main() {
TestSemantics( TestSemantics(
id: 4, id: 4,
flags: <SemanticsFlag>[SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider], flags: <SemanticsFlag>[SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider],
actions: <SemanticsAction>[SemanticsAction.increase, SemanticsAction.decrease], actions: <SemanticsAction>[SemanticsAction.focus, SemanticsAction.increase, SemanticsAction.decrease],
value: '40', value: '40',
increasedValue: '60', increasedValue: '60',
decreasedValue: '20', decreasedValue: '20',
@ -2633,6 +2637,7 @@ void main() {
SemanticsFlag.isSlider, SemanticsFlag.isSlider,
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.focus,
SemanticsAction.increase, SemanticsAction.increase,
SemanticsAction.decrease, SemanticsAction.decrease,
SemanticsAction.didGainAccessibilityFocus, SemanticsAction.didGainAccessibilityFocus,

View File

@ -78,7 +78,7 @@ void main() {
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
SemanticsFlag.isToggled, SemanticsFlag.isToggled,
], ],
actions: SemanticsAction.tap.index, actions: SemanticsAction.tap.index | SemanticsAction.focus.index,
label: 'aaa\nAAA', label: 'aaa\nAAA',
), ),
TestSemantics.rootChild( TestSemantics.rootChild(
@ -92,7 +92,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: SemanticsAction.tap.index, actions: SemanticsAction.tap.index | SemanticsAction.focus.index,
label: 'bbb\nBBB', label: 'bbb\nBBB',
), ),
TestSemantics.rootChild( TestSemantics.rootChild(
@ -106,7 +106,7 @@ void main() {
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isInMutuallyExclusiveGroup,
], ],
actions: SemanticsAction.tap.index, actions: SemanticsAction.tap.index | SemanticsAction.focus.index,
label: 'CCC\nccc', label: 'CCC\nccc',
), ),
], ],

View File

@ -3592,7 +3592,7 @@ void main() {
children: <TestSemantics>[ children: <TestSemantics>[
TestSemantics( TestSemantics(
id: 4, id: 4,
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.isSelected, SemanticsFlag.isSelected,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
@ -3604,7 +3604,7 @@ void main() {
TestSemantics( TestSemantics(
id: 5, id: 5,
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'TAB #1\nTab 2 of 2', label: 'TAB #1\nTab 2 of 2',
rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight), rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight),
transform: Matrix4.translationValues(116.0, 276.0, 0.0), transform: Matrix4.translationValues(116.0, 276.0, 0.0),
@ -3863,7 +3863,7 @@ void main() {
SemanticsFlag.isSelected, SemanticsFlag.isSelected,
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Semantics override 0\nTab 1 of 2', label: 'Semantics override 0\nTab 1 of 2',
rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight), rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight),
transform: Matrix4.translationValues(0.0, 276.0, 0.0), transform: Matrix4.translationValues(0.0, 276.0, 0.0),
@ -3871,7 +3871,7 @@ void main() {
TestSemantics( TestSemantics(
id: 5, id: 5,
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Semantics override 1\nTab 2 of 2', label: 'Semantics override 1\nTab 2 of 2',
rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight), rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight),
transform: Matrix4.translationValues(116.0, 276.0, 0.0), transform: Matrix4.translationValues(116.0, 276.0, 0.0),
@ -5652,14 +5652,14 @@ void main() {
flags: <SemanticsFlag>[SemanticsFlag.isFocusable, SemanticsFlag.isSelected], flags: <SemanticsFlag>[SemanticsFlag.isFocusable, SemanticsFlag.isSelected],
id: 2, id: 2,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
actions: 1, actions: 1 | SemanticsAction.focus.index,
), ),
TestSemantics( TestSemantics(
label: 'TAB2\nTab 2 of 2', label: 'TAB2\nTab 2 of 2',
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
id: 3, id: 3,
rect: TestSemantics.fullScreen, rect: TestSemantics.fullScreen,
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
), ),
TestSemantics( TestSemantics(
id: 4, id: 4,

View File

@ -607,6 +607,7 @@ void main() {
TestSemantics.rootChild( TestSemantics.rootChild(
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
label: 'ABC', label: 'ABC',
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),

View File

@ -6964,7 +6964,7 @@ void main() {
), ),
); );
expect(semantics, isNot(includesNodeWith(actions: <SemanticsAction>[SemanticsAction.tap]))); expect(semantics, isNot(includesNodeWith(actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus])));
semantics.dispose(); semantics.dispose();
}); });
@ -7005,7 +7005,7 @@ void main() {
), ),
); );
expect(semantics, isNot(includesNodeWith(actions: <SemanticsAction>[SemanticsAction.tap]))); expect(semantics, isNot(includesNodeWith(actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus])));
semantics.dispose(); semantics.dispose();
}); });

View File

@ -1250,7 +1250,7 @@ void main() {
semantics, semantics,
includesNodeWith( includesNodeWith(
label: amString, label: amString,
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.isButton, SemanticsFlag.isButton,
SemanticsFlag.isChecked, SemanticsFlag.isChecked,
@ -1264,7 +1264,7 @@ void main() {
semantics, semantics,
includesNodeWith( includesNodeWith(
label: pmString, label: pmString,
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.isButton, SemanticsFlag.isButton,
SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isInMutuallyExclusiveGroup,

View File

@ -2117,6 +2117,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
rect: const Rect.fromLTRB(0.0, 0.0, 87.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 87.0, 48.0),
), ),
@ -2130,6 +2131,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0) rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0)
), ),
@ -2143,6 +2145,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),
), ),
@ -2188,6 +2191,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
TestSemantics( TestSemantics(
@ -2201,6 +2205,7 @@ void main() {
], ],
actions: <SemanticsAction>[ actions: <SemanticsAction>[
SemanticsAction.tap, SemanticsAction.tap,
SemanticsAction.focus,
], ],
), ),
], ],

View File

@ -531,6 +531,7 @@ void main() {
flags: <SemanticsFlag>[SemanticsFlag.isFocusable], flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
label: 'Signed in\nname\nemail', label: 'Signed in\nname\nemail',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
actions: <SemanticsAction>[SemanticsAction.focus],
children: <TestSemantics>[ children: <TestSemantics>[
TestSemantics( TestSemantics(
label: r'B', label: r'B',

View File

@ -48,6 +48,7 @@ void main() {
matchesSemantics( matchesSemantics(
label: 'button', label: 'button',
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isButton: true, isButton: true,
isFocusable: true, isFocusable: true,
hasEnabledState: true, hasEnabledState: true,

View File

@ -1013,9 +1013,11 @@ void main() {
// This semantic is from `Focus` widget under `FocusableActionDetector`. // This semantic is from `Focus` widget under `FocusableActionDetector`.
matchesSemantics( matchesSemantics(
isFocusable: true, isFocusable: true,
hasFocusAction: true,
children: <Matcher>[ children: <Matcher>[
matchesSemantics( matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isButton: true, isButton: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
@ -1025,6 +1027,7 @@ void main() {
), ),
matchesSemantics( matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isButton: true, isButton: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
@ -1068,6 +1071,7 @@ void main() {
children: <Matcher>[ children: <Matcher>[
matchesSemantics( matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isButton: true, isButton: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,
@ -1077,6 +1081,7 @@ void main() {
), ),
matchesSemantics( matchesSemantics(
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isButton: true, isButton: true,
hasEnabledState: true, hasEnabledState: true,
isEnabled: true, isEnabled: true,

View File

@ -858,6 +858,7 @@ void main() {
matchesSemantics( matchesSemantics(
label: 'button', label: 'button',
hasTapAction: true, hasTapAction: true,
hasFocusAction: true,
isButton: true, isButton: true,
isFocusable: true, isFocusable: true,
hasEnabledState: true, hasEnabledState: true,

View File

@ -348,7 +348,7 @@ void main() {
scaffoldKey.currentState!.openDrawer(); scaffoldKey.currentState!.openDrawer();
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
expect(semantics, isNot(includesNodeWith(actions: <SemanticsAction>[SemanticsAction.tap]))); expect(semantics, isNot(includesNodeWith(actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus])));
expect(semantics, isNot(includesNodeWith(label: 'Dismiss'))); expect(semantics, isNot(includesNodeWith(label: 'Dismiss')));
semantics.dispose(); semantics.dispose();

View File

@ -1999,6 +1999,47 @@ void main() {
), ),
); );
}); });
testWidgets('Focus widget gains input focus when it gains accessibility focus', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.rtl,
child: Focus(
focusNode: focusNode,
child: const Text('Test'),
),
),
);
expect(
semantics,
hasSemantics(
TestSemantics.root(
children: <TestSemantics>[
TestSemantics(
id: 1,
flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
actions: <SemanticsAction>[SemanticsAction.focus],
label: 'Test',
textDirection: TextDirection.rtl,
),
],
),
ignoreRect: true,
ignoreTransform: true,
),
);
expect(focusNode.hasFocus, isFalse);
semanticsOwner.performAction(1, SemanticsAction.focus);
await tester.pumpAndSettle();
expect(focusNode.hasFocus, isTrue);
semantics.dispose();
});
}); });
group('ExcludeFocus', () { group('ExcludeFocus', () {

View File

@ -3182,6 +3182,9 @@ void main() {
flags: <SemanticsFlag>[ flags: <SemanticsFlag>[
SemanticsFlag.isFocusable, SemanticsFlag.isFocusable,
], ],
actions: <SemanticsAction>[
SemanticsAction.focus,
],
), ),
], ],
); );

View File

@ -333,7 +333,7 @@ void main() {
); );
expect(semantics, isNot(includesNodeWith( expect(semantics, isNot(includesNodeWith(
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
))); )));
semantics.dispose(); semantics.dispose();

View File

@ -260,7 +260,7 @@ void main() {
SemanticsFlag.isEnabled, SemanticsFlag.isEnabled,
SemanticsFlag.isFocusable SemanticsFlag.isFocusable
], ],
actions: <SemanticsAction>[SemanticsAction.tap], actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
label: 'Button', label: 'Button',
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
), ),

View File

@ -674,6 +674,7 @@ Matcher matchesSemantics({
bool isExpanded = false, bool isExpanded = false,
// Actions // // Actions //
bool hasTapAction = false, bool hasTapAction = false,
bool hasFocusAction = false,
bool hasLongPressAction = false, bool hasLongPressAction = false,
bool hasScrollLeftAction = false, bool hasScrollLeftAction = false,
bool hasScrollRightAction = false, bool hasScrollRightAction = false,
@ -753,6 +754,7 @@ Matcher matchesSemantics({
isExpanded: isExpanded, isExpanded: isExpanded,
// Actions // Actions
hasTapAction: hasTapAction, hasTapAction: hasTapAction,
hasFocusAction: hasFocusAction,
hasLongPressAction: hasLongPressAction, hasLongPressAction: hasLongPressAction,
hasScrollLeftAction: hasScrollLeftAction, hasScrollLeftAction: hasScrollLeftAction,
hasScrollRightAction: hasScrollRightAction, hasScrollRightAction: hasScrollRightAction,
@ -860,6 +862,7 @@ Matcher containsSemantics({
bool? isExpanded, bool? isExpanded,
// Actions // Actions
bool? hasTapAction, bool? hasTapAction,
bool? hasFocusAction,
bool? hasLongPressAction, bool? hasLongPressAction,
bool? hasScrollLeftAction, bool? hasScrollLeftAction,
bool? hasScrollRightAction, bool? hasScrollRightAction,
@ -939,6 +942,7 @@ Matcher containsSemantics({
isExpanded: isExpanded, isExpanded: isExpanded,
// Actions // Actions
hasTapAction: hasTapAction, hasTapAction: hasTapAction,
hasFocusAction: hasFocusAction,
hasLongPressAction: hasLongPressAction, hasLongPressAction: hasLongPressAction,
hasScrollLeftAction: hasScrollLeftAction, hasScrollLeftAction: hasScrollLeftAction,
hasScrollRightAction: hasScrollRightAction, hasScrollRightAction: hasScrollRightAction,
@ -2259,6 +2263,7 @@ class _MatchesSemanticsData extends Matcher {
required bool? isExpanded, required bool? isExpanded,
// Actions // Actions
required bool? hasTapAction, required bool? hasTapAction,
required bool? hasFocusAction,
required bool? hasLongPressAction, required bool? hasLongPressAction,
required bool? hasScrollLeftAction, required bool? hasScrollLeftAction,
required bool? hasScrollRightAction, required bool? hasScrollRightAction,
@ -2317,6 +2322,7 @@ class _MatchesSemanticsData extends Matcher {
}, },
actions = <SemanticsAction, bool>{ actions = <SemanticsAction, bool>{
if (hasTapAction != null) SemanticsAction.tap: hasTapAction, if (hasTapAction != null) SemanticsAction.tap: hasTapAction,
if (hasFocusAction != null) SemanticsAction.focus: hasFocusAction,
if (hasLongPressAction != null) SemanticsAction.longPress: hasLongPressAction, if (hasLongPressAction != null) SemanticsAction.longPress: hasLongPressAction,
if (hasScrollLeftAction != null) SemanticsAction.scrollLeft: hasScrollLeftAction, if (hasScrollLeftAction != null) SemanticsAction.scrollLeft: hasScrollLeftAction,
if (hasScrollRightAction != null) SemanticsAction.scrollRight: hasScrollRightAction, if (hasScrollRightAction != null) SemanticsAction.scrollRight: hasScrollRightAction,
@ -2379,8 +2385,8 @@ class _MatchesSemanticsData extends Matcher {
final Map<SemanticsFlag, bool> flags; final Map<SemanticsFlag, bool> flags;
@override @override
Description describe(Description description) { Description describe(Description description, [String? index]) {
description.add('has semantics'); description.add('${index == null ? '' : 'Child $index '}has semantics');
if (label != null) { if (label != null) {
description.add(' with label: $label'); description.add(' with label: $label');
} }
@ -2479,9 +2485,15 @@ class _MatchesSemanticsData extends Matcher {
description.add(' with custom hints: $hintOverrides'); description.add(' with custom hints: $hintOverrides');
} }
if (children != null) { if (children != null) {
description.add(' with children:\n'); description.add(' with children:\n ');
for (final _MatchesSemanticsData child in children!.cast<_MatchesSemanticsData>()) { final List<_MatchesSemanticsData> childMatches = children!.cast<_MatchesSemanticsData>();
child.describe(description); int childIndex = 1;
for (final _MatchesSemanticsData child in childMatches) {
child.describe(description, index != null ? '$index:$childIndex': '$childIndex');
if (child != childMatches.last) {
description.add('\n ');
}
childIndex += 1;
} }
} }
return description; return description;

View File

@ -746,6 +746,7 @@ void main() {
hasDidGainAccessibilityFocusAction: true, hasDidGainAccessibilityFocusAction: true,
hasDidLoseAccessibilityFocusAction: true, hasDidLoseAccessibilityFocusAction: true,
hasDismissAction: true, hasDismissAction: true,
hasFocusAction: true,
customActions: <CustomSemanticsAction>[action], customActions: <CustomSemanticsAction>[action],
)); ));
}); });
@ -1033,6 +1034,7 @@ void main() {
hasDidGainAccessibilityFocusAction: true, hasDidGainAccessibilityFocusAction: true,
hasDidLoseAccessibilityFocusAction: true, hasDidLoseAccessibilityFocusAction: true,
hasDismissAction: true, hasDismissAction: true,
hasFocusAction: true,
customActions: <CustomSemanticsAction>[action], customActions: <CustomSemanticsAction>[action],
), ),
); );
@ -1125,6 +1127,7 @@ void main() {
hasDidGainAccessibilityFocusAction: false, hasDidGainAccessibilityFocusAction: false,
hasDidLoseAccessibilityFocusAction: false, hasDidLoseAccessibilityFocusAction: false,
hasDismissAction: false, hasDismissAction: false,
hasFocusAction: false,
), ),
); );
}); });