Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e7dfd10
Show debug-mode message for widget rebuilds in profile mode
crackedhandle Apr 3, 2026
e1c52f3
Move RebuildStatsView tests to performance_screen_test
crackedhandle Apr 8, 2026
23d9d05
Fix formatting and add release note
crackedhandle Apr 14, 2026
a9febdd
Resolve merge conflict in release notes
crackedhandle Apr 14, 2026
0879481
style: format performance_screen_test
crackedhandle Apr 14, 2026
808bf1a
fix: restore removed tests and apply only required changes
crackedhandle Apr 14, 2026
d6ff5d2
style: format file and add required comments
crackedhandle Apr 14, 2026
2b176c3
fix: properly remove build artifacts
crackedhandle Apr 14, 2026
05507a2
Remove unnecessary imports
crackedhandle Apr 16, 2026
560df3a
Merge branch 'master' into fix-widget-rebuilds-profile-mode
crackedhandle May 3, 2026
de6949d
Address review feedback: use CenteredMessage, revert unrelated change…
crackedhandle Aug 4, 2026
a74899a
Merge branch 'fix-widget-rebuilds-profile-mode' of https://github.com/…
crackedhandle Aug 4, 2026
575b372
Merge remote-tracking branch 'upstream/master' into fix-widget-rebuil…
crackedhandle Aug 4, 2026
b1455f8
Merge remote-tracking branch 'upstream/master' into fix-widget-rebuil…
crackedhandle Aug 12, 2026
a3aa8da
Merge remote-tracking branch 'upstream/master' into fix-widget-rebuil…
crackedhandle Aug 13, 2026
eea3ca4
Merge branch 'master' into fix-widget-rebuilds-profile-mode
srawlins Sep 23, 2026
5c19593
Update performance_screen_test.dart
srawlins Sep 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ import '../../../../shared/ui/common_widgets.dart';
import '../flutter_frames/flutter_frame_model.dart';
import 'rebuild_stats_model.dart';

@visibleForTesting
const debugModeOnlyMessage =
'Rebuild information is not available for this frame.\n'
'Widget rebuild counts are only available when running '
'an app in debug mode.';

class RebuildStatsView extends StatefulWidget {
const RebuildStatsView({
super.key,
Expand Down Expand Up @@ -92,6 +98,12 @@ class _RebuildStatsViewState extends State<RebuildStatsView>

@override
Widget build(BuildContext context) {
final isProfileBuild =
serviceConnection.serviceManager.connectedApp?.isProfileBuildNow ??
false;
if (isProfileBuild) {
return const CenteredMessage(message: debugModeOnlyMessage);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expand Down
23 changes: 14 additions & 9 deletions packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ To learn more about DevTools, check out the
* Fixed a bug where the Flutter frames chart could appear frozen after
switching away from the Performance screen and coming back.
[#9960](https://github.com/flutter/devtools/pull/9960)
* Added a message in the Performance panel when widget rebuild tracking is
unavailable because the app is running in profile mode.
[#9755](https://github.com/flutter/devtools/pull/9755)

## CPU profiler updates

Expand All @@ -40,15 +43,16 @@ To learn more about DevTools, check out the

## Memory updates

* Added the ability to pin classes to the top of the Profile Memory table. [#8898](https://github.com/flutter/devtools/issues/8898)
* Added the ability to pin classes to the top of the Profile Memory table.
[#8898](https://github.com/flutter/devtools/issues/8898)

## Debugger updates

* Prevent values from being garbage-collected, while being evaluated.
* Prevented values from being garbage-collected, while being evaluated.
[#9885](https://github.com/flutter/devtools/pull/9885)
* Update to latest version of the Dart syntax highlighting grammar
[#9920](https://github.com/flutter/devtools/pull/9920).
* Fix a bug in the TextMate grammar parser that could result in code after
* Fixed a bug in the TextMate grammar parser that could result in code after
comments being classified as comments.
[#9921](https://github.com/flutter/devtools/pull/9921).
* Fixed an overflow in the debugging controls when the Debugger screen is
Expand All @@ -70,7 +74,7 @@ To learn more about DevTools, check out the

## Logging updates

* Correct time units and cumulative nature of GC events.
* Corrected time units and cumulative nature of GC events.
[#9890](https://github.com/flutter/devtools/pull/9890)
* Fixed a bug where long `dart:developer` log messages lost their structured
Details view. -
Expand All @@ -83,7 +87,7 @@ TODO: Remove this section if there are not any updates.
## Deep links tool updates

* Added a "Watch tutorial" link to the status line that points to the
[deep links video tutorial](https://youtu.be/d7sZL6h1Elw).
[deep links video tutorial](https://youtu.be/d7sZL6hIElw).
[#9925](https://github.com/flutter/devtools/pull/9925)

## VS Code sidebar updates
Expand All @@ -92,12 +96,13 @@ TODO: Remove this section if there are not any updates.

## DevTools extension updates

* Hide the DevTools extensions menu button in single-screen embedded mode (`EmbedMode.embedOne`) on standard screens.
* Hide the DevTools extensions menu button in single-screen embedded mode
(`EmbedMode.embedOne`) on standard screens.
[#8507](https://github.com/flutter/devtools/issues/8507)
* Added iframe sandboxing for embedded DevTools extensions to enforce origin
isolation. [#9967](https://github.com/flutter/devtools/pull/9967)
* Improved DevTools extension isolation by tracking the providing package name for
enablement, deduplication, and asset loading.
* Improved DevTools extension isolation by tracking the providing package
name for enablement, deduplication, and asset loading.
[#9981](https://github.com/flutter/devtools/pull/9981)

## Advanced developer mode updates
Expand All @@ -107,4 +112,4 @@ TODO: Remove this section if there are not any updates.
## Full commit history

To find a complete list of changes in this release, check out the
[DevTools git log](https://github.com/flutter/devtools/tree/v2.61.0).
[DevTools git log](https://github.com/flutter/devtools/tree/v2.61.0).
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'dart:async';

import 'package:devtools_app/devtools_app.dart';
import 'package:devtools_app/src/screens/performance/panes/controls/performance_controls.dart';
import 'package:devtools_app/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart';
import 'package:devtools_app/src/screens/performance/panes/timeline_events/timeline_events_view.dart';
import 'package:devtools_app/src/screens/performance/tabbed_performance_view.dart';
import 'package:devtools_app/src/shared/feature_flags.dart';
Expand Down Expand Up @@ -218,7 +219,6 @@ void main() {
await tester.runAsync(() async {
await pumpPerformanceScreen(tester, runAsync: true);
await tester.pumpAndSettle();

final chartButtonFinder = find.byType(VisibilityButton);
expect(chartButtonFinder, findsOneWidget);

Expand All @@ -231,7 +231,6 @@ void main() {

await tester.tap(chartButtonFinder);
await tester.pumpAndSettle();

// The flutter frames chart should no longer be visible.
expect(find.byType(FramesChartControls), findsNothing);
expect(
Expand Down Expand Up @@ -395,6 +394,64 @@ void main() {
},
);
});

group('RebuildStatsView', () {
late FakeServiceConnectionManager fakeServiceConnection;
late RebuildCountModel model;
late ValueNotifier<FlutterFrame?> selectedFrame;

setUp(() {
fakeServiceConnection = FakeServiceConnectionManager();
mockConnectedApp(fakeServiceConnection.serviceManager.connectedApp!);
setGlobal(ServiceConnectionManager, fakeServiceConnection);
setGlobal(IdeTheme, IdeTheme());
setGlobal(NotificationService, NotificationService());
setGlobal(BannerMessagesController, BannerMessagesController());
setGlobal(PreferencesController, PreferencesController());
setGlobal(OfflineDataController, OfflineDataController());
model = RebuildCountModel();
selectedFrame = ValueNotifier<FlutterFrame?>(null);
});

testWidgets('shows message when running in profile mode', (
WidgetTester tester,
) async {
mockConnectedApp(
fakeServiceConnection.serviceManager.connectedApp!,
isProfileBuild: true,
);

await tester.pumpWidget(
wrapWithControllers(
RebuildStatsView(model: model, selectedFrame: selectedFrame),
),
);
await tester.pump();

expect(
find.textContaining('Widget rebuild counts are only available'),
findsOneWidget,
);
});

testWidgets('shows normal UI when running in debug mode', (
WidgetTester tester,
) async {
mockConnectedApp(fakeServiceConnection.serviceManager.connectedApp!);

await tester.pumpWidget(
wrapWithControllers(
RebuildStatsView(model: model, selectedFrame: selectedFrame),
),
);
await tester.pump();

expect(
find.textContaining('Widget rebuild counts are only available'),
findsNothing,
);
});
});
});
}

Expand Down
Loading