Unverified Commit 177dbc94 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Make _kDebugFocus into a global that can be set (debugFocusChanges) (#85343)

This removes the _kDebugFocus private global and replaces it with a global debugFocusChanges
parent ce057d4d
......@@ -15,12 +15,15 @@ import 'focus_scope.dart';
import 'focus_traversal.dart';
import 'framework.dart';
// Used for debugging focus code. Set to true to see highly verbose debug output
// when focus changes occur.
const bool _kDebugFocus = false;
/// Setting to true will cause extensive logging to occur when focus changes occur.
///
/// Can be used to debug focus issues: each time the focus changes, the focus
/// tree will be printed and requests for focus and other focus operations will
/// be logged.
bool debugFocusChanges = false;
bool _focusDebug(String message, [Iterable<String>? details]) {
if (_kDebugFocus) {
if (debugFocusChanges) {
debugPrint('FOCUS: $message');
if (details != null && details.isNotEmpty) {
for (final String detail in details) {
......@@ -28,6 +31,7 @@ bool _focusDebug(String message, [Iterable<String>? details]) {
}
}
}
// Return true so that it can be easily used inside of an assert.
return true;
}
......@@ -1789,7 +1793,7 @@ class FocusManager with DiagnosticableTreeMixin, ChangeNotifier {
notifyListeners();
}
assert(() {
if (_kDebugFocus) {
if (debugFocusChanges) {
debugDumpFocusTree();
}
return true;
......
......@@ -1351,4 +1351,50 @@ void main() {
tester.binding.focusManager.removeListener(handleFocusChange);
});
testWidgets('debugFocusChanges causes logging of focus changes', (WidgetTester tester) async {
final bool oldDebugFocusChanges = debugFocusChanges;
final DebugPrintCallback oldDebugPrint = debugPrint;
final StringBuffer messages = StringBuffer();
debugPrint = (String? message, {int? wrapWidth}) {
messages.writeln(message ?? '');
};
debugFocusChanges = true;
try {
final BuildContext context = await setupWidget(tester);
final FocusScopeNode parent1 = FocusScopeNode(debugLabel: 'parent1');
final FocusAttachment parent1Attachment = parent1.attach(context);
final FocusNode child1 = FocusNode(debugLabel: 'child1');
final FocusAttachment child1Attachment = child1.attach(context);
parent1Attachment.reparent(parent: tester.binding.focusManager.rootScope);
child1Attachment.reparent(parent: parent1);
int notifyCount = 0;
void handleFocusChange() {
notifyCount++;
}
tester.binding.focusManager.addListener(handleFocusChange);
parent1.requestFocus();
expect(notifyCount, equals(0));
await tester.pump();
expect(notifyCount, equals(1));
notifyCount = 0;
child1.requestFocus();
await tester.pump();
expect(notifyCount, equals(1));
notifyCount = 0;
tester.binding.focusManager.removeListener(handleFocusChange);
} finally {
debugFocusChanges = oldDebugFocusChanges;
debugPrint = oldDebugPrint;
}
final String messagesStr = messages.toString();
expect(messagesStr.split('\n').length, equals(58));
expect(messagesStr, contains(RegExp(r' └─Child 1: FocusScopeNode#[a-f0-9]{5}\(parent1 \[PRIMARY FOCUS\]\)')));
expect(messagesStr, contains('FOCUS: Notifying 2 dirty nodes'));
expect(messagesStr, contains(RegExp(r'FOCUS: Scheduling update, current focus is null, next focus will be FocusScopeNode#.*parent1')));
});
}
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