text:
Using dart:ui from non-main-thread Isolates crashes

Latest update (tl;dr: no current plans): https://github.com/flutter/flutter/issues/10647#issuecomment-1167923640
Steps to Reproduce
In a fresh codebase generated by flutter create, I added the following functions and amended the main() function. Code taken from this example:
void echo(SendPort sender) {
  print("echo() the Isolate has been spawned!");
  ReceivePort receivePort = new ReceivePort();
  sender.send(receivePort.sendPort);
  receivePort.listen((data) {
    String msg = data[0];
    SendPort replyTo = data[1];
    print("Isolate received: $msg");
    WidgetsFlutterBinding.ensureInitialized();
    replyTo.send("Greetings from echo() the Isolate!");
  });
}

Future sendReceive(SendPort port, String msg) {
  ReceivePort receivePort = new ReceivePort();
  port.send([msg, receivePort.sendPort]);
  return receivePort.first;
}

void main() {
  ReceivePort receivePort = new ReceivePort();
  Future<Isolate> remote = Isolate.spawn(echo, receivePort.sendPort);
  remote.then((_) => receivePort.first).then((sendPort) {
    sendReceive(sendPort, "message sent from main()").then((msg) {
      print("Main received: $msg");
    });
  });
  runApp(new MyApp());
}

When I comment out the WidgetsFlutterBinding.ensureInitialized(); call, everything runs smoothly. Leaving it in, the app crashes. When I run it in SkyShell with that call left in, I get a seg fault:
echo() the Isolate has been spawned!
Isolate received: message sent from main()
Segmentation fault: 11

What is happening here? Should WidgetsFlutterBinding.ensureInitialized() be able to be called from a spawned Isolate?
Flutter Doctor
[✓] Flutter (on Mac OS X 10.12.5 16F73, locale en-US, channel alpha)
    • Flutter at /Users/emshack/flutter
    • Framework revision e2f54df5ab (10 days ago), 2017-06-02 10:43:54 -0700
    • Engine revision 1f2aa07571
    • Tools Dart version 1.24.0-dev.3.0

[✓] Android toolchain - develop for Android devices (Android SDK 25.0.3)
    • Android SDK at /Users/emshack/Library/Android/sdk
    • Platform android-25, build-tools 25.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version: OpenJDK Runtime Environment (build 1.8.0_112-release-b06)

[✓] iOS toolchain - develop for iOS devices (Xcode 8.3.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 8.3.2, Build version 8E2002
    • ios-deploy 1.9.1
    • CocoaPods version 1.2.0

[✓] Android Studio (version 2.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Gradle version 3.2
    • Java version: OpenJDK Runtime Environment (build 1.8.0_112-release-b06)

[✓] IntelliJ IDEA Community Edition (version 2016.3.4)
    • Dart plugin version 163.13137
    • Flutter plugin version 12.1

[✓] Connected devices
    • iPhone 7 Plus • 09A7F58D-C832-4D91-B681-F67134E64361 • ios • iOS 10.3 (simulator)

dart:ui doesn't exist in non-main isolates, so I wouldn't expect much of the Flutter framework to work there.  FYI @Hixie.
We're currently in the process of making some improvements to our engine to allow exposing dart:ui on non-main isolates, but those are not yet complete.

Ok, please let me know when something like this would be possible!

This will also help another part of our project where we currently spawn another process and communicate via HTTP as a workaround.  So +1 to making this work in an isolate.

@GaryQian is currently working on wiring up libtxt as our new txt backend.  I'm told that's the largest single blocker to being able to use dart:ui off the main thread.  I suspect it may be several months before that's all landed and integrated and off-main-thread dart:ui is support at our current schedules though.  @abarth or @Hixie may correct my estimates however.

@chinmaygarde Any idea what the current status of this is?
We will have to come to a decision on what needs to be supported here by 1.0.

Launching multiple Flutter views in their own isolates when their own dedicated threads is now supported (and is the default). Having multiple isolates talk to the same view is not currently supported and is not a priority.
We should probably not crash when WidgetsFlutterBinding.ensureInitialized is called from a secondary isolate however. Happy to work towards understanding if the current scheme of having multiple Flutter views solves @emshack's use case.

I need this so much, especially for a heavy things like Path.combine.
I'm having a frame running for 3 seconds because there is no way to isolate native executions on Path.

I have same problem

Same problem

Did you guys find any solution to open UI from isolate ?

Issue replicable on latest beta.
I/flutter (16811): echo() the Isolate has been spawned!
I/flutter (16811): Isolate received: message sent from main()
E/flutter (16811): [ERROR:flutter/runtime/dart_isolate.cc(882)] Unhandled exception:
E/flutter (16811): UI actions are only available on root isolate.

Although moving WidgetsFlutterBinding.ensureInitialized(); inside main() method doesn't throw the said error.

flutter doctor -v
[✓] Flutter (Channel beta, 1.22.0-12.2.pre, on Mac OS X 10.15.4 19E2269, locale
    en-IN)
    • Flutter version 1.22.0-12.2.pre at /Users/dhs/documents/Fluttersdk/flutter
    • Framework revision 2bafdc8226 (4 days ago), 2020-09-25 12:48:22 -0700
    • Engine revision f763b5b9b9
    • Dart version 2.10.0 (build 2.10.0-110.5.beta)

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.0)
    • Android SDK at /Users/dhs/Library/Android/sdk
    • Platform android-30, build-tools 30.0.0
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6222593)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.5)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.5, Build version 11E608c
    • CocoaPods version 1.9.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 46.0.2
    • Dart plugin version 193.7361
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6222593)

[✓] VS Code (version 1.49.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.11.0

[✓] Connected device (2 available)
    • Web Server (web) • web-server • web-javascript • Flutter Tools
    • Chrome (web)     • chrome     • web-javascript • Google Chrome
      85.0.4183.121

• No issues found!

Issue replicable on latest beta.
I/flutter (16811): echo() the Isolate has been spawned!
I/flutter (16811): Isolate received: message sent from main()
E/flutter (16811): [ERROR:flutter/runtime/dart_isolate.cc(882)] Unhandled exception:
E/flutter (16811): UI actions are only available on root isolate.

Although moving WidgetsFlutterBinding.ensureInitialized(); inside main() method doesn't throw the said error.
flutter doctor -v

could you give a small example , please?  thank you

Is this still not possible? i'm building 1000's of Paragraph objects and would like to do it in in non-main isolates.. but still getting this crash

I am using dart:ui for image processing. Processing a bunch of images freezes my UI, and I, unfortunately, was unable to get the code running in a isolate.
// Some sample code that can't be run in an isolate:
Future<Image> pngRead(File pngFile) async {
  final bytes = await pngFile.readAsBytes();
  final codec = await instantiateImageCodec(bytes);
  final frame = await codec.getNextFrame();
  return frame.image;
}

Future<Image> generateImage(
  CustomPainter? painter,
  int width,
  int height,
) async {
  final recorder = PictureRecorder();
  final canvas = Canvas(recorder);
  painter?.paint(canvas, Size(width.toDouble(), height.toDouble()));
  final picture = recorder.endRecording();
  return picture.toImage(width, height);
}

@Hixie @chinmaygarde Hi bro, I think this is very important thing that flutter should support.
What should I do if I want to change app language via Get.updateLocale()?
App always lag when I call that method on main isolate. That's too sad!
Please support us a solution, thank you!

Any progress on this? we're stuck to proceed with flutter because of the below issues.

We've to use multiple isolates for painting a spreadsheet but dart:ui is not available in non-ui isolates.
send the ui:image to the root isolate immediately. currently the decoding of image received at ui isolate takes a lot of ms.

Is there a way to overcome this issue?

It has been 5 years, Flutter still not fix this problem, It is very important for us,  I could fix this problem with SurfaceView on Android, how to fix this on Flutter?

Any updates on this?

Regarding usecases, I am using dart ui.PictureRecorder to draw a series of PNG images to be used in an overlay that gets merged on top of a user uploaded video. At a frame rate of 30+ frames per second, the app needs to generate thousands of PNGs for a 10 minute video. Of course this doesn't run well on the main isolate and I need to run this work on a pool of isolates. I initially ran in to the same problem that started this thread while attempting to use regular isolates. As such, I switched to use the Flutter Isolates package..  Dart UI works in the Flutter Isolates package, however, I ran into other bugs that have been open for years that render the package unusable for this kind of work.
Unfortunately this is one of a many dead-ends I have encountered while trying to build my app in flutter. I will be honest, I really don't want to spend my time filling in the gaps of a half-functional framework with patches, PRs, and design doc I have to write myself. I just want to build a beautiful app (like Tim Sneath says all the time at the flutter events. ), but this has proved very difficult with flutter. Using flutter for a real-world project is like  trying to use a kid's plastic toy hammer on a real construction job.

@Hixie FYI, I describe a use-case and attempted mitigations related to this constraint in #115257

From a Flutter application developer’s perspective, dart:ui is no different from any other general purpose dart library.  For example, an application developer might use dart:math for literally infinite many use cases, some of which might need to run inside an isolate for performance reasons. The developer would be surprised and disappointed to find that after successfully compiling their Flutter application, a call to dart:math breaks when called from an isolate at runtime.  This is exactly what happens with dart:ui as evidenced by the number of issues I have stumbled across that are all asking to use some component of dart:ui in an isolate. Within each of those issues, there are many additional use cases contributed by other users via comments.  Most of these use cases are attempting to use dart:ui as a generic drawing or image  processing tool.
I gather that there are some “unsafe” components in dart:ui that should not be called from an isolate that can impact application rendering and frame scheduling.  But, to reiterate, many of these use cases are looking to use the “safe” components of dart:ui  (Canvas, Picture, PictureRecorder, Paint, Path,  Radius, Rect, Offset, Image, Gradient, etc.), using dart:ui as a generic drawing or image manipulation tool.  But then, why are these "safe" generic drawing utilities packaged with “unsafe” Flutter components?  Alternatively,  why are the “safe” generic drawing utilities indiscriminately restricted from isolates along with the “unsafe” Flutter components. To go back to the analogy, would it make sense for the Flutter team to restrict  dart:math from isolates if there was some special Flutter code packaged with dart:math. Of course it doesn't, but it appears that that is exactly what is happening with dart:ui.

Reproduces on the latest versions of flutter. Updating labels.

code sample
import 'dart:isolate';

import 'package:flutter/material.dart';

void echo(SendPort sender) {
  print("echo() the Isolate has been spawned!");
  ReceivePort receivePort = ReceivePort();
  sender.send(receivePort.sendPort);
  receivePort.listen((data) {
    String msg = data[0];
    SendPort replyTo = data[1];
    print("Isolate received: $msg");
    WidgetsFlutterBinding.ensureInitialized();
    replyTo.send("Greetings from echo() the Isolate!");
  });
}

Future sendReceive(SendPort port, String msg) {
  ReceivePort receivePort = ReceivePort();
  port.send([msg, receivePort.sendPort]);
  return receivePort.first;
}

void main() {
  ReceivePort receivePort = ReceivePort();
  Future<Isolate> remote = Isolate.spawn(echo, receivePort.sendPort);
  remote.then((_) => receivePort.first).then((sendPort) {
    sendReceive(sendPort, "message sent from main()").then((msg) {
      print("Main received: $msg");
    });
  });
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      theme: ThemeData.dark(),
      home: const Home(),
    );
  }
}

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Material App Bar'),
      ),
      body: const Center(
        child: Text('some text'),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {},
      ),
    );
  }
}

logs
Launching lib/main.dart on macOS in debug mode...
Building macOS application...
--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:arm64, id:00008103-000329201AD1001E }
{ platform:macOS, arch:x86_64, id:00008103-000329201AD1001E }
Debug service listening on ws://127.0.0.1:51624/HWY-7KvoUsw=/ws
Syncing files to device macOS...
flutter: echo() the Isolate has been spawned!
flutter: Isolate received: message sent from main()
[ERROR:flutter/runtime/dart_isolate.cc(1097)] Unhandled exception:
UI actions are only available on root isolate.
#0      FfiTrampoline____nativeSetNeedsReportTimings$Method$FfiNative$Ptr (dart:ffi)
#1      PlatformDispatcher.__nativeSetNeedsReportTimings (dart:ui/platform_dispatcher.dart:546:24)
#2      PlatformDispatcher._nativeSetNeedsReportTimings (dart:ui/platform_dispatcher.dart:543:52)
#3      PlatformDispatcher.onReportTimings= (dart:ui/platform_dispatcher.dart:535:29)
#4      SchedulerBinding.addTimingsCallback (package:flutter/src/scheduler/binding.dart:308:26)
#5      SchedulerBinding.initInstances (package:flutter/src/scheduler/binding.dart:240:7)
#6      ServicesBinding.initInstances (package:flutter/src/services/binding.dart:37:11)
#7      PaintingBinding.initInstances (package:flutter/src/painting/binding.dart:20:11)
#8      SemanticsBinding.initInstances (package:flutter/src/semantics/binding.dart:18:11)
#9      RendererBinding.initInstances (package:flutter/src/rendering/binding.dart:30:11)
#10     WidgetsBinding.initInstances (package:flutter/src/widgets/binding.dart:249:11)
#11     new BindingBase (package:flutter/src/foundation/binding.dart:151:5)
#12     new _WidgetsFlutterBinding&BindingBase&GestureBinding (package:flutter/src/widgets/binding.dart)
#13     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding (package:flutter/src/widgets/binding.dart)
#14     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding (package:flutter/src/widgets/binding.dart)
#15     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding (package:flutter/src/widgets/binding.dart)
#16     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding (package:flutter/src/widgets/binding.dart)
#17     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding&RendererBinding (package:flutter/src/widgets/binding.dart)
#18     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding (package:flutter/src/widgets/binding.dart)
#19     new WidgetsFlutterBinding (package:flutter/src/widgets/binding.dart)
#20     WidgetsFlutterBinding.ensureInitialized (package:flutter/src/widgets/binding.dart:1260:7)
#21     echo.<anonymous closure> (package:ent/main.dart:13:27)
#22     _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)
#23     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#24     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#25     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#26     _StreamController._add (dart:async/stream_controller.dart:648:7)
#27     _StreamController.add (dart:async/stream_controller.dart:596:5)
#28     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)
Application finished.

flutter doctor -v
[✓] Flutter (Channel stable, 3.7.7, on macOS 13.2.1 22D68 darwin-arm64, locale en-GB)
    • Flutter version 3.7.7 on channel stable at /Users/nexus/dev/sdks/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 2ad6cd72c0 (9 days ago), 2023-03-08 09:41:59 -0800
    • Engine revision 1837b5be5f
    • Dart version 2.19.4
    • DevTools version 2.20.1

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/221.6008.13.2211.9477386/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14C18
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.1)
    • 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 11.0.15+0-b2043.56-8887301)

[✓] Android Studio (version 2022.1)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/221.6008.13.2211.9477386/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 11.0.15+0-b2043.56-8887301)

[✓] IntelliJ IDEA Community Edition (version 2022.3.3)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 72.1.4
    • Dart plugin version 223.8888

[✓] VS Code (version 1.76.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.60.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.2.1 22D68 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 111.0.5563.64

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

[!] Flutter (Channel master, 3.9.0-9.0.pre.32, on macOS 13.2.1 22D68 darwin-arm64, locale en-GB)
    • Flutter version 3.9.0-9.0.pre.32 on channel master at /Users/nexus/dev/sdks/flutters
    ! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 53dfd23b04 (4 hours ago), 2023-03-17 01:59:19 -0400
    • Engine revision d9e65441ea
    • Dart version 3.0.0 (build 3.0.0-339.0.dev)
    • DevTools version 2.22.2
    • 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 33.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/221.6008.13.2211.9477386/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14C18
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.1)
    • 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 11.0.15+0-b2043.56-8887301)

[✓] Android Studio (version 2022.1)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/221.6008.13.2211.9477386/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 11.0.15+0-b2043.56-8887301)

[✓] IntelliJ IDEA Community Edition (version 2022.3.3)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 72.1.4
    • Dart plugin version 223.8888

[✓] VS Code (version 1.76.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.60.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.2.1 22D68 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 111.0.5563.64

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.

If Google does not want to fix this issue, can they provide a workaround with a working example?

From a Flutter application developer’s perspective, dart:ui is no different from any other general purpose dart library. For example, an application developer might use dart:math for literally infinite many use cases, some of which might need to run inside an isolate for performance reasons. The developer would be surprised and disappointed to find that after successfully compiling their Flutter application, a call to dart:math breaks when called from an isolate at runtime. This is exactly what happens with dart:ui as evidenced by the number of issues I have stumbled across that are all asking to use some component of dart:ui in an isolate. Within each of those issues, there are many additional use cases contributed by other users via comments. Most of these use cases are attempting to use dart:ui as a generic drawing or image processing tool.
I gather that there are some “unsafe” components in dart:ui that should not be called from an isolate that can impact application rendering and frame scheduling. But, to reiterate, many of these use cases are looking to use the “safe” components of dart:ui (Canvas, Picture, PictureRecorder, Paint, Path, Radius, Rect, Offset, Image, Gradient, etc.), using dart:ui as a generic drawing or image manipulation tool. But then, why are these "safe" generic drawing utilities packaged with “unsafe” Flutter components? Alternatively, why are the “safe” generic drawing utilities indiscriminately restricted from isolates along with the “unsafe” Flutter components. To go back to the analogy, would it make sense for the Flutter team to restrict dart:math from isolates if there was some special Flutter code packaged with dart:math. Of course it doesn't, but it appears that that is exactly what is happening with dart:ui.

I second that. In my point of view, there are two main usecases:

Run intensive rendering-related code in other isolates as to not block main thread.
Use general classes related to rendering, but not coupled to Flutter, to implement custom render-related code.

The 1st one is harder to implement, since it requires changing the engine, and is related to other limitations of the current state of threading in Dart.
The 2nd one is simpler, and could be easier to implement. I imagine Dart can easily choose to allow importing files from dart:ui that do not import from anything related to flutter. I don't know if that's possible, but is sounds more doable than solving the 1st point.
Personally, more than a couple times I had to implement code related to rendering, either as a Dart library or to run in an Isolate, not necessarily on Flutter. Being unable to use Offset, Rect, Size, Color etc. is just a weird decision. Why should I manually implement Rect if there is a perfect implementation available in core? Instead, devs are expected to make them from scratch (a 3rd party library for those rendering utils would be nice), basically making libraries naturally incompatible with each other, for not adhering to a common interface.

Would one way of potentially working around this be to use Lightweight flutter engines in a pure Flutter app? (ie. notAdd-to-App).  Since instances of the Lightweight flutter engines have their own threads but share some resources they would be fast to start up and perhaps could be used for offscreen rendering?  (Please note: I'm a Flutter newbie, so there could be gaps in my understanding, so pardon if it is a stupid question).  There are so many use cases which require being able to draw to a canvas in an isolate is required to get Flutter to perform any where near native solutions.

This is disappointing
Flutter should take a look at this issue please

By all accounts this has been an issue since 2017, and in the 6 long years since, the issue has never been addressed.  For all the talk of Flutter having a highly performant rendering engine, it does not support any use-cases where complex imagery has to generated.  The only possibility to accomplish this without affecting user interactions is if the rendering of the imagery in background isolates.  With that not being possible, Flutter is orders of magnitude slower than Skia / Xamarin in accomplishing this, so slow as to be unusable.  I guess Flutter is only meant for cartoons, forget use cases like GIS or real time updates ...

@Medit8r I hit this issue back in 2021, not sure if I commented here, but seems like this issue is not going to be fixed unless there is a change in the flutter design itself, something I doubt they will pull anytime soon, the project I started back then in flutter I had to rewrite twice to go around this issue with no luck sadly, I went to discover different technologies and as far as I know Xamarin is Xml based, not much what a flutter dev would like to move to, the technology I recommend is Jetpack compose and Compose Multiplatform, developed by JetBrains themselves, I worked with it, they have coroutines where u can pull some ui logic into another thread (if safe to call it a thread), but basically what we exactly want! which is to offload some ui code into another isolate. Kotlin is also super cool as well, so no complains so far, apart from being relatively new, back then I doubted the move from flutter, but looking into 2023, Although flutter is very promising and I like it, I simply don't regret the move I made. So I recommend it to everyone.👌

Isolates from the Flutter Isolates package works fine with calls to dart.ui on both IOS and Android. I have been using it to generate lots of images from a pool of Flutter Isolates.

Just want to add my use case:
I use dart:ui & Canvas to render thousands of video frames.
I'd like to use multiple isolates to increase speed.

I released a new plugin that workarounds this issue.  https://pub.dev/packages/dart_ui_isolate
It is similar to the flutter_isolate package, but is specifically aimed at allowing dart:ui to run in an isolate.

@chipweinberger Thank you for that! We dropped a project a couple of years ago because of this issue. We're planning to give it another chance in the next couple of months, so I'll be testing your plugin then.

I've released a new plugin. https://pub.dev/packages/dart_ui_isolate
It is very similar to the flutter_isolate package, but is specifically for allowing dart:ui to run in an isolate, without the additional complexity of external plugin support.
Due to that, it supports FlutterEngineGroup which saves 100s of megabytes of memory.

Can you show an example of how to use it with widgets?

What I understood from @chipweinberger, ui isolates can be used from Android, iOS and OSX. Are there any plans to support the other platforms?
Independently, even when using this functionality on supported platforms, I'm either holding it wrong or it's pretty clunky. Let's say I rasterize an image with dart:ui on a child ui isolate, I then have to copy the image bytes into the dart isolate to then send it over, to then decode the image which will copy the bytes back to native. Naively, I would have hope to use ImageDescriptor, i.e. just sending a pointer to the image in memory, however ImageDescriptor doesn't seem to be serializable[^1]. With this new functionality, should it be?

Can you show an example of how to use it with widgets?

Non-authoritatively: I don't think that's an intended use-case

[^1]: Unhandled Exception: Invalid argument: is a regular instance reachable via : Instance of '_NativeImageDescriptor'

deduping into https://github.com/flutter/flutter/issues/13343

authors: 7mada123 Hellomik2002 HiCubee Hixie Medit8r MikeFP SivaramSS Somtobro VuHongKy chinmaygarde chipweinberger danagbemava-nc darshankawar emshack ershat-dl eseidelGoogle hahouari ignatz jonahwilliams maganap matthew-carroll mishadynin mtiziano p4-k4 paramita ramesh456 rlueders ruskakimov sgehrman ydotmalik


text:
Certain canvas operations should allow physical pixel alignment

(With some recently learnings from the breakage I caused in https://github.com/flutter/flutter/issues/111145)
Certain operations on the canvas can look much better if they are aligned to physical pixels, for example drawing an image could be pixel aligned. This is especially noticeable on low DPR devices, though it can be noticed on higher DPR devices with a careful eye.
Flutter uses logical pixels for all drawing operations. Logical pixels convert to physical pixels at a ratio specified by the specific device the Flutter application is running on. For example, my home desktop monitor has a configured DPR of 1.25, meaning for every 4 logical pixels, there are 5 physical pixels. Many mobile devices have device pixel ratios greater than 2.
In framework code, it is possible to convert logical pixels to physical pixels and vice-versa using the windows devicePixelRatio. Additionally, due to the current unconditional presence of the raster cache pixel snapping, we can assume that every picture has an origin which is always aligned to a physical pixel. That is, 0,0 in each picture is guaranteed to fall on a pixel boundary. It seems like it may be possible for user code to manually pixel align, but there are some problems today:
Logical to Physical Conversion
All canvas APIs accept logical pixels (except those that refer to samples/dimensions from an Image). In order to align an operation, you would need to convert the requested logical pixels to physical pixels, round, and then convert back to logical pixels:
var dxx = (dx * devicePixelRatio).round() / devicePixelRatio;
var dxy = (dy * devicePixelRatio).round() / devicePixelRatio

However, the rounded out physical pixel does not necessarily correspond to an exact logical pixel. This may leave the ultimately chosen destination at the mercy of floating point math. Consider, we want to draw an image at the logical pixels (23, 42.5) with a device pixel ratio of 1.25.  We convert this to the physical pixels (28.75, 53.1250). This can be rounded to (29, 53) which we then convert back to logical pixels of (23.2, 42.4). Everything is good!
But what happens if we have a DPR like 3.33? For the same X coordinate, we convert, round , and convert back ending up with 23.1231231231. Hopefully that rounds to a physical pixel, but it might not.
Knowledge of Accumulated Transformations
The above conversions only work if the only transform above the current picture is the DPR transform. It is possible for a given widget or render object to compute a "localToGlobal" or "globalToLocal" transform, but there is no guarantee the render object will repaint if this changes. Consider the following widget tree:
Transform.scale(x, child: RepaintBoundary(child: Widget()))

The first time that Widget paints, it can compute the total transform and incorporate that to ensure it is still pixel aligned. However if the scaling value changes, then because of the RepaintBounary wrapping Widget, it will not be repainted. Thus the pixel alignment will fail.
For other sorts of transformations, animations are common, and pixel alignment may not be important. For example, if you are apply a perspective transform or doing a rotation, then there may be no benefits in pixel alignment.
Other workarounds
The only 100% guaranteed way to pixel align the origin of a drawing operation is to place it in its own Picture using a RepaintBoundary. However, adding repaint boundaries can also regress performance by adding more layer management.
Ideas
Could we delegate pixel alignment to the engine? For example, in the same way we round out the bounds and origin for raster caching. The canvas/display list code could also encode some intent that some operation should be pixel aligned, and use its knowledge of the CTM to compute that exactly. Would this have an impact on raster caching?

FYI @dnfield @goderbauer @Hixie

There is some discussion related to this in https://github.com/flutter/flutter/issues/59798.

yes definitely related. drawImage might be a case where alignment makes sense to do at the level of an individual draw operation, but pixel aware layout might be required to handle path drawing.
That is similarly not possible today for the same reasons listed here

I think the difference between this issue and those linked issues is that there is almost no reason I can think of where you would want to draw an image at a non-integral location. Paths and things have more caveats

Someone had a patch at some point to try to force images to always render on physical pixel boundaries... it was a non-Google contributor, can't remember who.

(The patch was rejected because it probably didn't do the right thing in a lot of cases and only would have covered some specific code path IIRC)

https://github.com/flutter/flutter/pull/67041

Yeah that won't do the right thing since it isn't aware of the ctm

In general this kind of thing scares me.
It's really easy for this kind of thing to result in hard-to-find bugs whose symptoms are things like vibrating text or twitching borders, or where an animation that does a rotation has a sharp quality drop when rotating past a right angle, or a zoom effect to have frames that seem to jiggle, etc. IMHO it's much better to dead-reckon the layout to end up at pixel boundaries "naturally".
I don't know if we still do it but we used to have some snapping around text. IMHO we should remove all snapping.

I just removed snapping from the engine and it has caused probably one of the worse visual regressions in recent memory 😆

This is the kind of thing that would have been much easier if we'd done it right from the start, certainly. Happy to advise further if there's something concrete I can advise on. :-)

The problem ends up being that we eventually do pixel snapping somewhere, and it gets really confusing when that happens unexpectedly.
If we don't encode pixel snapping higher up in the stack, then we end up with people who write golden tests and assert on exact pixel values and thus encode into their tests that we do pixel snapping somewhere in the stack, they just don't know where (and get surprised when they add or drop it obliquely).
People end up wanting this for text and images specifically. Maybe rather than encoding this for particular DL ops, we'd have some kind of global flag that opts people into physical pixel boundaries for text and image related ops? Something like Paint.enableDithering?

There are certain operations where pixel snapping has impact on rendering quality on low DPR, like drawing an image. There are certain operations where you are anti-aliasing anyway, like drawing a diagonal line. Even if I wanted pixel alignment, I'm not sure that I would want them applied uniformly

Right, I mean if that flag is set globally, then all image and text operations (drawImage, drawImageRect, drawImageNine, drawAtlas, drawParagraph). would get pixel aligned

Though you can still have rotated/transformed text. Maybe that doesn't matter.
Also if it is correct to pixel snap these values, i'd rather do it consistently (except flutter_tester). if its not correct, or there are better methods, then we shouldn't support this method at all

My ideal world:

Layout widgets are physical pixel aware (i.e. child is always positioned on pixel boundary, and if sized by layout also size is pixel snapped)
TextPainter _applyFloatingPointHack instead rounds to nearest physical pixel boundary (rounding to logical pixel doesn't help much with 150% scaling...)
BoxDecoration rounds itself to physical pixels, i.e. 1.0 border is painted a 1px in 100-150% scaling, 2px 175%-250% scaling, 3px 275+, etc. Same goes for padding and margin. This way a Text + Padding + BoxDecoration dimensions would always be snapped on physical pixels.

I think these together would get us quite far on low-dpi devices. Which is a significant amount of Windows PCs.

RenderObjects don't know their context (and can't, for performance reasons). They could be placed inside another RenderObject that applies an arbitrary rotation or perspective transform, say. I'm not sure how we could ever do that ideal world given those constraints.

For layers, where pixel snapping makes difference, there will be only one scale transform above them (scale by devicePixelRatio).
In practice devicePixelRatio value is same for entire window. Each layer could simply snap it's size to devicePixelRatio (i.e. size.width = (size.width * devicePixelRatio).round() / devicePixelRatio) as well as snap any translation that applies to children.
As long as all layers play nice, we should end up on pixel perfect coordinates.
Now if there an arbitrary scaling or perspective transform somewhere, then these pixel adjustments will mean that we land slightly different final (sub)pixels. But with arbitrary transforms like these we already gave up pixel alignment so all bets are off.
This way we would trade sharp physical perfect appearance for possible very mild (hopefully?) distortion when using arbitrary scale/rotate transform.
I think it shouldn't be too difficult to build a prototype for this to see how it behaves in practice and whether my assumptions are right.

Well, that's a different conversation, because that's about layers, not widgets or layout. Layers are always pixel snapped unless someone has applied a transform. Layers could know where they are (it's not free but it's possible, we use it e.g. for the follower layer). But it seems like if we're only concerned with layers that are axis-aligned and don't have unusual transformations applied then the only actual case where they may be off-grid would be during scrolling. We could provide an option that makes layers used in scrolling snap to the nearest physical pixel. I wouldn't want to do that by default, since it would reduce the quality of scrolling on modern systems, but it's possible to do.

Sorry, my bad, I actually meant render object. It's too early in the morning I guess :) I edited the comment.
This needs to be done on render object level (where the layout is calculated). Pixel snapping layers themself is too late.

Render objects don't know their context (and can't, for performance reasons). They can't change their size arbitrarily (they have to obey the constraints). We considered doing this very early on in Flutter's design but decided (based on our experience with similar logic on the web) to not do it and the whole design of the rendering layer is predicated (in part) on this not being supported. I suspect (again based on the experience with web) that the results of such snapping in the framework would actually be quite frustrating for developers.
That said, developers that want things to line up with the pixel grid on devices with simple device pixel ratios can do this quite easily, FWIW, by only ever giving sizes in whole-numbered pixels. Things only go off-grid once the layout pushes it off-grid, it's not like the core layout widgets do it of their own accord. :-)

Device with simple pixel ratios were never the problem. But a large amount of windows users are using 125%, 150% pixel scaling. Which makes pretty much any Flutter application blurry by default and there is no solution for this.
This is not problem with WPF or electron applications. With 150% pixel scaling 1 logical px box border on web will render as 1 physical pixel. With 175 pixel scaling, 1 logical px box border renders as two physical pixels. At no point it becomes blurry. This is the case for Electron, Web and WPF seems to work same.
In my previous comment I never suggested layer changing size arbitrarily. Just that whenever layer sizes itself, it snaps the size to pixels (according to devicePixelRatio). This doesn't involve breaking constraints, because the constraints would alrady be pixel snapped.
Ideally this should be completely transparent to developers. Just like it is on web or Electron.
As a developer, if I do box 1px box border, I don't care if it renders as 1 or 2 physical pixels, as long as it stays sharp. But that's not the case right now.

If you want a one-physical-pixel border, set the border width to 0.

But I don't want one physical-pixel-border. I want 1 physical pixel border on 100%, 125, 150% scaling, 2 physical border on 175 - 250% pixel scaling, 3 physical pixel border on 275-350% pixel scaling, etc.
This is what Win UI applications do, as well as web browsers.

Ah, right. That's the behaviour I was describing earlier as something we very explicitly decided not to do in the core of Flutter, because of our experience with this kind of thing on web. It's relatively straightforward to build widgets that do this, though. For example, you could have a "box" widget that takes a border width, and applies math to that border width to make it a round number of devicePixelRatio pixels and then passes it on to a BoxDecoration, or some such.

(One example of the kind of problem you get with low-level snapping is that animating the transform ends up being very janky, e.g. because you suddenly have to change from being snapped half a pixel over from the "natural" position to being rotated by half a degree (which can't snap usefully).)

I no longer think this is a good idea. I'm closing the issue, but if you disagree feel free to reopen

source: gharchive/issue

authors: Hixie dnfield goderbauer jonahwilliams knopp

repo: flutter/flutter

license_type: permissive

license_source: github-api


text:
Images coming from Camera Stream are getting Blurred in Certain devices

Hi,
We have two Apps in which we are using 2 different versions of Camera Plugin.
App1 -- Camera Plugin Version 0.10.3
App2 -- Camera Plugin version 0.9.4+18
In both Apps the cameraController.takePicture() is throwing an error on the below mentioned devices
Vivo- V2045, vivo 1904, V2142, Y35, V2036
Samsung - Galaxy A22, Galaxy m51, galaxy 10s.
We have tried clicking the images using the cameraController.startImageStream which is giving the images in the form of Stream. Now, the above error has gone but the issue is that in certain devices like One Plus 7Pro, One plus 9Pro, RealMe2 Pro, MI devices etc the images which are getting clicked are blurred.
However, in certain devices like Samsung, Tecno it is working fine.
We are using below code for clicking the images and for converting those CameraImage into the JPG Image File.
Clicking Images via Camera using startImageStream
`await controller!.startImageStream((image) async {
print('image steaming');
print('image ${image.planes.last.bytes}');
if (count < 2) {
count++;
return null;
}
controller?.stopImageStream();

    print('image steaming stopped');
    print('image planes -- ' + image.planes.length.toString());

    var img = await convertYUV420toImageColor(image);

    if (img == null) {
      return null;
    }
    await _saveImage(image, Directory("${extDir!.path}/"),
        "IMG_${DateTime.now().millisecondsSinceEpoch}.png",
        success: (filePath) {
      print('image steaming saved file');
      onComplete(filePath);
    });
  });`

convertYUV420toImageColor function code
`Future<Uint8List?> convertYUV420toImageColor(CameraImage image) async {
try {
final int width = image.width;
final int height = image.height;
final int uvRowStride = image.planes[1].bytesPerRow;
final int uvPixelStride = image.planes[1].bytesPerPixel ?? 0;

  print("uvRowStride: " + uvRowStride.toString());
  print("uvPixelStride: " + uvPixelStride.toString());
  print('image Width -- ' + image.width.toString());
  print('image Height -- ' + image.height.toString());
  print('image P lanes -- ' + image.planes.length.toString());
  print('image Format -- ' + image.format.group.toString());
  print('image planes raw-- ' + image.format.raw.toString());
  // imgLib -> Image package from https://pub.dartlang.org/packages/image
  //var img = imglib.Image(width, height); // Create Image buffer

  final Directory directory =
      Directory('/storage/emulated/0/Download');
  var fileName = "dataFile_for_plane";

  for (int i = 0; i < image.planes.length; i++) {
    print("Saving data file");
    final File dataFile = File(
        '${directory.path}' + "/" + fileName + "_" + i.toString() + ".txt");
    var finalString = 'image Width -- ' +
        image.width.toString() +
        "\n" +
        'image Height -- ' +
        image.height.toString() +
        "\n" +
        'image Width -- ' +
        image.width.toString() +
        "\n" +
        'image Planes --' +
        image.planes[i].bytes.toString() +
        "\n" +
        'image Format -- ' +
        image.format.toString() +
        "\n" +
        'image Group -- ' +
        image.format.group.toString() +
        "\n" +
        'image planes raw --' +
        image.format.raw.toString() +
        "\n";
    await dataFile.writeAsString(finalString);
    print("Saved data file" + dataFile.path.toString());
  }
  var img = imglib.Image(height, width);

  // Fill image buffer with plane[0] from YUV420_888
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      final int uvIndex =
          uvPixelStride * (x / 2).floor() + uvRowStride * (y / 2).floor();
      final int index = y * width + x;

      final yp = image.planes[0].bytes[index];
      final up = image.planes[1].bytes[uvIndex];
      final vp = image.planes[2].bytes[uvIndex];
      // Calculate pixel color
      int r = (yp + vp * 1436 / 1024 - 179).round().clamp(0, 255);
      int g = (yp - up * 46549 / 131072 + 44 - vp * 93604 / 131072 + 91)
          .round()
          .clamp(0, 255);
      int b = (yp + up * 1814 / 1024 - 227).round().clamp(0, 255);
      // color: 0x FF  FF  FF  FF
      //           A   B   G   R
      // //img.data[index] = shift | (b << 16) | (g << 8) | r;
      // if (img.boundsSafe(height - y, x)) {
      //   img.setPixelRgba(-(y + 1), x + 1, r, g, b, shift);
      // }
      if (img.boundsSafe(height - y, x)) {
        img.setPixelRgba(height - y, x, r, g, b, shift);
      }
    }
  }

  imglib.PngEncoder pngEncoder = new imglib.PngEncoder(level: 0, filter: 0);
  List<int> png = pngEncoder.encodeImage(img);
  // muteYUVProcessing = false;
  return Uint8List.fromList(png);
} catch (e) {
  print(">>>>>>>>>>>> ERROR:" + e.toString());
}
return null;
}`

The above code is giving us blur images in certain devices like One Plus 9 Pro, One Plus 7 Pro, RealMe 2 Pro etc.
Video link of the issue, flutter logs and the Complete Camera code is attached for reference.
Video showing the issue: https://drive.google.com/file/d/1qXNoLG6KtyVwZ86UaxzMx091WhqmHucX/view
Flutter Logs: https://drive.google.com/file/d/11bUyfH0fEo-YN2GdlWwSWgA16-88YtR6/view?usp=share_link
Camera.dart complete code: https://drive.google.com/file/d/1HGYOMYcNrEOK6rH_QpiCd9cXM1w-Cjws/view?usp=sharing
Any help would be appreciated.
Thanks in advance.

@manmmohanIntello
Please provide flutter doctor -v and the code sample in complete minimal reproducible format (ex: main.dart) that we can directly copy paste and run to verify.
Also, if you also could share the blurred images vs regular images as a result of this to properly address the issue.

Hi @darshankawar,
The code mentioned in the previous thread is giving us blur images in certain devices like One Plus 9 Pro, One Plus 7 Pro, RealMe 2 Pro etc.
Video link of the issue, flutter logs and the Complete Camera code is attached for reference.
Video showing the issue: https://drive.google.com/file/d/1qXNoLG6KtyVwZ86UaxzMx091WhqmHucX/view
Flutter Logs: https://drive.google.com/file/d/11bUyfH0fEo-YN2GdlWwSWgA16-88YtR6/view?usp=share_link
Camera.dart complete code: https://drive.google.com/file/d/1HGYOMYcNrEOK6rH_QpiCd9cXM1w-Cjws/view?usp=sharing

@manmmohanIntello
I can't access the google drive link as it asks for permission.
Also can you share details as which apis / OS are the listed devices are on ?
See this similar / related issue and check if it resembles with your case.

@darshankawar ,
I have provided the access of the drive link. Also, the issue is on devices ranges from Android 10, 11, 12 and 13 on various device.
The above issue which u have pointed is separate one where Camera Preview is blurred. In my case the Preview is fine. The issue is with the images which I click, those gets blurred in certain devices.

Hi @manmmohanIntello
Thanks for providing more information but your sample code is containing many 3rd plugins/packages (such as geolocator, image_cropper) that we may not verify if the issue belongs to the camera plugin or those plugins.
You may try camera sample code instead (and modify it if it's necessary) to see if the issue occurs.

Hi,
Thanks for the reply. I have tried the sample Camera code as well but it was also showing error. I have found a solution. Upgraded the resolution from Medium to High and now the images are appearing fine in all the devices in which we have tested the code.
So, I am marking this issue as resolved.

authors: darshankawar huycozy manmmohanIntello


text:
Network resources (the doctor check crashed)

Is there an existing issue for this?

[X] I have searched the existing issues
[X] I have read the guide to filing a bug

Steps to reproduce
Flutter upgrade to 3.10.0
flutter doctor
Actual results

Logs

Logs

<!-- Paste your logs here -->

Flutter Doctor output

Doctor output

<!-- Paste your output here -->

This issue seems related to your network, please ensure you have a working internet connection.
There is a checklist you can use for this:

[ ]  Is the network stable and fast?
[ ]  Do you use any proxy server?
[ ]  It may be useful for troubleshooting the issue: https://dart.dev/tools/pub/troubleshoot#pub-get-fails-from-behind-a-corporate-firewall


text:
embedding Mac frameworks crashes with an exception

Is there an existing issue for this?

[X] I have searched the existing issues
[X] I have read the guide to filing a bug

Steps to reproduce

create a basic flutter app: flutter create basic_app
from the flutter app, build mac frameworks: flutter build macos-framework
create an XCode app
insert the two previously built frameworks (FlutterMacOS & App) to the XCode app (I had to add an explicit copy step to codesign the added frameworks)
add a Swift Window class with the skeleton described in FlutterViewController.h (example code below)
in the storyboard, assign the above window class to the main window
try to run the XCode app; it will stop with an exception where the FlutterViewController is created

I tried the same thing with a previous flutter version (iirc, ca. 2 months ago) and back then it worked as expected. I'm using the latest MacOS (13.4) and the latest XCode (14.3), but the same happened with an older MacOS (12.x)
Expected results
FlutterViewController being created without exception
Actual results
When creating the view controller (let flutterViewController = FlutterViewController()), an exception is raised and the program stops. The exception says
"-[MacApp4.AppDelegate setTerminationHandler:]: unrecognized selector sent to instance 0x600003c3c000"
Code sample
Code sample
import Cocoa
import FlutterMacOS

class MainFlutterWindow: NSWindow {
  override func awakeFromNib() {
    let flutterViewController = FlutterViewController()
    let windowFrame = self.frame
    self.contentViewController = flutterViewController
    self.setFrame(windowFrame, display: true)

    //RegisterGeneratedPlugins(registry: flutterViewController)

    super.awakeFromNib()
  }
}

Screenshots or Video

Screenshots / Video demonstration
[Upload media here]

Logs
Logs
[Paste your logs here]

Flutter Doctor output
Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.1, on macOS 13.4 22F66 darwin-x64, locale de-DE)
[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
[✓] Chrome - develop for the web
[!] Android Studio (not installed)
[✓] VS Code (version 1.78.2)
[✓] Connected device (2 available)
[✓] Network resources

! Doctor found issues in 2 categories.

Hi @woolfman007
Can you please share the complete sample project? It would be appreciated if you could push it into a GitHub repository so we can pull and try reproducing it. Thank you!

sure, here you go:
https://github.com/woolfman007/flutter_framework_embedding.git
Just clone, run flutter build macos-framework in the flutter project folder, then run the XCode project. I'm trying that on an Intel Mac, haven't tried it on silicon yet.

Thank you for providing the complete sample. I can see the issue as well.
Taking a look at the error message, it seems to be similar to https://github.com/flutter/flutter/issues/124829, Steps to reproduce are not the same, though.
Also, I checked this on Flutter 3.7.12 but it had another crash. Do you remember which Flutter version the issue doesn't happen?

Hi huycozy, the actual project is on a different machine, which is a little tricky to access right now; however, I have the resp. pubspec.yaml at hand. There it says:
  sdk: ">=2.17.0 <3.0.0" ```

So, it seems it's pre-3.0 Does that help in any way?

Thanks for your response.
Per https://github.com/flutter/flutter/issues/124829#issuecomment-1509312490, that issue doesn't happen on stable 3.7.11 but still on beta and master. Keeping this open for further insights.
Flutter stable & master: unrecognized selector sent to instance

crash stack
2023-05-26 11:33:21.381895+0700 MacApp4[76733:12245020] -[MacApp4.AppDelegate setTerminationHandler:]: unrecognized selector sent to instance 0x6000028901a0
2023-05-26 11:33:21.397660+0700 MacApp4[76733:12245020] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MacApp4.AppDelegate setTerminationHandler:]: unrecognized selector sent to instance 0x6000028901a0'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007ff81a53743b __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x00007ff81a086e25 objc_exception_throw + 48
	2   CoreFoundation                      0x00007ff81a5ce56b -[NSObject(NSObject) __retain_OA] + 0
	3   CoreFoundation                      0x00007ff81a4a169b ___forwarding___ + 1324
	4   CoreFoundation                      0x00007ff81a4a10d8 _CF_forwarding_prep_0 + 120
	5   FlutterMacOS                        0x00000001072d610d -[FlutterEngineTerminationHandler initWithEngine:terminator:] + 237
	6   FlutterMacOS                        0x00000001072d7390 -[FlutterEngine initWithName:project:allowHeadlessExecution:] + 496
	7   FlutterMacOS                        0x00000001072f6d04 _ZL10CommonInitP21FlutterViewControllerP13FlutterEngine + 116
	8   FlutterMacOS                        0x00000001072f70fe -[FlutterViewController initWithNibName:bundle:] + 126
	9   MacApp4                             0x0000000101639f73 $sSo21FlutterViewControllerCABycfcTO + 19
	10  MacApp4                             0x0000000101639b9f $sSo21FlutterViewControllerCABycfC + 31
	11  MacApp4                             0x0000000101639989 $s7MacApp417MainFlutterWindowC12awakeFromNibyyF + 89
	12  MacApp4                             0x0000000101639bec $s7MacApp417MainFlutterWindowC12awakeFromNibyyFTo + 28
	13  CoreFoundation                      0x00007ff81a4b3976 -[NSSet makeObjectsPerformSelector:] + 231
	14  AppKit                              0x00007ff81d5bef17 -[NSIBObjectData nibInstantiateWithOwner:options:topLevelObjects:] + 1367
	15  AppKit                              0x00007ff81d634f9b -[NSNib _instantiateNibWithExternalNameTable:options:] + 656
	16  AppKit                              0x00007ff81d634c16 -[NSNib _instantiateWithOwner:options:topLevelObjects:] + 143
	17  AppKit                              0x00007ff81de53e0f -[NSStoryboard _instantiateControllerWithIdentifier:creator:storyboardSegueTemplate:sender:] + 470
	18  AppKit                              0x00007ff81d5a5010 NSApplicationMain + 745
	19  MacApp4                             0x000000010163a2b4 $sSo21NSApplicationDelegateP6AppKitE4mainyyFZ + 36
	20  MacApp4                             0x000000010163a287 $s7MacApp411AppDelegateC5$mainyyFZ + 39
	21  MacApp4                             0x000000010163a318 main + 24
	22  dyld                                0x00007ff81a0b3310 start + 2432
)
2023-05-26 11:33:21.398180+0700 MacApp4[76733:12245020] [General] An uncaught exception was raised
2023-05-26 11:33:21.398236+0700 MacApp4[76733:12245020] [General] -[MacApp4.AppDelegate setTerminationHandler:]: unrecognized selector sent to instance 0x6000028901a0
2023-05-26 11:33:21.398322+0700 MacApp4[76733:12245020] [General] (
	0   CoreFoundation                      0x00007ff81a53743b __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x00007ff81a086e25 objc_exception_throw + 48
	2   CoreFoundation                      0x00007ff81a5ce56b -[NSObject(NSObject) __retain_OA] + 0
	3   CoreFoundation                      0x00007ff81a4a169b ___forwarding___ + 1324
	4   CoreFoundation                      0x00007ff81a4a10d8 _CF_forwarding_prep_0 + 120
	5   FlutterMacOS                        0x00000001072d610d -[FlutterEngineTerminationHandler initWithEngine:terminator:] + 237
	6   FlutterMacOS                        0x00000001072d7390 -[FlutterEngine initWithName:project:allowHeadlessExecution:] + 496
	7   FlutterMacOS                        0x00000001072f6d04 _ZL10CommonInitP21FlutterViewControllerP13FlutterEngine + 116
	8   FlutterMacOS                        0x00000001072f70fe -[FlutterViewController initWithNibName:bundle:] + 126
	9   MacApp4                             0x0000000101639f73 $sSo21FlutterViewControllerCABycfcTO + 19
	10  MacApp4                             0x0000000101639b9f $sSo21FlutterViewControllerCABycfC + 31
	11  MacApp4                             0x0000000101639989 $s7MacApp417MainFlutterWindowC12awakeFromNibyyF + 89
	12  MacApp4                             0x0000000101639bec $s7MacApp417MainFlutterWindowC12awakeFromNibyyFTo + 28
	13  CoreFoundation                      0x00007ff81a4b3976 -[NSSet makeObjectsPerformSelector:] + 231
	14  AppKit                              0x00007ff81d5bef17 -[NSIBObjectData nibInstantiateWithOwner:options:topLevelObjects:] + 1367
	15  AppKit                              0x00007ff81d634f9b -[NSNib _instantiateNibWithExternalNameTable:options:] + 656
	16  AppKit                              0x00007ff81d634c16 -[NSNib _instantiateWithOwner:options:topLevelObjects:] + 143
	17  AppKit                              0x00007ff81de53e0f -[NSStoryboard _instantiateControllerWithIdentifier:creator:storyboardSegueTemplate:sender:] + 470
	18  AppKit                              0x00007ff81d5a5010 NSApplicationMain + 745
	19  MacApp4                             0x000000010163a2b4 $sSo21NSApplicationDelegateP6AppKitE4mainyyFZ + 36
	20  MacApp4                             0x000000010163a287 $s7MacApp411AppDelegateC5$mainyyFZ + 39
	21  MacApp4                             0x000000010163a318 main + 24
	22  dyld                                0x00007ff81a0b3310 start + 2432
)
libc++abi: terminating with uncaught exception of type NSException
(lldb)

flutter doctor -v (stable and master)
[✓] Flutter (Channel stable, 3.10.2, on macOS 13.0.1 22A400 darwin-x64, locale en-VN)
    • Flutter version 3.10.2 on channel stable at /Users/huynq/Documents/GitHub/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 9cd3d0d9ff (22 hours ago), 2023-05-23 20:57:28 -0700
    • Engine revision 90fa3ae28f
    • Dart version 3.0.2
    • DevTools version 2.23.1

[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
    • Android SDK at /Users/huynq/Library/Android/sdk
    • Platform android-33, build-tools 32.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.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E222b
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.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
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] VS Code (version 1.78.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.64.0

[✓] Connected device (3 available)
    • RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64  • Android 11 (API 30)
    • macOS (desktop)  • macos            • darwin-x64     • macOS 13.0.1 22A400 darwin-x64
    • Chrome (web)     • chrome           • web-javascript • Google Chrome 113.0.5672.126

[✓] Network resources
    • All expected network resources are available.

• No issues found!

[!] Flutter (Channel master, 3.11.0-14.0.pre.26, on macOS 13.0.1 22A400 darwin-x64, locale en-VN)
    • Flutter version 3.11.0-14.0.pre.26 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 6c2041e1e9 (54 minutes ago), 2023-05-25 22:17:26 -0400
    • Engine revision 593d4d6b1f
    • Dart version 3.1.0 (build 3.1.0-147.0.dev)
    • DevTools version 2.23.1
    • 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 32.0.0)
    • Android SDK at /Users/huynq/Library/Android/sdk
    • Platform android-33, build-tools 32.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.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E222b
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.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
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] VS Code (version 1.78.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.64.0

[✓] Connected device (3 available)
    • RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64  • Android 11 (API 30)
    • macOS (desktop)  • macos            • darwin-x64     • macOS 13.0.1 22A400 darwin-x64
    • Chrome (web)     • chrome           • web-javascript • Google Chrome 113.0.5672.126

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.

Flutter 3.3.10 & 3.7.12: Out of memory

crash stack
2023-05-26 11:30:03.376563+0700 MacApp4[75889:12237263] Metal API Validation Enabled
Exhausted heap space, trying to allocate 32 bytes.
../../third_party/dart/runtime/vm/object.cc: 2727: error: Out of memory.
version=2.18.6 (stable) (Tue Dec 13 21:15:14 2022 +0000) on "macos_x64"
pid=75889, thread=259, isolate_group=vm-isolate(0x7f896689fc00), isolate=vm-isolate(0x7f89668a4800)
isolate_instructions=110e9d180, vm_instructions=110e9d180
  pc 0x0000000110ffb185 fp 0x00007ff7b5163770 dart::Profiler::DumpStackTrace(void*)+0x85
  pc 0x0000000110e9d394 fp 0x00007ff7b5163850 dart::Assert::Fail(char const*, ...) const+0x84
  pc 0x0000000110f72cfe fp 0x00007ff7b51638a0 dart::Object::Allocate(long, long, dart::Heap::Space, bool)+0x12e
  pc 0x0000000110fa2d70 fp 0x00007ff7b5163910 dart::Code::FinalizeCode(dart::FlowGraphCompiler*, dart::compiler::Assembler*, dart::Code::PoolAttachment, bool, dart::CodeStatistics*)+0xc0
  pc 0x0000000110fa31cf fp 0x00007ff7b5163940 dart::Code::FinalizeCodeAndNotify(char const*, dart::FlowGraphCompiler*, dart::compiler::Assembler*, dart::Code::PoolAttachment, bool, dart::CodeStatistics*)+0x2f
  pc 0x000000011107de18 fp 0x00007ff7b5163a80 dart::StubCode::Generate(char const*, dart::compiler::ObjectPoolBuilder*, void (*)(dart::compiler::Assembler*))+0xb8
  pc 0x000000011107dcc0 fp 0x00007ff7b5163b30 dart::StubCode::Init()+0xd0
  pc 0x0000000110ee862f fp 0x00007ff7b5164160 dart::Dart::DartInit(Dart_InitializeParams const*)+0x4df
  pc 0x0000000110ee88f1 fp 0x00007ff7b5164180 dart::Dart::Init(Dart_InitializeParams const*)+0x31
  pc 0x0000000110e5955d fp 0x00007ff7b51642e0 DartVMInitializer::Initialize(Dart_InitializeParams*, bool, bool)+0x2d
  pc 0x0000000110e58157 fp 0x00007ff7b5164500 flutter::DartVM::DartVM(std::__1::shared_ptr<flutter::DartVMData const>, std::__1::shared_ptr<flutter::IsolateNameServer>)+0xbb7
  pc 0x0000000110e5746d fp 0x00007ff7b5164cb0 flutter::DartVM::Create(flutter::Settings, fml::RefPtr<flutter::DartSnapshot const>, fml::RefPtr<flutter::DartSnapshot const>, std::__1::shared_ptr<flutter::IsolateNameServer>)+0x12d
  pc 0x0000000110e5a0d2 fp 0x00007ff7b5165460 flutter::DartVMRef::Create(flutter::Settings, fml::RefPtr<flutter::DartSnapshot const>, fml::RefPtr<flutter::DartSnapshot const>)+0x232
  pc 0x0000000110cb8644 fp 0x00007ff7b51662b0 flutter::Shell::Create(flutter::PlatformData const&, flutter::TaskRunners, flutter::Settings, std::__1::function<std::__1::unique_ptr<flutter::PlatformView, std::__1::default_delete<flutter::PlatformView> > (flutter::Shell&)> const&, std::__1::function<std::__1::unique_ptr<flutter::Rasterizer, std::__1::default_delete<flutter::Rasterizer> > (flutter::Shell&)> const&, bool)+0x144
  pc 0x0000000110e868ba fp 0x00007ff7b5166ac0 flutter::EmbedderEngine::LaunchShell()+0x9a
  pc 0x0000000110e705fb fp 0x00007ff7b5166c00 FlutterEngineRunInitialized+0x17b
  pc 0x00000001105bc07b fp 0x00007ff7b5166f60 -[FlutterEngine runWithEntrypoint:]+0x6eb
  pc 0x00000001105d91a4 fp 0x00007ff7b5166f90 -[FlutterViewController launchEngine]+0x54
  pc 0x00000001105d8f35 fp 0x00007ff7b5166fc0 -[FlutterViewController viewWillAppear]+0x65
  pc 0x00007ff81d70c08c fp 0x00007ff7b5166fe0 -[NSViewController _sendViewWillAppear]+0x28
  pc 0x00007ff81d70bf4d fp 0x00007ff7b5167010 -[NSViewController _windowWillOrderOnScreen]+0x62
  pc 0x00007ff81df123c9 fp 0x00007ff7b5167110 -[NSView _windowWillOrderOnScreen]+0x43
  pc 0x00007ff81df1245f fp 0x00007ff7b5167210 -[NSView _windowWillOrderOnScreen]+0xd9
  pc 0x00007ff81d70bdd6 fp 0x00007ff7b5167240 -[NSWindow _doWindowWillBeVisibleAsSheet:]+0x3b
  pc 0x00007ff81df2a7b1 fp 0x00007ff7b5167360 -[NSWindow _reallyDoOrderWindowAboveOrBelow:]+0x53a
  pc 0x00007ff81df2b413 fp 0x00007ff7b5167390 -[NSWindow _reallyDoOrderWindow:]+0x63
  pc 0x00007ff81df2b689 fp 0x00007ff7b5167450 -[NSWindow _doOrderWindow:]+0x127
  pc 0x00007ff81d6ff62a fp 0x00007ff7b5167470 -[NSWindow makeKeyAndOrderFront:]+0x2f
  pc 0x00007ffa361d180a fp 0x00007ff7b51674f0 -[QLSeamlessDocumentOpener showWindow:contentFrame:withBlock:]+0xa9
  pc 0x00007ff81d802900 fp 0x00007ff7b51675a0 -[NSWindowController showWindow:]+0x2a0
  pc 0x00007ff81d5a510c fp 0x00007ff7b51675f0 NSApplicationMain+0x3e5
  pc 0x000000010ad9c2b4 fp 0x00007ff7b5167610 $sSo21NSApplicationDelegateP6AppKitE4mainyyFZ+0x24
  pc 0x000000010ad9c287 fp 0x00007ff7b5167630 $s7MacApp411AppDelegateC5$mainyyFZ+0x27
  pc 0x000000010ad9c318 fp 0x00007ff7b5167650 main+0x18
  pc 0x00007ff81a0b3310 fp 0x00007ff7b51678f0 start+0x980
-- End of DumpStackTrace
(lldb)

Hi @huycozy,
thanks very much for your investigations. Does that mean, that it'll work on 3.7.11? I'll check that. Otherwise, will there be a fix?

Does that mean, that it'll work on 3.7.11?

@woolfman007 No, this issue still appears as I mentioned above (Out of memory error). I mean issue #124829 didn't appear on 3.7.11.
What I am summarizing above is: there is a difference between the two issues on Flutter versions (for some specific reason that needs further investigation). The error message on the latest version can be seen to be similar, though (unrecognized selector sent to instance). Hope this explanation is more clear :)

@huycozy thanks for the clarification. I just made a test with 2.13 and also encountered the out of memory issue. Can you tell when there might be a fix? I'm facing a major strategic decision in this regarding the product I'm building...

@woolfman007 Please see https://github.com/flutter/flutter/wiki/Issue-hygiene#when-will-my-bug-be-fixed

This looks like your app delegate isn't extending FlutterAppDelegate.  If you extend that, then it should support the missing selector.

@woolfman007 I have the same use case as you, running Flutter as a plug-in hosted in another app. I figured out a workaround for the time being. But it would be nice if Flutter would check if the app delegate responds to the selector before invoking it.
Workaround:

void setTerminationHandler_(_Nonnull id self, _Nonnull SEL cmd, _Nullable id handler) {
    // We don't need to handle termination.
}

/// Makes the current NSApplication's delegate understand the selector "setTerminationHandler:". Flutter calls this on initialization and fails
/// if the app delegate doesn't understand it (https://github.com/flutter/flutter/issues/124829#issuecomment-1608228991).
/// Host app delegate doesn't understand it of course, so we need to add it on-the-fly. The handler doesn't need to do anything in our case.
NS_INLINE void modifyAppDelegate() {
    Class appDelegateClass = [[[NSApplication sharedApplication] delegate] class];
    const SEL selector = @selector(setTerminationHandler:);
    if ([appDelegateClass instancesRespondToSelector:selector]) {
        printf("Modifying app delegate was not necessary");
        return;
    }
    printf("Modifying the app delegate...\n");
    class_addMethod(appDelegateClass, selector, (IMP)setTerminationHandler_, "v@:@");
}

@woolfman007 I have the same use case as you, running Flutter as a plug-in hosted in another app. I figured out a workaround for the time being. But it would be nice if Flutter would check if the app delegate responds to the selector before invoking it.
Workaround:
void setTerminationHandler_(_Nonnull id self, _Nonnull SEL cmd, _Nullable id handler) {
    // We don't need to handle termination.
}

/// Makes the current NSApplication's delegate understand the selector "setTerminationHandler:". Flutter calls this on initialization and fails
/// if the app delegate doesn't understand it (https://github.com/flutter/flutter/issues/124829#issuecomment-1608228991).
/// Host app delegate doesn't understand it of course, so we need to add it on-the-fly. The handler doesn't need to do anything in our case.
NS_INLINE void modifyAppDelegate() {
    Class appDelegateClass = [[[NSApplication sharedApplication] delegate] class];
    const SEL selector = @selector(setTerminationHandler:);
    if ([appDelegateClass instancesRespondToSelector:selector]) {
        printf("Modifying app delegate was not necessary");
        return;
    }
    printf("Modifying the app delegate...\n");
    class_addMethod(appDelegateClass, selector, (IMP)setTerminationHandler_, "v@:@");
}

phantastic, thanks for sharing! It seems to be a viable workaround for now! Still let's hope they provide a real fix soon

I am working on a "real" fix in this PR: https://github.com/flutter/engine/pull/43425

oh, brilliant! I missed that you already mentioned that. Thanks so much!

authors: gspencergoog helgoboss huycozy woolfman007


text:
[image_picker] image_picker: ^1.0.1 image rotation issue

Is there an existing issue for this?

[X] I have searched the existing issues
[X] I have read the guide to filing a bug

Steps to reproduce
Pick up photos and see the cache results.
The preview is displayed correctly, but the image in memory has been rotated with image_picker: ^1.0.1
(the same problem occurs in both Android and IOS)
This happens with a few pictures.
Expected results
Keep the correct orientation of the image.
I use this image to push to the server, so the original orientation of the image should be correct.
Actual results
The image was automatically rotated
Code sample
Code sample
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  XFile? _xFile;

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            if (_xFile != null) Image.file(File(_xFile?.path ?? '')),
            TextButton(
              onPressed: () async {
                final image =
                    await ImagePicker().pickImage(source: ImageSource.gallery);
                if (image != null) {
                  setState(() {
                    _xFile = image;
                  });
                }
              },
              child: const Text('Pick Image'),
            ),
          ],
        ),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration
https://github.com/flutter/flutter/assets/53120409/306399d8-97b0-4d71-8930-296649341ba8
[The image has an error]

Logs
Logs
[Paste your logs here]

Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.10.5, on macOS 13.4 22F66 darwin-arm64, locale en-VN)
    • Flutter version 3.10.5 on channel stable at /Users/cuong.nv2/fvm/versions/3.10.5
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 796c8ef792 (7 weeks ago), 2023-06-13 15:51:02 -0700
    • Engine revision 45f6e00911
    • Dart version 3.0.5
    • DevTools version 2.23.1

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/cuong.nv2/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E300c
    • CocoaPods version 1.12.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.1)
    • 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 11.0.15+0-b2043.56-8887301)

[✓] Connected device (5 available)
    • SM A536E (mobile)           • R5CT43S52SD                          • android-arm64  • Android 12 (API 31)
    • sdk gphone64 arm64 (mobile) • emulator-5554                        • android-arm64  • Android 13 (API 33) (emulator)
    • iPhone Xʀ (mobile)          • 94A1EBEC-51FB-4B71-8ED6-C876D62CFE30 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator)
    • macOS (desktop)             • macos                                • darwin-arm64   • macOS 13.4 22F66 darwin-arm64
    • Chrome (web)                • chrome                               • web-javascript • Google Chrome 115.0.5790.114

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Hi @CuongNV12. Thanks for filing this issue, I can't seem to reproduce this issue on the latest stable channel. Can you upgrade to the latest version to confirm if this issue still persists?

The image may contain EXIF data, which records the image's orientation. While some software, like Android Studio's Device File Explorer, may not respect this EXIF orientation, Flutter correctly rotates the image in the same way that Android's file picker does.
You can use the https://pub.dev/packages/exif package to confirm whether the image is originally in landscape mode, even though the EXIF data may rotate it.

Hi @CuongNV12. Thanks for filing this issue, I can't seem to reproduce this issue on the latest stable channel. Can you upgrade to the latest version to confirm if this issue still persists?

I've used flutter sdk 3.10.6 in stable channel and image_picker: ^1.0.1 but the problem still occurs.
You can use below image to reproduce this issue.
https://user-images.githubusercontent.com/53120409/258004351-dda26e7f-6325-4d85-a484-bde65f6b8a70.jpg
Doctor output
[✓] Flutter (Channel stable, 3.10.6, on macOS 13.4 22F66 darwin-arm64, locale en-VN)
    • Flutter version 3.10.6 on channel stable at /Users/cuong.nv2/fvm/versions/3.10.6
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision f468f3366c (3 weeks ago), 2023-07-12 15:19:05 -0700
    • Engine revision cdbeda788a
    • Dart version 3.0.6
    • DevTools version 2.23.1
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
• Android SDK at /Users/cuong.nv2/Library/Android/sdk
• Platform android-33, build-tools 33.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 14E300c
• CocoaPods version 1.12.1
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2022.1)
• 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 11.0.15+0-b2043.56-8887301)
[✓] Connected device (4 available)
• sdk gphone64 arm64 (mobile) • emulator-5554                        • android-arm64  • Android 13 (API 33) (emulator)
• iPhone Xʀ (mobile)          • 94A1EBEC-51FB-4B71-8ED6-C876D62CFE30 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator)
• macOS (desktop)             • macos                                • darwin-arm64   • macOS 13.4 22F66 darwin-arm64
• Chrome (web)                • chrome                               • web-javascript • Google Chrome 115.0.5790.170
[✓] Network resources
• All expected network resources are available.
• No issues found!

The image may contain EXIF data, which records the image's orientation. While some software, like Android Studio's Device File Explorer, may not respect this EXIF orientation, Flutter correctly rotates the image in the same way that Android's file picker does.
You can use the https://pub.dev/packages/exif package to confirm whether the image is originally in landscape mode, even though the EXIF data may rotate it.

This is EXIF data.

While some software, like Android Studio's Device File Explorer, may not respect this EXIF orientation

It doesn't seem to be the fault of Android Studio Device File Explorer. because i used this file to send to the server, after getting the image url and displaying, the image still shows like Android Studio Device File Explorer does.

Hi @CuongNV12. Thanks for the detailed explanation. Using the image you shared, I can see from the EXIF data that it's rotated 90.
{Image ImageWidth: 600, Image ImageLength: 398, Image ExifOffset: 62, Image Orientation: Rotated 90 CCW, EXIF LightSource: Unknown}

Checking the downloaded file from the device, I see the correct image but viewing the Downloads folder via Android Studio Device File Explorer, I see the image rotated, hence this might stand.

While some software, like Android Studio's Device File Explorer, may not respect this EXIF orientation

It seems to be a display error of Android Studio Device File Explorer, and our fie uploader.
Thank you for supporting me!


text:
Running flutter config shows analytics as always disabled

Is there an existing issue for this?

[X] I have searched the existing issues
[X] I have read the guide to filing a bug

Steps to reproduce

Run flutter --disable-telemetry to disable telemetry (it should say Analytics reporting disabled.)
Run flutter config to see the current status of analytics opt in (it should sayAnalytics reporting is currently disabled. at the bottom)
Run flutter --enable-telemetry to re-enable it, it should say (it should say `Analytics reporting enabled.)
Run flutter config again... it still says Analytics reporting is currently disabled. at the bottom even though the configuration files say it is enabled

Expected results
It should report the current state of opt in
Actual results
It is always saying the user is opted out, even after enabling it again
Code sample
Code sample
[Paste your code here]

Screenshots or Video

Screenshots / Video demonstration
[Upload media here]

Logs
Logs
[Paste your logs here]

Flutter Doctor output
Doctor output
[!] Flutter (Channel [user-branch], 3.13.0-18.0.pre.37, on macOS 13.5 22G74 darwin-arm64, locale en)
    ! Flutter version 3.13.0-18.0.pre.37 on channel [user-branch] at /Users/eliasyishak/Desktop/flutter
      Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
      If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.
    ! Upstream repository https://github.com/christopherfujino/flutter.git is not a standard remote.
      Set environment variable "FLUTTER_GIT_URL" to https://github.com/christopherfujino/flutter.git to dismiss this error.
    • Framework revision 1a734750e5 (6 days ago), 2023-08-03 10:45:49 -0700
    • Engine revision 4cc0b3dab0
    • Dart version 3.2.0 (build 3.2.0-33.0.dev)
    • DevTools version 2.26.1
    • 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 33.0.0)
    • Android SDK at /Users/eliasyishak/Library/Android/sdk
    • Platform android-33, build-tools 33.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.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E300c
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.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
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1.3)
    • IntelliJ at /Users/eliasyishak/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.9161.38/IntelliJ IDEA.app
    • 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

[✓] VS Code (version 1.81.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.70.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.5 22G74 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 115.0.5790.170

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.

This is my mistake, this is not a bug.  This is working as intended when you're on a feature branch per the logic found here
The conditional check here is triggered because my version begins with [user-branch] so the flutter tool automatically suppressed analytics which resulted in the Analytics reporting is currently disabled. being printed when running flutter config
It works as expected when running it from the master/main channel.
fyi @Hixie

That makes sense. Can we make the message say why telemetry is disabled? Since both you and I got confused about it we're probably not the only ones. :-)

@CoderDake This might make a good tool starter bug. Feel free to reach out to @eliasyishak if you need more context.

authors: Hixie christopherfujino eliasyishak


text:
scaffoldKey.currentState.showBottomSheet  quite different from  showModalBottomSheet

I have a hard time understanding why the API is not more symmetrical and easier to use  for showing a
Modal or not Modal Bottom sheet. I like the straight forward approach under 2. for the Modal Bottom sheet. Why is there not a same for the non Modal?

      new InkWell(
            onLongPress: () {
                HomeScreen.scaffoldKey.currentState.showBottomSheet<Null>(
                  (context) => createBottomSheet(context, appController));
            },

      new InkWell(
            onLongPress: () {
              showModalBottomSheet<Null>(
                  context: context,
                  builder: (context) =>
                      createBottomSheet(context, appController));
            },

[√] Flutter (on Microsoft Windows [Version 10.0.16299.64], locale en-US, channel alpha)
• Flutter at c:\sdks\flutter
• Framework revision e8aa40eddd (6 weeks ago), 2017-10-17 15:42:40 -0700
• Engine revision 7c4142808c
• Tools Dart version 1.25.0-dev.11.0
[√] Android toolchain - develop for Android devices (Android SDK 27.0.1)
• Android SDK at C:\Users\ride4\AppData\Local\Android\sdk
• Platform android-27, build-tools 27.0.1
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-915-b01)
[√] Android Studio (version 3.0)
• Android Studio at C:\Program Files\Android\Android Studio
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-915-b01)
[√] IntelliJ IDEA Community Edition (version 2017.2)
• Flutter plugin version 19.1
• Dart plugin version 172.4343.25
[√] Connected devices
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 7.1.1 (API 25) (emulator)

Good point.


text:
Regression in web size

SkiaPerf is reporting a regression in web app size:
https://flutter-flutter-perf.skia.org/e/?begin=1696393467&end=1697646347&keys=X5fca5a031b9159f9008ccc2a5e12abae&requestType=0&selected=commit%3D37453%26name%3D%252Carch%253Dintel%252Cbranch%253Dmaster%252Cconfig%253Ddefault%252Cdevice_type%253Dnone%252Cdevice_version%253Dnone%252Chost_type%253Dlinux%252Csub_result%253Dhello_world_web_build_dir_compressed_bytes%252Ctest%253Dweb_size__compile_test%252C&xbaroffset=37451
Guessing it's due to https://github.com/flutter/engine/pull/46973, and that this might be intentional, but filing this issue just in case
cc @eyebrowsoffire @yjbanov

Yep, that's expected. Thanks for flagging it, I think we can close.

authors: eyebrowsoffire zanderso


text:
Dashboard/Cocoon is down

PR status checks aren't completing, which is blocking the re-opening of the tree.
https://www.google.com/url?sa=j&url=https%3A%2F%2Fgithub.com%2Fflutter%2Fflutter%2Fpull%2F141689%23issuecomment-1896139364&uct=1702503458&usg=SMf_YpWvr_s3OMonTmHKg5l2ENs.&opi=73833047&source=chat

Seems to be back!


text:
How can I change the Cursor Color of the Textfield independent of the Primary color

Steps to Reproduce
The cursor seems to default to the primary color as well as the drag handles of a textfield.
The primary color is sometimes very hard to see above a white background and I would like to change it for certain themes. I could not find a theme setting to do so.
Flutter Doctor
C:\Pojects\lambDev\lookatmybaby_flutter>flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (on Microsoft Windows [Version 10.0.16299.214], locale en-US, channe
l dev)
[√] Android toolchain - develop for Android devices (Android SDK 27.0.2)
[√] Android Studio (version 3.0)
[√] IntelliJ IDEA Community Edition (version 2017.2)
[√] VS Code (version 1.20.0)
[√] Connected devices

• No issues found!

This solved the problem for me (see #10063): add textSelectionColor: Colors.black to the ThemeData when calling the constructor of MaterialApp at the very "top" of the app.

@ride4sun Does @dsteinkopf's solution work for you?

@Hixie thanks that's working.
#15571 is related.

They have already provided cursorColor property in ThemeData

Does not seems to work on my iOS device, but is working on my Android.
Should it be working ?
Flutter version stable 1.2.1

@g-balas
This should work well.
MaterialApp(
  title: "Rate your Colleagues",
  theme: ThemeData(
    cupertinoOverrideTheme: CupertinoThemeData(
      primaryColor: Colors.red,
    ),
    cursorColor: Colors.red,
    home: SplashScreen(),
  );

TextFormField(
cursorColor: Colors.yellow,
    )

Step By Step Guide to flutter textfield background color on focus

Step By Step Guide to flutter textfield background color on focus

return MaterialApp(
theme: ThemeData(
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.orange
)
),

authors: Hixie dsteinkopf flutterq g-balas hadasacwebit mono0926 napoettker ride4sun unnatishah96 zoechi


text:
Please update web package in shared_preferences_web to 1.0.0. It's incompatible with latest auto_route version. Currently shared_preferences using shared_preferences_web which depends on  web ^0.5.0. They are conflicting. Please fix it asap

Steps to reproduce

Install latest version of shared_preferences
Install latest version of auto_route

Expected results
Should run normally
Actual results
Conflicting because of "web" package(which is dependency of shared_preferences_web)
Code sample
Code sample
[Paste your code here]

Screenshots or Video

Screenshots / Video demonstration
[Upload media here]

Logs
Logs
[Paste your logs here]

Flutter Doctor output
Doctor output
[Paste your output here]

Closing this as a duplicate of https://github.com/flutter/flutter/issues/151981

This should get published in the next few hours.

authors: danagbemava-nc ditman esepai


text:
Add onChanged and autoPlay to CarouselView

Proposal
Carousel View should have autoPlay feature and onChanged, i know there is already onTap implemented.
Problem: I see some effect on ontap while elevation, background color and overlayColor is already transparent
   SizedBox(
          height: 200,
          width: double.infinity,
          child: CarouselView(
            itemExtent: double.infinity,
            backgroundColor: Colors.transparent,
            itemSnapping: true,
            onTap: null,
            overlayColor: WidgetStateProperty.resolveWith((state) => Colors.transparent),
            elevation: 0,
            controller: CarouselController(
              initialItem: 0,
            ),
            children:
                banners.map((uri) => TRoundedImage(imageUri: uri)).toList(),
          ),
        ),

"onChanged" please with the current Image Index.

ScrollNotifications can be used to listen for changes, and animating the view can be done using the animateTo method like other scrolling widgets.

autoPlay feature is must

suppose you've 3-4 items in the viewport by specifying itemExtent to be anything less than the device width. How do you expect onChanged should be fired.
Does it fire for one specific item, or collectively for items that are in view?

onChanged is must to

authors: Ayush783 Piinks berkbiyikci bharathwajv md-rifatkhan tschiekdev