diff --git a/lib/shared/widgets/app_dialog.dart b/lib/shared/widgets/app_dialog.dart index 73004af5..d47fc7d0 100644 --- a/lib/shared/widgets/app_dialog.dart +++ b/lib/shared/widgets/app_dialog.dart @@ -101,23 +101,25 @@ class _BlurredDialogScaffoldState extends State<_BlurredDialogScaffold> { child: Stack( fit: StackFit.expand, children: [ - // Backdrop: animates blur sigma and dim alpha directly (no FadeTransition). + // Backdrop: static blur; only opacity/dim animate (blur sigma is expensive). Positioned.fill( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: widget.barrierDismissible ? widget.onDismiss : null, child: AnimatedBuilder( animation: curved, - builder: (ctx, _) { - final t = curved.value; - return ClipRect( - child: BackdropFilter( - filter: - ImageFilter.blur(sigmaX: 8.0 * t, sigmaY: 8.0 * t), - child: Container( - color: Colors.black.withValues(alpha: 0.32 * t), - ), + child: ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8), + child: const ColoredBox( + color: Color(0x52000000), // black @ 0.32 ), + ), + ), + builder: (ctx, child) { + return Opacity( + opacity: curved.value.clamp(0.0, 1.0), + child: child, ); }, ), diff --git a/test/shared/app_dialog_test.dart b/test/shared/app_dialog_test.dart index 96a775f8..6f39ddee 100644 --- a/test/shared/app_dialog_test.dart +++ b/test/shared/app_dialog_test.dart @@ -1,3 +1,5 @@ +import 'dart:ui' show ImageFilter; + import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:querya_desktop/core/motion/querya_motion.dart'; @@ -83,6 +85,23 @@ void main() { expect(find.byType(ScaleTransition), findsNothing); }); + testWidgets('backdrop keeps static blur sigma; opacity carries enter', + (tester) async { + final ctx = await pumpHost(tester); + + showAppDialog( + context: ctx, + builder: (c) => const SimpleDialog(title: Text('Blur')), + ); + // Mid-enter: blur must stay sigma 8 (not sigma * t). + await tester.pump(); + await tester.pump(const Duration(milliseconds: 40)); + + final filter = tester.widget(find.byType(BackdropFilter)); + expect(filter.filter, ImageFilter.blur(sigmaX: 8, sigmaY: 8)); + expect(find.byType(Opacity), findsWidgets); + }); + testWidgets('enter uses standard duration under full motion', (tester) async { final ctx = await pumpHost(tester); showAppDialog(