@@ -14,6 +14,7 @@ class WidgetFilter {
14
14
late WidgetFilterColorScheme _scheme;
15
15
late double _pixelRatio;
16
16
late Rect _bounds;
17
+ late List <Element > _visitList;
17
18
final _warnedWidgets = < int > {};
18
19
19
20
/// Used to test _obscureElementOrParent
@@ -34,11 +35,24 @@ class WidgetFilter {
34
35
assert (colorScheme.background.isOpaque);
35
36
assert (colorScheme.defaultMask.isOpaque);
36
37
assert (colorScheme.defaultTextMask.isOpaque);
38
+
39
+ // clear the output list
37
40
items.clear ();
38
- if (context is Element ) {
39
- _process (context);
40
- } else {
41
- context.visitChildElements (_process);
41
+
42
+ // Reset the list of elements we're going to process.
43
+ // Then do a breadth-first tree traversal on all the widgets.
44
+ // TODO benchmark performance compared to to DoubleLinkedQueue.
45
+ _visitList = [];
46
+ context.visitChildElements (_visitList.add);
47
+ while (_visitList.isNotEmpty) {
48
+ // Get a handle on the items we're supposed to process in this step.
49
+ // Then _visitList (which is updated in _process()) with a new instance.
50
+ final currentList = _visitList;
51
+ _visitList = [];
52
+
53
+ for (final element in currentList) {
54
+ _process (element);
55
+ }
42
56
}
43
57
}
44
58
@@ -66,7 +80,7 @@ class WidgetFilter {
66
80
break ;
67
81
case SentryMaskingDecision .continueProcessing:
68
82
// If this element should not be obscured, visit and check its children.
69
- element.visitChildElements (_process );
83
+ element.visitChildElements (_visitList.add );
70
84
break ;
71
85
}
72
86
}
0 commit comments