mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
[flutter] tab navigation does not notify the focus scope node (#86141)
This commit is contained in:
parent
731360fd84
commit
6d8c850ee7
|
@ -2011,11 +2011,8 @@ class _FocusTrap extends SingleChildRenderObjectWidget {
|
|||
}
|
||||
|
||||
class _RenderFocusTrap extends RenderProxyBoxWithHitTestBehavior {
|
||||
_RenderFocusTrap(this._focusScopeNode) {
|
||||
focusScopeNode.addListener(_currentFocusListener);
|
||||
}
|
||||
_RenderFocusTrap(this._focusScopeNode);
|
||||
|
||||
FocusNode? currentFocus;
|
||||
Rect? currentFocusRect;
|
||||
Expando<BoxHitTestResult> cachedResults = Expando<BoxHitTestResult>();
|
||||
|
||||
|
@ -2024,13 +2021,7 @@ class _RenderFocusTrap extends RenderProxyBoxWithHitTestBehavior {
|
|||
set focusScopeNode(FocusScopeNode value) {
|
||||
if (focusScopeNode == value)
|
||||
return;
|
||||
focusScopeNode.removeListener(_currentFocusListener);
|
||||
_focusScopeNode = value;
|
||||
focusScopeNode.addListener(_currentFocusListener);
|
||||
}
|
||||
|
||||
void _currentFocusListener() {
|
||||
currentFocus = focusScopeNode.focusedChild;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -2069,11 +2060,11 @@ class _RenderFocusTrap extends RenderProxyBoxWithHitTestBehavior {
|
|||
|| event.buttons != kPrimaryButton
|
||||
|| event.kind != PointerDeviceKind.mouse
|
||||
|| _shouldIgnoreEvents
|
||||
|| currentFocus == null) {
|
||||
|| _focusScopeNode.focusedChild == null) {
|
||||
return;
|
||||
}
|
||||
final BoxHitTestResult? result = cachedResults[entry];
|
||||
final FocusNode? focusNode = currentFocus;
|
||||
final FocusNode? focusNode = _focusScopeNode.focusedChild;
|
||||
if (focusNode == null || result == null)
|
||||
return;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
|
@ -429,4 +430,62 @@ void main() {
|
|||
expect(focusNodeA.hasFocus, false);
|
||||
expect(focusNodeB.hasFocus, true);
|
||||
}, variant: TargetPlatformVariant.desktop());
|
||||
|
||||
testWidgets('A Focused text-field will lose focus when clicking outside of its hitbox with a mouse on desktop after tab navigation', (WidgetTester tester) async {
|
||||
final FocusNode focusNodeA = FocusNode();
|
||||
final FocusNode focusNodeB = FocusNode();
|
||||
final Key key = UniqueKey();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
const TextField(),
|
||||
const TextField(),
|
||||
TextField(
|
||||
focusNode: focusNodeA,
|
||||
),
|
||||
Container(
|
||||
key: key,
|
||||
height: 200,
|
||||
),
|
||||
TextField(
|
||||
focusNode: focusNodeB,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
// Tab over to the 3rd text field.
|
||||
for (int i = 0; i < 3; i += 1) {
|
||||
await tester.sendKeyDownEvent(LogicalKeyboardKey.tab);
|
||||
await tester.sendKeyUpEvent(LogicalKeyboardKey.tab);
|
||||
}
|
||||
|
||||
expect(focusNodeA.hasFocus, true);
|
||||
expect(focusNodeB.hasFocus, false);
|
||||
|
||||
// Click on the container to not hit either text field.
|
||||
final TestGesture down2 = await tester.startGesture(tester.getCenter(find.byKey(key)), kind: PointerDeviceKind.mouse);
|
||||
await tester.pump();
|
||||
await tester.pumpAndSettle();
|
||||
await down2.up();
|
||||
await down2.removePointer();
|
||||
|
||||
expect(focusNodeA.hasFocus, false);
|
||||
expect(focusNodeB.hasFocus, false);
|
||||
|
||||
// Second text field can still gain focus.
|
||||
|
||||
final TestGesture down3 = await tester.startGesture(tester.getCenter(find.byType(TextField).last), kind: PointerDeviceKind.mouse);
|
||||
await tester.pump();
|
||||
await tester.pumpAndSettle();
|
||||
await down3.up();
|
||||
await down3.removePointer();
|
||||
|
||||
expect(focusNodeA.hasFocus, false);
|
||||
expect(focusNodeB.hasFocus, true);
|
||||
}, variant: TargetPlatformVariant.desktop());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue