-
Notifications
You must be signed in to change notification settings - Fork 87
Description
Bug report
When you scroll a Wolt Modal bottom sheet with a mouse scroll wheel or by holding down the mouse and dragging, an exception is thrown by Flutter SDK.
════════ Exception caught by gestures library ══════════════════════════════════
'package:flutter/src/rendering/proxy_box.dart': Failed assertion: line 2948 pos 12: '!debugNeedsLayout': is not true.
Steps to reproduce
Use the short code sample given further below to reproduce the error. (The error can also be seen with the package own sample).
- Used package version: 0.11.0
- Used Flutter version: 3.29.3
Build a macOS desktop app.
Press "Open test sheet".
Scroll the bottom sheet content with a mouse scroll wheel.
OR
If you have mouse drag scrolling enabled, like in this example, you can also trigger the error by holding down the mouse button on the scrolling content and dragging the content up and down.
Expected behavior
Expect the content to scroll without issues.
Actual behavior
The app throws the exception shown in video and log below.
If you scroll with the trackpad the exception is typically not thrown, although you can get it occasionally then also if you scroll really fast back and forth with the trackpad. Often also when you drag-close the sheet with the trackpad.
Video demo
Screen.Recording.2025-04-26.at.22.52.19.mov
Exception log
======== Exception caught by gestures library ======================================================
The following assertion was thrown while handling a pointer data packet:
'package:flutter/src/rendering/proxy_box.dart': Failed assertion: line 2948 pos 12: '!debugNeedsLayout': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.yml
When the exception was thrown, this was the stack:
#2 RenderFractionalTranslation.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:2948:12)
#3 RenderFractionalTranslation.hitTest (package:flutter/src/rendering/proxy_box.dart:2935:12)
#4 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#5 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#6 RenderShiftedBox.hitTestChildren.<anonymous closure> (package:flutter/src/rendering/shifted_box.dart:95:24)
#7 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:840:31)
#8 RenderShiftedBox.hitTestChildren (package:flutter/src/rendering/shifted_box.dart:90:21)
#9 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#10 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#11 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#12 RenderClipRect.hitTest (package:flutter/src/rendering/proxy_box.dart:1568:18)
#13 RenderBoxContainerDefaultsMixin.defaultHitTestChildren.<anonymous closure> (package:flutter/src/rendering/box.dart:3339:25)
#14 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:840:31)
#15 RenderBoxContainerDefaultsMixin.defaultHitTestChildren (package:flutter/src/rendering/box.dart:3334:33)
#16 RenderStack.hitTestChildren (package:flutter/src/rendering/stack.dart:695:12)
#17 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#18 RenderBoxContainerDefaultsMixin.defaultHitTestChildren.<anonymous closure> (package:flutter/src/rendering/box.dart:3339:25)
#19 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:840:31)
#20 RenderBoxContainerDefaultsMixin.defaultHitTestChildren (package:flutter/src/rendering/box.dart:3334:33)
#21 RenderStack.hitTestChildren (package:flutter/src/rendering/stack.dart:695:12)
#22 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#23 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#24 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#25 RenderAbsorbPointer.hitTest (package:flutter/src/rendering/proxy_box.dart:3877:56)
#26 RenderShiftedBox.hitTestChildren.<anonymous closure> (package:flutter/src/rendering/shifted_box.dart:95:24)
#27 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:840:31)
#28 RenderShiftedBox.hitTestChildren (package:flutter/src/rendering/shifted_box.dart:90:21)
#29 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#30 _RenderLayoutBuilder.hitTestChildren (package:flutter/src/widgets/layout_builder.dart:407:19)
#31 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#32 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#33 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#34 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#35 RenderCustomPaint.hitTestChildren (package:flutter/src/rendering/custom_paint.dart:564:18)
#36 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#37 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#38 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#39 RenderPhysicalShape.hitTest (package:flutter/src/rendering/proxy_box.dart:2138:18)
#40 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#41 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#42 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#43 RenderProxyBoxWithHitTestBehavior.hitTest (package:flutter/src/rendering/proxy_box.dart:183:19)
#44 RenderBoxContainerDefaultsMixin.defaultHitTestChildren.<anonymous closure> (package:flutter/src/rendering/box.dart:3339:25)
#45 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:840:31)
#46 RenderBoxContainerDefaultsMixin.defaultHitTestChildren (package:flutter/src/rendering/box.dart:3334:33)
#47 RenderCustomMultiChildLayoutBox.hitTestChildren (package:flutter/src/rendering/custom_layout.dart:429:12)
#48 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#49 RenderShiftedBox.hitTestChildren.<anonymous closure> (package:flutter/src/rendering/shifted_box.dart:95:24)
#50 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:840:31)
#51 RenderShiftedBox.hitTestChildren (package:flutter/src/rendering/shifted_box.dart:90:21)
#52 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#53 RenderBoxContainerDefaultsMixin.defaultHitTestChildren.<anonymous closure> (package:flutter/src/rendering/box.dart:3339:25)
#54 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:840:31)
#55 RenderBoxContainerDefaultsMixin.defaultHitTestChildren (package:flutter/src/rendering/box.dart:3334:33)
#56 RenderCustomMultiChildLayoutBox.hitTestChildren (package:flutter/src/rendering/custom_layout.dart:429:12)
#57 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#58 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#59 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#60 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#61 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#62 RenderPhysicalModel.hitTest (package:flutter/src/rendering/proxy_box.dart:2032:18)
#63 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#64 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#65 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#66 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#67 RenderIgnorePointer.hitTest (package:flutter/src/rendering/proxy_box.dart:3625:31)
#68 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#69 RenderFractionalTranslation.hitTestChildren.<anonymous closure> (package:flutter/src/rendering/proxy_box.dart:2956:22)
#70 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:840:31)
#71 RenderFractionalTranslation.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:2949:19)
#72 RenderFractionalTranslation.hitTest (package:flutter/src/rendering/proxy_box.dart:2935:12)
#73 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#74 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#75 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#76 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#77 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#78 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#79 RenderOffstage.hitTest (package:flutter/src/rendering/proxy_box.dart:3756:31)
#80 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#81 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#82 _RenderTheaterMixin.hitTestChildren.childHitTest (package:flutter/src/widgets/overlay.dart:1097:22)
#83 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:840:31)
#84 _RenderTheaterMixin.hitTestChildren (package:flutter/src/widgets/overlay.dart:1098:22)
#85 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#86 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#87 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#88 RenderAbsorbPointer.hitTest (package:flutter/src/rendering/proxy_box.dart:3877:56)
#89 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#90 RenderProxyBoxWithHitTestBehavior.hitTest (package:flutter/src/rendering/proxy_box.dart:183:19)
#91 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#92 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#93 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#94 RenderCustomPaint.hitTestChildren (package:flutter/src/rendering/custom_paint.dart:564:18)
#95 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#96 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#97 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#98 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#99 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#100 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#101 RenderTapRegionSurface.hitTest (package:flutter/src/widgets/tap_region.dart:234:28)
#102 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#103 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#104 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#105 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#106 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#107 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#108 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:128:19)
#109 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2943:11)
#110 RenderView.hitTest (package:flutter/src/rendering/view.dart:311:12)
#111 RendererBinding.hitTestInView (package:flutter/src/rendering/binding.dart:649:34)
#112 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:408:7)
#113 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:394:5)
#114 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:341:7)
#115 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:308:9)
#116 _invoke1 (dart:ui/hooks.dart:332:13)
#117 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:451:7)
#118 _dispatchPointerDataPacket (dart:ui/hooks.dart:267:31)
(elided 2 frames from class _AssertionError)Code sample
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Wolt Modal Sheet Issue',
scrollBehavior: DragScrollBehavior(),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Wolt Modal Sheet Issue')),
body: Center(
child: ElevatedButton(
child: const Text('Open test sheet'),
onPressed: () {
WoltModalSheet.show<void>(
context: context,
pageListBuilder: (modalSheetContext) {
return [_buildPage(modalSheetContext)];
},
modalTypeBuilder: (context) {
return WoltBottomSheetType();
},
onModalDismissedWithDrag: () {
debugPrint('Bottom sheet is dismissed with drag.');
Navigator.of(context).pop();
},
onModalDismissedWithBarrierTap: () {
debugPrint('Modal is dismissed with barrier tap.');
Navigator.of(context).pop();
},
);
},
),
),
);
}
SliverWoltModalSheetPage _buildPage(BuildContext modalSheetContext) {
return WoltModalSheetPage(
hasSabGradient: false, // Remove default gradient overlay
topBarTitle: const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'Demo of scroll issue',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
isTopBarLayerAlwaysVisible: true, // Keep title visible when scrolling
// Main content is the scrollable list
child: ListView.builder(
physics: const ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: 50,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text('Scrolling content ${index + 1}'),
leading: CircleAvatar(child: Text('${index + 1}')),
);
},
),
);
}
}
// Define a custom scroll behavior that enables mouse dragging
class DragScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.trackpad,
PointerDeviceKind.stylus,
PointerDeviceKind.invertedStylus,
PointerDeviceKind.mouse,
};
}
Blocker issue at HypeHype for adopting Wolt Modal Sheet
We are trying Wolt modal sheet at HypeHype, but since our app for devs in debug mode shows exceptions also on purpose to the dev in annoying popup's in the app during development, it pretty much makes the package a no starter as it spams the entire app with error popups all the time when you scroll on desktop build.
The HypeHype game platform app supports and targets iOS, Android, Windows, macOS and Web.
This is an example of what it looks like when we use it:
hh_demo.mov
Clearly not a very nice dev experience.