wrap static method
- required Widget child,
- GlassThemeData? theme,
- bool respectSystemAccessibility = true,
- bool adaptiveQuality = false,
- GlassAdaptiveScopeConfig? adaptiveConfig,
- Brightness? brightnessResolver()?,
Wraps child in the Liquid Glass infrastructure scopes and applies all
behavioral configuration.
Responsibility: widget-tree composition and runtime behavior. All configuration that affects how glass widgets behave lives here — explicit, visible, and co-located with the widget tree entry point.
Optional — provides app-wide theming and adaptive quality.
GlassBackdropScope is no longer needed (each glass layer manages its own
backdrop); wrap() is only required if you use theme: or
adaptiveQuality:.
// Zero-config (most apps):
runApp(LiquidGlassWidgets.wrap(const MyApp()));
// Recommended for Android / broad device support:
runApp(LiquidGlassWidgets.wrap(
child: const MyApp(),
adaptiveQuality: true,
theme: GlassThemeData(...),
));
// Game / experience — bypass accessibility, conservative quality start:
runApp(LiquidGlassWidgets.wrap(
child: const MyApp(),
respectSystemAccessibility: false,
adaptiveQuality: true,
adaptiveConfig: GlassAdaptiveScopeConfig(
initialQuality: GlassQuality.standard,
allowStepUp: true,
),
));
Parameters
respectSystemAccessibility (default true)
When true, system Reduce Motion and Reduce Transparency flags are
respected automatically — no extra setup required. All glass widgets read
MediaQuery directly and degrade gracefully. Set to false to ignore
system accessibility flags globally (e.g. for a game where full glass
fidelity is intentional regardless of OS settings). A
GlassAccessibilityScope placed anywhere in the widget tree always takes
precedence over this flag, allowing per-subtree overrides.
adaptiveQuality (default false, experimental)
When true, inserts a root GlassAdaptiveScope that automatically
benchmarks the device and adjusts the global glass quality ceiling in real
time. Three phases:
- Phase 1 (synchronous): forces
minimalwhere shaders are unsupported; caps atstandardon web. - Phase 2 (~180 frames ≈ 3 s at 60 fps): measures real P75 raster durations and sets the initial quality tier.
- Phase 3 (ongoing, near-zero overhead): degrades when P95 exceeds 1.5× the frame budget for 3 consecutive windows; recovers when P95 drops below 0.6× budget for 10 consecutive windows.
Experimental in 0.8.0 — Phase 2 thresholds (12 ms / 20 ms P75) are based on reasoning, not yet validated across the full Android device landscape. Enable this feature and report unexpected quality degradation or promotion to help us tune the thresholds.
Acts as an app-wide quality ceiling — individual widgets with an
explicit quality: parameter are still capped by it. When no
adaptiveConfig is provided, the scope starts at GlassQuality.standard
to prevent jank during the warm-up window on mid-range devices.
For per-screen control, use GlassAdaptiveScope directly in the tree.
adaptiveConfig (optional)
Custom GlassAdaptiveScopeConfig for the root GlassAdaptiveScope.
Ignored when adaptiveQuality is false. Defaults to
GlassAdaptiveScopeConfig(initialQuality: GlassQuality.standard).
Scope nesting order (outermost → innermost → child)
GlassAdaptiveScope (when enabled) → GlassTheme (when provided) → child
Implementation
///
/// **`adaptiveConfig`** (optional)\
/// Custom [GlassAdaptiveScopeConfig] for the root [GlassAdaptiveScope].
/// Ignored when [adaptiveQuality] is `false`. Defaults to
/// `GlassAdaptiveScopeConfig(initialQuality: GlassQuality.standard)`.
///
/// ### Scope nesting order (outermost → innermost → child)
///
/// `GlassAdaptiveScope` (when enabled) → `GlassTheme` (when provided) → `child`
static Widget wrap({
required Widget child,
GlassThemeData? theme,
bool respectSystemAccessibility = true,
bool adaptiveQuality = false,
GlassAdaptiveScopeConfig? adaptiveConfig,
/// Optional brightness resolver for MaterialApp integration.
///
/// When using `MaterialApp`, pass `Theme.maybeBrightnessOf` here so glass
/// widgets correctly honour `ThemeMode.light` / `.dark` / `.system` even
/// when the device OS and the app theme disagree:
///
/// ```dart
/// runApp(LiquidGlassWidgets.wrap(
/// child: const MyApp(),
/// brightnessResolver: Theme.maybeBrightnessOf,
/// ));
/// ```
///
/// This package has zero `flutter/material.dart` imports (required for the
/// `cupertino_ui` split). The callback pattern lets you bridge Material's
/// `ThemeMode` into the glass brightness cascade without coupling the
/// package to Material. `CupertinoApp` users can omit this parameter.
Brightness? Function(BuildContext)? brightnessResolver,
}) {
// Apply global accessibility preference.
glass_config.respectSystemAccessibility = respectSystemAccessibility;
// Register the optional Material brightness resolver.
// This lets MaterialApp users pass Theme.maybeBrightnessOf without this
// package needing to import flutter/material.dart.
glassExternalBrightnessResolver = brightnessResolver;
Widget result = child;
if (theme != null) {
result = GlassTheme(data: theme, child: result);
}
if (adaptiveQuality) {
// When no adaptiveConfig is given: GlassAdaptiveScope.initState() seeds
// the first frame at GlassQuality.standard while Phase 2 benchmarks the
// device (~3 s). Phase 2 then promotes to `premium` if the device passes
// the warmup threshold — no caller config needed.
//
// When the caller provides adaptiveConfig: use their settings as-is.
// If initialQuality is null, Phase 2 still runs fresh and promotes/demotes
// from the conservative standard starting point.
final config = adaptiveConfig ?? const GlassAdaptiveScopeConfig();
result = GlassAdaptiveScope(
minQuality: config.minQuality,
maxQuality: config.maxQuality,
initialQuality: config.initialQuality,
targetFrameMs: config.targetFrameMs,
allowStepUp: config.allowStepUp,
warmupPremiumThresholdMs: config.warmupPremiumThresholdMs,
warmupStandardThresholdMs: config.warmupStandardThresholdMs,
frostStep: config.frostStep,
onQualityChanged: config.onQualityChanged,
onDiagnostic: config.onDiagnostic,
debugLogDiagnostics: config.debugLogDiagnostics,
child: result,
);
}
return result;
}