flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
165.32k stars 27.28k forks source link

`DataColumn` overflow in canvaskit in a certain language #149010

Open kkundi opened 4 months ago

kkundi commented 4 months ago

Steps to reproduce

Run the code on Chrome.

I think it occurs when there are long values ​​in a specific column. Exception occurs when the length of the value of a column is smaller than the column name.

This does not occur when the column name is English, but occurs when Korean or Japanese are used.

Expected results

No exception

Actual results

Excaption caught

A RenderFlex overflowed by 9.7 pixels on the right.

Code sample

Code sample ```dart import 'package:flutter/material.dart'; /// Flutter code sample for [PaginatedDataTable]. class MyDataSource extends DataTableSource { @override int get rowCount => 3; @override DataRow? getRow(int index) { switch (index) { case 0: return const DataRow( cells: [ DataCell(Text('Sarah')), DataCell(Text('19')), DataCell(Text( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.')), ], ); case 1: return const DataRow( cells: [ DataCell(Text('Janine')), DataCell(Text('43')), DataCell(Text('Professor')), ], ); case 2: return const DataRow( cells: [ DataCell(Text('William')), DataCell(Text('27')), DataCell(Text('Associate Professor')), ], ); default: return null; } } @override bool get isRowCountApproximate => false; @override int get selectedRowCount => 0; } final DataTableSource dataSource = MyDataSource(); void main() => runApp(const DataTableExampleApp()); class DataTableExampleApp extends StatelessWidget { const DataTableExampleApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: SingleChildScrollView( padding: EdgeInsets.all(12.0), child: DataTableExample(), ), ); } } class DataTableExample extends StatelessWidget { const DataTableExample({super.key}); @override Widget build(BuildContext context) { return PaginatedDataTable( columns: const [ DataColumn( label: Text('Name'), ), DataColumn( label: Text('나이'), ), DataColumn( label: Text('Role'), ), ], source: dataSource, ); } } ```

Screenshots or Video

Screenshots / Video demonstration 스크린샷 2024-05-24 오전 10 16 39 스크린샷 2024-05-24 오전 10 17 00 스크린샷 2024-05-24 오전 10 20 55

Logs

Logs ```console ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ The following assertion was thrown during layout: A RenderFlex overflowed by 9.7 pixels on the right. The relevant error-causing widget was: PaginatedDataTable PaginatedDataTable:file:///Users/kunsukim/workspace/collector-admin/lib/main.dart:72:12 To inspect this widget in Flutter DevTools, visit: http://127.0.0.1:9100/#/inspector?uri=http%3A%2F%2F127.0.0.1%3A55860%2Fz7XHytwuSWg%3D&inspectorRef=inspector-0 The overflowing RenderFlex has an orientation of Axis.horizontal. The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and black striped pattern. This is usually caused by the contents being too big for the RenderFlex. Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size. This is considered an error condition because it indicates that there is content that cannot be seen. If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView. The specific RenderFlex in question is: RenderFlex#c0c97 relayoutBoundary=up1 OVERFLOWING: creator: Row ← DefaultTextStyle ← AnimatedDefaultTextStyle ← Align ← Padding ← ConstrainedBox ← Container ← Listener ← RawGestureDetector ← GestureDetector ← Semantics ← DefaultSelectionStyle ← ⋯ parentData: offset=Offset(0.0, 18.0) (can use size) constraints: BoxConstraints(0.0<=w<=16.2, 0.0<=h<=56.0) size: Size(16.2, 20.0) direction: horizontal mainAxisAlignment: start mainAxisSize: max crossAxisAlignment: center textDirection: ltr verticalDirection: down ```

Flutter Doctor output

Doctor output ```console [✓] Flutter (Channel stable, 3.22.1, on macOS 13.3 22E252 darwin-arm64, locale ko-KR) • Flutter version 3.22.1 on channel stable at /Users/kunsukim/development/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision a14f74ff3a (33 hours ago), 2024-05-22 11:08:21 -0500 • Engine revision 55eae6864b • Dart version 3.4.1 • DevTools version 2.34.3 [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at /Users/kunsukim/Library/Android/sdk • Platform android-34, build-tools 34.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231) • All Android licenses accepted. [!] Xcode - develop for iOS and macOS (Xcode 14.3.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14E300c ! Flutter recommends a minimum Xcode version of 15. Download the latest version or update via the Mac App Store. ! CocoaPods 1.12.1 out of date (1.13.0 is recommended). CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side. Without CocoaPods, plugins will not work on iOS or macOS. For more info, see https://flutter.dev/platform-plugins To upgrade see https://guides.cocoapods.org/using/getting-started.html#updating-cocoapods for instructions. [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2022.3) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231) [✓] VS Code (version 1.87.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.84.0 [✓] Connected device (4 available) • iPhone 14 Pro Max (mobile) • 532B6A58-E623-486F-9AC9-429A856A611A • ios • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator) • macOS (desktop) • macos • darwin-arm64 • macOS 13.3 22E252 darwin-arm64 • Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin • macOS 13.3 22E252 darwin-arm64 • Chrome (web) • chrome • web-javascript • Google Chrome 125.0.6422.77 [✓] Network resources • All expected network resources are available. ! Doctor found issues in 1 category. ```
huycozy commented 4 months ago

Thank you for the report. I can see the same behavior.

I also checked a case when I set the column name (DataColumn Text label) to English but non-English for column value (DataCell's Text child), the issue didn't occur.

flutter doctor -v (stable and master) ```bash [✓] Flutter (Channel stable, 3.22.1, on macOS 14.1 23B74 darwin-x64, locale en-VN) • Flutter version 3.22.1 on channel stable at /Users/huynq/Documents/GitHub/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision a14f74ff3a (11 hours ago), 2024-05-22 11:08:21 -0500 • Engine revision 55eae6864b • Dart version 3.4.1 • DevTools version 2.34.3 [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at /Users/huynq/Library/Android/sdk • Platform android-34, build-tools 34.0.0 • ANDROID_HOME = /Users/huynq/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 15.3) • Xcode at /Applications/Xcode15.3.app/Contents/Developer • Build 15E204a • CocoaPods version 1.15.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2023.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • android-studio-dir = /Applications/Android Studio.app/ • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874) [✓] VS Code (version 1.89.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.88.0 [✓] Connected device (2 available) • macOS (desktop) • macos • darwin-x64 • macOS 14.1 23B74 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 125.0.6422.76 [✓] Network resources • All expected network resources are available. • No issues found! ``` ```bash [!] Flutter (Channel master, 3.23.0-3.0.pre.1, on macOS 14.1 23B74 darwin-x64, locale en-VN) • Flutter version 3.23.0-3.0.pre.1 on channel master at /Users/huynq/Documents/GitHub/flutter_master ! Warning: `flutter` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path. ! Warning: `dart` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path. • Upstream repository https://github.com/flutter/flutter.git • Framework revision 1317046ef8 (62 minutes ago), 2024-05-23 22:35:13 -0400 • Engine revision d78f667533 • Dart version 3.5.0 (build 3.5.0-187.0.dev) • DevTools version 2.36.0-dev.10 • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades. [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at /Users/huynq/Library/Android/sdk • Platform android-34, build-tools 34.0.0 • ANDROID_HOME = /Users/huynq/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 15.3) • Xcode at /Applications/Xcode15.3.app/Contents/Developer • Build 15E204a • CocoaPods version 1.15.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2023.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • android-studio-dir = /Applications/Android Studio.app/ • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874) [✓] VS Code (version 1.89.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.88.0 [✓] Connected device (4 available) • RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64 • Android 11 (API 30) • iPhone (mobile) • d9a94afe2b649fef56ba0bfeb052f0f2a7dae95e • ios • iOS 15.8 19H370 • macOS (desktop) • macos • darwin-x64 • macOS 14.1 23B74 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 125.0.6422.76 [✓] Network resources • All expected network resources are available. ! Doctor found issues in 1 category. ```
TahaTesser commented 4 months ago

@kkundi Does this only produce on web? I can't reproduce on desktop app.

kkundi commented 4 months ago

@TahaTesser I launched at iOS simulator. The problem didn't occur. So I thought it is only produce on web.

If It is not reproduced on web, Would you try to make column value (Lorem ipsum value) is enough long? If all column value is displayed in one screen, the problem doesn't occur.

스크린샷 2024-05-27 오전 9 47 52 스크린샷 2024-05-27 오전 9 48 04
kkundi commented 4 months ago

@TahaTesser I tried to reproduce the problem on desktop app. but it didn't occur. It occur only on web.

TahaTesser commented 4 months ago

@kkundi

This seems to be a bug in canvaskit renderer. This can better produced in DataTable which PaginatedDataTable uses internally.

Code sample

expand to view the code sample ```dart import 'package:flutter/material.dart'; /// Flutter code sample for [DataTable]. void main() => runApp(const DataTableExampleApp()); class DataTableExampleApp extends StatelessWidget { const DataTableExampleApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('DataTable Sample')), body: const DataTableExample(), ), ); } } class DataTableExample extends StatelessWidget { const DataTableExample({super.key}); @override Widget build(BuildContext context) { return DataTable( columns: const [ DataColumn( label: Text('Name'), ), DataColumn( label: Text('나이'), // label: Text('나이'), ), DataColumn( label: Text('Role'), ), ], rows: const [ DataRow( cells: [ DataCell(Text('Sarah')), DataCell(Text('19')), DataCell(Text('Student')), ], ), DataRow( cells: [ DataCell(Text('Janine')), DataCell(Text('43')), DataCell(Text('Professor')), ], ), DataRow( cells: [ DataCell(Text('William')), DataCell(Text('27')), DataCell(Text('Associate Professor')), ], ), ], ); } } ```
--web-renderer html --web-renderer canvaskit
yjbanov commented 4 months ago

I suspect the issue is in the DataColumn widget itself. The issue is probably that CanvasKit fetches the font lazily, but by the time it's fetched the widget already measured the width of the header cell and cached it. The web engine sends a signal when fonts change, and the expectation is that all widgets showing text should remeasure themselves. This would be a fix in the widget, so for now I'm redirecting to the framework team.

However, if it turns out that the bug is in the web engine, please send it back to team-web.

TahaTesser commented 4 months ago

@yjbanov You're right, I can confirm this. Since DataTable is a stateless widget and it builds the columns and rows in the build for the underlying Table widget, The DataTable is not rebuilt when the system font changes.

I can fix this by rebuilding Table widget with ListenableBuilder listening to PaintingBinding.instance.systemFonts and attaching a UniqueKey to the Table to rebuild itself when the system font changes.

        child: ListenableBuilder(
          listenable: PaintingBinding.instance.systemFonts, // Listen for changes to the system fonts.
          builder: (BuildContext context, _) {
            return Table(
              key: UniqueKey(),
              columnWidths: tableColumns.asMap(),
              defaultVerticalAlignment: TableCellVerticalAlignment.middle,
              children: tableRows,
              border: border,
            );
          }
        ),

I'll explore some other possible fixes for this.