diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart index 5e8f9e92d4..6e1bae2f9c 100644 --- a/packages/flutter/lib/src/widgets/widget_inspector.dart +++ b/packages/flutter/lib/src/widgets/widget_inspector.dart @@ -2958,6 +2958,9 @@ class _WidgetInspectorState extends State final Rect bounds = (Offset.zero & (view.physicalSize / view.devicePixelRatio)).deflate(_kOffScreenMargin); if (!bounds.contains(_lastPointerLocation!)) { selection.clear(); + } else { + // Otherwise notify DevTools of the current selection. + WidgetInspectorService.instance._sendInspectEvent(selection.current); } } diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index 71a15cbdb7..d1f2978181 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -414,6 +414,30 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ); } + Future panAndVerifyWidgetSelection({ + required Finder startAt, + required Finder endAt, + required bool isSelected, + required GlobalKey widgetKey, + }) async { + // Pan to the widget. + final ui.Offset start = tester.getCenter(startAt); + final ui.Offset end = tester.getCenter(endAt); + await tester.dragFrom( + tester.getCenter(startAt), + Offset(end.dx - start.dx, end.dy - start.dy), + ); + await tester.pump(); + + // Verify the pan end was intercepted by the Widget Inspector. + final RenderObject renderObject = + find.byKey(widgetKey).evaluate().first.renderObject!; + expect( + WidgetInspectorService.instance.selection.candidates, + contains(renderObject), + ); + } + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -475,6 +499,37 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ); expect(log, equals([])); + + // Now pan to the top button and verify it's selected in the Inspector. + await panAndVerifyWidgetSelection( + startAt: find.text('BOTTOM'), + endAt: find.text('TOP'), + isSelected: true, + widgetKey: topButtonKey, + ); + expect( + paragraphText( + WidgetInspectorService.instance.selection.current! as RenderParagraph, + ), + equals('TOP'), + ); + expect(log, equals([])); + + // Now pan to the bottom button and verify it's selected in the Inspector. + await panAndVerifyWidgetSelection( + startAt: find.text('TOP'), + endAt: find.text('BOTTOM'), + isSelected: true, + widgetKey: bottomButtonKey, + ); + expect( + paragraphText( + WidgetInspectorService.instance.selection.current! as RenderParagraph, + ), + equals('BOTTOM'), + ); + expect(log, equals([])); + // Now exit selection mode by tapping the Exit Selection Mode button. await tester.tap(find.byKey(exitWidgetSelectionButtonKey)); await tester.pump();