Make FocusManager configurable in BuildOwner (#71872)

This commit is contained in:
Todd Volkert 2020-12-08 12:42:39 -08:00 committed by GitHub
parent 7324ade361
commit 7ec3f6bdf9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 2 deletions

View file

@ -71,6 +71,22 @@ class PointerRouter {
_globalRoutes.remove(route);
}
/// The number of global routes that have been registered.
///
/// This is valid in debug builds only. In release builds, this will throw an
/// [UnsupportedError].
int get debugGlobalRouteCount {
int? count;
assert(() {
count = _globalRoutes.length;
return true;
}());
if (count != null) {
return count!;
}
throw UnsupportedError('debugGlobalRouteCount is not supported in release builds');
}
void _dispatch(PointerEvent event, PointerRoute route, Matrix4? transform) {
try {
event = event.transformed(transform);

View file

@ -2554,7 +2554,8 @@ abstract class BuildContext {
/// widget tree.
class BuildOwner {
/// Creates an object that manages widgets.
BuildOwner({ this.onBuildScheduled });
BuildOwner({ this.onBuildScheduled, FocusManager? focusManager }) :
focusManager = focusManager ?? FocusManager();
/// Called on each build pass when the first buildable element is marked
/// dirty.
@ -2585,7 +2586,7 @@ class BuildOwner {
/// the [FocusScopeNode] for a given [BuildContext].
///
/// See [FocusManager] for more details.
FocusManager focusManager = FocusManager();
FocusManager focusManager;
/// Adds an element to the dirty elements list so that it will be rebuilt
/// when [WidgetsBinding.drawFrame] calls [buildScope].

View file

@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
@ -1483,6 +1485,27 @@ void main() {
)
);
});
testWidgets('Can create BuildOwner that does not interfere with pointer router or raw key event handler', (WidgetTester tester) async {
final int pointerRouterCount = GestureBinding.instance!.pointerRouter.debugGlobalRouteCount;
final RawKeyEventHandler? rawKeyEventHandler = RawKeyboard.instance.keyEventHandler;
expect(rawKeyEventHandler, isNotNull);
BuildOwner(focusManager: _FakeFocusManager());
expect(GestureBinding.instance!.pointerRouter.debugGlobalRouteCount, pointerRouterCount);
expect(RawKeyboard.instance.keyEventHandler, same(rawKeyEventHandler));
});
}
class _FakeFocusManager implements FocusManager {
@override
dynamic noSuchMethod(Invocation invocation) {
return super.noSuchMethod(invocation);
}
@override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return '_FakeFocusManager';
}
}
class _WidgetWithNoVisitChildren extends StatelessWidget {