Skip to content

Commit 9fb6a25

Browse files
Add debug disable layer toggles to the Performance page (#3441)
1 parent d4214f1 commit 9fb6a25

15 files changed

+357
-83
lines changed

packages/devtools_app/lib/src/analytics/constants.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ const refreshTimelineEvents = 'refreshTimelineEvents';
5555
const timelineFlameChartHelp = 'timelineFlameChartHelp';
5656
const selectFlutterFrame = 'selectFlutterFrame';
5757
const traceEventProcessingTime = 'traceEventProcessingTime';
58+
const disableClipLayersOption = 'disableClipLayers';
59+
const disableOpacityLayersOption = 'disableOpacityLayers';
60+
const disablePhysicalShapeLayersOption = 'disablePhysicalShapeLayers';
5861

5962
// CPU profiler UX actions:
6063
const profileGranularityPrefix = 'profileGranularity';

packages/devtools_app/lib/src/common_widgets.dart

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ class DevToolsTooltip extends StatelessWidget {
596596
@required this.child,
597597
this.waitDuration = tooltipWait,
598598
this.preferBelow = false,
599-
this.padding,
599+
this.padding = const EdgeInsets.all(defaultSpacing),
600600
this.decoration,
601601
this.textStyle,
602602
}) : super(key: key);
@@ -1404,12 +1404,20 @@ class NotifierCheckbox extends StatelessWidget {
14041404
Key key,
14051405
@required this.notifier,
14061406
this.onChanged,
1407+
this.enabled = true,
14071408
}) : super(key: key);
14081409

1410+
/// The notifier this [NotifierCheckbox] is responsible for listening to and
1411+
/// updating.
14091412
final ValueNotifier<bool> notifier;
14101413

1414+
/// The callback to be called on change in addition to the notifier changes
1415+
/// handled by this class.
14111416
final void Function(bool newValue) onChanged;
14121417

1418+
/// Whether this checkbox should be enabled for interaction.
1419+
final bool enabled;
1420+
14131421
void _updateValue(bool value) {
14141422
if (notifier.value != value) {
14151423
notifier.value = value;
@@ -1426,7 +1434,7 @@ class NotifierCheckbox extends StatelessWidget {
14261434
builder: (context, value, _) {
14271435
return Checkbox(
14281436
value: value,
1429-
onChanged: _updateValue,
1437+
onChanged: enabled ? _updateValue : null,
14301438
);
14311439
},
14321440
);
@@ -1441,6 +1449,7 @@ class CheckboxSetting extends StatelessWidget {
14411449
this.description,
14421450
this.tooltip,
14431451
this.onChanged,
1452+
this.enabled = true,
14441453
}) : super(key: key);
14451454

14461455
final ValueListenable<bool> notifier;
@@ -1453,6 +1462,9 @@ class CheckboxSetting extends StatelessWidget {
14531462

14541463
final void Function(bool newValue) onChanged;
14551464

1465+
/// Whether this checkbox setting should be enabled for interaction.
1466+
final bool enabled;
1467+
14561468
@override
14571469
Widget build(BuildContext context) {
14581470
final theme = Theme.of(context);
@@ -1461,7 +1473,7 @@ class CheckboxSetting extends StatelessWidget {
14611473
overflow: TextOverflow.visible,
14621474
text: TextSpan(
14631475
text: title,
1464-
style: theme.regularTextStyle,
1476+
style: enabled ? theme.regularTextStyle : theme.subtleTextStyle,
14651477
),
14661478
);
14671479

@@ -1488,6 +1500,7 @@ class CheckboxSetting extends StatelessWidget {
14881500
NotifierCheckbox(
14891501
notifier: notifier,
14901502
onChanged: onChanged,
1503+
enabled: enabled,
14911504
),
14921505
Flexible(
14931506
child: textContent,

packages/devtools_app/lib/src/error_badge_manager.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ class ErrorBadgeManager extends DisposableController
3636
// Ensure structured errors are enabled.
3737
serviceManager.serviceExtensionManager.setServiceExtensionState(
3838
extensions.structuredErrors.extension,
39-
true,
40-
true,
39+
enabled: true,
40+
value: true,
4141
);
4242

4343
// Log Flutter extension events.

packages/devtools_app/lib/src/inspector/inspector_controller.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ class InspectorController extends DisposableController
127127
if (_supportsToggleSelectWidgetMode.value) {
128128
serviceManager.serviceExtensionManager.setServiceExtensionState(
129129
extensions.enableOnDeviceInspector.extension,
130-
true,
131-
true,
130+
enabled: true,
131+
value: true,
132132
);
133133
}
134134
});

packages/devtools_app/lib/src/performance/performance_screen.dart

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,8 @@ class _SecondaryControls extends StatelessWidget {
313313
profileGranularityFlagNotifier:
314314
controller.cpuProfilerController.profileGranularityFlagNotifier,
315315
),
316-
const SizedBox(width: defaultSpacing),
317-
if (serviceManager.connectedApp.isFlutterAppNow)
316+
const SizedBox(width: denseSpacing),
317+
if (serviceManager.connectedApp.isFlutterAppNow) ...[
318318
ServiceExtensionButtonGroup(
319319
minScreenWidthForTextBeforeScaling:
320320
_secondaryControlsMinIncludeTextWidth,
@@ -326,6 +326,15 @@ class _SecondaryControls extends StatelessWidget {
326326
//trackRebuildWidgets,
327327
],
328328
),
329+
const SizedBox(width: denseSpacing),
330+
IconLabelButton(
331+
icon: Icons.build,
332+
label: 'More debugging options',
333+
tooltip:
334+
'Opens a list of options you can use to help debug performance',
335+
onPressed: () => _openDebuggingOptionsDialog(context),
336+
),
337+
],
329338
const SizedBox(width: defaultSpacing),
330339
ExportButton(
331340
onPressed: () => _exportPerformanceData(context),
@@ -351,6 +360,13 @@ class _SecondaryControls extends StatelessWidget {
351360
Notifications.of(context).push(successfulExportMessage(exportedFile));
352361
}
353362

363+
void _openDebuggingOptionsDialog(BuildContext context) {
364+
showDialog(
365+
context: context,
366+
builder: (context) => DebuggingOptionsDialog(),
367+
);
368+
}
369+
354370
void _openSettingsDialog(BuildContext context) {
355371
showDialog(
356372
context: context,
@@ -359,6 +375,39 @@ class _SecondaryControls extends StatelessWidget {
359375
}
360376
}
361377

378+
class DebuggingOptionsDialog extends StatelessWidget {
379+
@override
380+
Widget build(BuildContext context) {
381+
final theme = Theme.of(context);
382+
return DevToolsDialog(
383+
title: dialogTitleText(theme, 'Debugging Options'),
384+
includeDivider: false,
385+
content: Container(
386+
width: defaultDialogWidth,
387+
child: Column(
388+
mainAxisSize: MainAxisSize.min,
389+
crossAxisAlignment: CrossAxisAlignment.start,
390+
children: [
391+
Text(
392+
'When toggling on/off a rendering layer, you will need '
393+
'to reproduce activity in your app to see the effects of the '
394+
'debugging option.',
395+
style: theme.subtleTextStyle,
396+
),
397+
const SizedBox(height: defaultSpacing),
398+
ServiceExtensionCheckbox(service: disableClipLayers),
399+
ServiceExtensionCheckbox(service: disableOpacityLayers),
400+
ServiceExtensionCheckbox(service: disablePhysicalShapeLayers),
401+
],
402+
),
403+
),
404+
actions: [
405+
DialogCloseButton(),
406+
],
407+
);
408+
}
409+
}
410+
362411
class PerformanceSettingsDialog extends StatelessWidget {
363412
const PerformanceSettingsDialog(this.controller);
364413

0 commit comments

Comments
 (0)