Skip to content

Commit 56352b6

Browse files
committed
add widgetLocationIdMap extension.
1 parent 3a3a0db commit 56352b6

2 files changed

Lines changed: 69 additions & 7 deletions

File tree

packages/flutter/lib/src/widgets/service_extensions.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,22 @@ enum WidgetInspectorServiceExtensions {
135135
/// extension is registered.
136136
trackRebuildDirtyWidgets,
137137

138+
/// Name of service extension that, when called, returns the mapping of
139+
/// widget locations to ids.
140+
///
141+
/// This service extension is only supported if
142+
/// [WidgetInspectorService._widgetCreationTracked] is true.
143+
///
144+
/// See also:
145+
///
146+
/// * [trackRebuildDirtyWidgets], which toggles dispatching events that use
147+
/// these ids to efficiently indicate the locations of widgets.
148+
/// * [WidgetInspectorService.initServiceExtensions], where the service
149+
/// extension is registered.
150+
widgetLocationIdMap,
151+
138152
/// Name of service extension that, when called, determines whether
153+
/// [WidgetInspectorService._trackRepaintWidgets], which determines whether
139154
/// a callback is invoked for every [RenderObject] painted each frame.
140155
///
141156
/// See also:

packages/flutter/lib/src/widgets/widget_inspector.dart

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,13 @@ mixin WidgetInspectorService {
10501050
},
10511051
);
10521052

1053+
_registerSignalServiceExtension(
1054+
name: WidgetInspectorServiceExtensions.widgetLocationIdMap.name,
1055+
callback: () {
1056+
return _locationIdMapToJson();
1057+
},
1058+
);
1059+
10531060
_registerBoolServiceExtension(
10541061
name: WidgetInspectorServiceExtensions.trackRepaintWidgets.name,
10551062
getter: () async => _trackRepaintWidgets,
@@ -2259,9 +2266,11 @@ mixin WidgetInspectorService {
22592266
bool? _widgetCreationTracked;
22602267

22612268
late Duration _frameStart;
2269+
late int _frameNumber;
22622270

22632271
void _onFrameStart(Duration timeStamp) {
22642272
_frameStart = timeStamp;
2273+
_frameNumber = PlatformDispatcher.instance.frameData.frameNumber;
22652274
SchedulerBinding.instance.addPostFrameCallback(_onFrameEnd);
22662275
}
22672276

@@ -2275,7 +2284,13 @@ mixin WidgetInspectorService {
22752284
}
22762285

22772286
void _postStatsEvent(String eventName, _ElementLocationStatsTracker stats) {
2278-
postEvent(eventName, stats.exportToJson(_frameStart));
2287+
postEvent(
2288+
eventName,
2289+
stats.exportToJson(
2290+
_frameStart,
2291+
frameNumber: _frameNumber,
2292+
),
2293+
);
22792294
}
22802295

22812296
/// All events dispatched by a [WidgetInspectorService] use this method
@@ -2466,7 +2481,7 @@ class _ElementLocationStatsTracker {
24662481

24672482
/// Exports the current counts and then resets the stats to prepare to track
24682483
/// the next frame of data.
2469-
Map<String, dynamic> exportToJson(Duration startTime) {
2484+
Map<String, dynamic> exportToJson(Duration startTime, {required int frameNumber}) {
24702485
final List<int> events = List<int>.filled(active.length * 2, 0);
24712486
int j = 0;
24722487
for (final _LocationCount stat in active) {
@@ -2476,6 +2491,7 @@ class _ElementLocationStatsTracker {
24762491

24772492
final Map<String, dynamic> json = <String, dynamic>{
24782493
'startTime': startTime.inMicroseconds,
2494+
'frameNumber': frameNumber,
24792495
'events': events,
24802496
};
24812497

@@ -3120,11 +3136,21 @@ class _InspectorOverlayLayer extends Layer {
31203136
final Rect targetRect = MatrixUtils.transformRect(
31213137
state.selected.transform, state.selected.rect,
31223138
);
3123-
final Offset target = Offset(targetRect.left, targetRect.center.dy);
3124-
const double offsetFromWidget = 9.0;
3125-
final double verticalOffset = (targetRect.height) / 2 + offsetFromWidget;
3126-
3127-
_paintDescription(canvas, state.tooltip, state.textDirection, target, verticalOffset, size, targetRect);
3139+
if (!targetRect.hasNaN) {
3140+
final Offset target = Offset(targetRect.left, targetRect.center.dy);
3141+
const double offsetFromWidget = 9.0;
3142+
final double verticalOffset = (targetRect.height) / 2 + offsetFromWidget;
3143+
3144+
_paintDescription(
3145+
canvas,
3146+
state.tooltip,
3147+
state.textDirection,
3148+
target,
3149+
verticalOffset,
3150+
size,
3151+
targetRect,
3152+
);
3153+
}
31283154

31293155
// TODO(jacobr): provide an option to perform a debug paint of just the
31303156
// selected widget.
@@ -3518,6 +3544,27 @@ int _toLocationId(_Location location) {
35183544
return id;
35193545
}
35203546

3547+
Map<String, dynamic> _locationIdMapToJson() {
3548+
final Map<String, Map<String, List<Object?>>> fileLocationsMap = <String, Map<String, List<Object?>>>{};
3549+
for (final MapEntry<_Location, int> entry in _locationToId.entries) {
3550+
final _Location location = entry.key;
3551+
final Map<String, List<Object?>> locations = fileLocationsMap.putIfAbsent(
3552+
location.file, () => <String, List<Object?>>{
3553+
'ids': <int>[],
3554+
'lines': <int>[],
3555+
'columns': <int>[],
3556+
'names': <String?>[],
3557+
},
3558+
);
3559+
3560+
locations['ids']!.add(entry.value);
3561+
locations['lines']!.add(location.line);
3562+
locations['columns']!.add(location.column);
3563+
locations['names']!.add(location.name);
3564+
}
3565+
return fileLocationsMap;
3566+
}
3567+
35213568
/// A delegate that configures how a hierarchy of [DiagnosticsNode]s are
35223569
/// serialized by the Flutter Inspector.
35233570
@visibleForTesting

0 commit comments

Comments
 (0)