flutter icon indicating copy to clipboard operation
flutter copied to clipboard

The program for Windows runs only once

Open AlexSensey opened this issue 1 year ago • 25 comments

Hello I decided to import the program for Windows, but a problem arose. The same problem with a new project that I create from scratch.

For me, after the build, the project from the folder (exe file) is launched only the first time. It does not start the next time, but there are processes in the task manager. exe debug file runs without problems. Created other projects from scratch, same problem. I tried to run it on other computers, and there, too, only the first run, then everything. After renaming the folder, it starts again and also once.

AlexSensey avatar Jan 28 '23 13:01 AlexSensey

And in general, it works somehow strangely, if you close it and wait, the program may start, sometimes it may not. Or it may not start but be in processes, and the other instance will start normally, and there may be several instances in the process.

AlexSensey avatar Jan 28 '23 15:01 AlexSensey

What's the output of flutter doctor?

What Windows version are you running?

codespearhead avatar Jan 29 '23 03:01 codespearhead

Screenshot 2023-01-29 124548 Screenshot 2023-01-29 124509

flutter doctor -v Screenshot 2023-01-29 130207

Hi The program starts, just in the release the window is not displayed and there are no errors. In debugging everything works fine. And this is on all applications, even on new ones.

AlexSensey avatar Jan 29 '23 10:01 AlexSensey

Added a line of code for debugging in the release - file win32_window.cpp MessageBox(NULL, L"Window ok", L"Title", MB_ICONINFORMATION);

everything starts without problems, only before starting each time a window appears with a message

HWND window = CreateWindow( window_class, title.c_str(), WS_OVERLAPPEDWINDOW, Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), Scale(size.width, scale_factor), Scale(size.height, scale_factor), nullptr, nullptr, GetModuleHandle(nullptr), this);

if (!window) { return false; } MessageBox(NULL, L"Window ok", L"Title", MB_ICONINFORMATION);

UpdateTheme(window);

return OnCreate(); }

AlexSensey avatar Jan 29 '23 12:01 AlexSensey

The flutter_window.cpp file does not always work

flutter_controller_->engine()->SetNextFrameCallback(& {
this->Show(); });

I still don't understand why

if called simply this->Show(); without using SetNextFrameCallback then everything works

AlexSensey avatar Jan 29 '23 13:01 AlexSensey

Triage report

I can reproduce this issue on Master (3.7.0-30.0.pre.7). Once you close the window, there still seems to be an open process in Task Manager. Manually ending the task doesn't solve the issue of the programming not opening again.

flutter doctor -v (Master)
[!] Flutter (Channel master, 3.7.0-30.0.pre.7, on Microsoft Windows [Version 10.0.22621.1105], locale en-US)
    • Flutter version 3.7.0-30.0.pre.7 on channel master at C:\Users\Nabeel\fvm\versions\master
    ! The flutter binary is not on your path. Consider adding C:\Users\Nabeel\fvm\versions\master\bin to your path.
    ! Warning: `dart` on your path resolves to C:\tools\dart-sdk\bin\dart.exe, which is not inside your current Flutter SDK checkout at C:\Users\Nabeel\fvm\versions\master. Consider adding C:\Users\Nabeel\fvm\versions\master\bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 15cd00f1ed (6 hours ago), 2023-01-29 21:58:05 -0500
    • Engine revision a7bb0e4108
    • Dart version 3.0.0 (build 3.0.0-179.0.dev)
    • DevTools version 2.20.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.

[✓] Windows Version (Installed version of Windows is version 10 or higher)

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at C:\android-sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: C:\Users\Nabeel\AppData\Local\JetBrains\Toolbox\apps\AndroidStudio\ch-0\213.7172.25.2113.9014738\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • CHROME_EXECUTABLE = C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe

[✓] Visual Studio - develop for Windows (Visual Studio Community 2022 17.4.2)
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.4.33122.133
    • Windows 10 SDK version 10.0.22621.0

[✓] Android Studio (version 2021.3)
    • Android Studio at C:\Users\Nabeel\AppData\Local\JetBrains\Toolbox\apps\AndroidStudio\ch-0\213.7172.25.2113.9014738
    • Flutter plugin version 70.2.3
    • Dart plugin version 213.7433
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] VS Code (version 1.74.3)
    • VS Code at C:\Users\Nabeel\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.46.0

[✓] VS Code (version 1.73.0-insider)
    • VS Code at C:\Users\Nabeel\AppData\Local\Programs\Microsoft VS Code Insiders
    • Flutter extension version 3.50.0

[✓] Connected device (3 available)
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.22621.1105]
    • Chrome (web)      • chrome  • web-javascript • unknown
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 109.0.1518.52

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

! Doctor found issues in 1 category.

exaby73 avatar Jan 30 '23 08:01 exaby73

When the program does not open, it is in the background tasks. And if everything is fine, then in Apps

I still don't understand why the program starts in different ways.

AlexSensey avatar Jan 30 '23 10:01 AlexSensey

I'm seeing the same problem. The dead tasks are sitting in the message loop, waiting for something to happen.

mikehearn avatar Jan 30 '23 16:01 mikehearn

The next frame callback is indeed not called when this happens, which I guess is about 50% of the time. It smells like a startup race. Maybe in release mode some code path gets a bit faster than normal and outruns the other. From reading the code my guess is that Rasterizer::DrawToSurfaceUnsafe fails but the return code is unfortunately discarded without being logged anywhere.

mikehearn avatar Jan 30 '23 16:01 mikehearn

cc @cbracken

chinmaygarde avatar Jan 30 '23 19:01 chinmaygarde

Unfortunately, we are having this issue in one of our store apps. You can download our app in Microsoft store and repro the issue.

Link: https://apps.microsoft.com/store/detail/senserver/9NHWV679JNQC?hl=en-us&gl=us

Try running the the app multiple times, it might show only once or never show up. I'm on windows 11.

[✓] Flutter (Channel stable, 3.7.4, on Microsoft Windows [Version 10.0.22621.1265], locale en-US)
[✓] Windows Version (Installed version of Windows is version 10 or higher)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
[✓] Chrome - develop for the web
[✓] Visual Studio - develop for Windows (Visual Studio Enterprise 2022 17.5.0)
[✓] Android Studio (version 2022.1)
[✓] VS Code (version 1.75.1)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

mgenware avatar Feb 22 '23 17:02 mgenware

Yes. It doesn't repro on debug mode or flutter run --release (which is how we tested apps in release mode and why we didn't catch this before releasing to public).

I can repro it on a newly created windows app.

Steps:

  • flutter create windows_app
  • Build the app in release mode flutter build windows
  • Go to .\build\windows\runner\Release
  • Click and run windows_app.exe multiple times

Now you have a bunch of window-less processes:

image

@exaby73 @chinmaygarde @cbracken Sorry for tagging you guys. Just wanted to get some attention, this seems like a big regression.

mgenware avatar Feb 22 '23 17:02 mgenware

One possible workaround for this is to revert to the last working SDK before 3.7.0, which is 3.3.10.

Then recreate your windows project:

  • Delete the windows project folder
  • Recreate a new one for 3.3.10 flutter create --org <org> --project-name <name> --platforms=windows .

Review your changes and rebuild windows in release mode. The problem should be gone.

mgenware avatar Feb 23 '23 15:02 mgenware

@mgenware Note that there's a simple workaround. Edit flutter_window.cpp and replace:

flutter_controller_->engine()->SetNextFrameCallback([&]{
this->Show();
});

with

this->Show();

mikehearn avatar Feb 24 '23 09:02 mikehearn

Thanks @mikehearn , that helps a lot!

mgenware avatar Feb 24 '23 10:02 mgenware

@mgenware You're welcome! In return I hope you don't mind if I hawk my wares to you a bit - you might find Conveyor a nice way to package and distribute your Flutter app to desktop users. At the moment it doesn't upload to the MS Store for you, but it could if that's a necessary feature and the UX is quite pleasant even outside the store.

mikehearn avatar Feb 24 '23 11:02 mikehearn

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(
      restorationScopeId: "desktop-demo1",
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

As shown in the code above, you must give a value to the 'restorationScopeId' field, otherwise the window will not be displayed. As for the reason, I am not very clear.

misaka19002 avatar Mar 23 '23 02:03 misaka19002

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(
      restorationScopeId: "desktop-demo1",
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

As shown in the code above, you must give a value to the 'restorationScopeId' field, otherwise the window will not be displayed. As for the reason, I am not very clear.

This should be stated in the documentation of Flutter. I wasted days only to figure out why the window is not displaying. Thank you for this hint though.

Shiyam23 avatar Mar 27 '23 10:03 Shiyam23

The sample/scaffolding app doesn't do that, so if it's required then it needs to be updated.

mikehearn avatar Mar 27 '23 10:03 mikehearn

Yup, this is causing all windows apps created from 3.7.x branch template to not run in release mode. Why is it still open after months baffles me.

mgenware avatar Mar 27 '23 11:03 mgenware

I don't quite understand why it only happens sometimes, if the cause is a missing api call. When I first looked at this it seemed more like a race condition.

mikehearn avatar Mar 27 '23 11:03 mikehearn

Hello

This bug still happens, i think it's serious one.

My workaround, in the file windows/runner/win32_window.cpp, rollback this line :

window_class, title.c_str(), WS_OVERLAPPEDWINDOW,

back to:

window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,

The problematic commit: https://github.com/flutter/flutter/commit/c60cf97c1904883accf43ad844d7ff11cf446846#diff-94cbb9b7f709182d95298fa42c4c3bbf24af03be9cd12a32cb941d62d663e2d0

YehudaKremer avatar Apr 29 '23 18:04 YehudaKremer

@loic-sharma https://github.com/flutter/flutter/pull/109816 Please take a look to see if there is a solution to this problem. It seems that the Flutter official team may not address it at the moment.

AoEiuV020 avatar May 11 '23 04:05 AoEiuV020

Thanks for tagging me, I'll investigate.

loic-sharma avatar May 12 '23 18:05 loic-sharma

Mike is right: there's a race condition between the Windows main thread and Flutter's threads. Flutter can render the first frame before the main thread has a chance to register the callback that shows the window after the first frame.

I can reproduce this using a debugger:

  1. Add a breakpoint on flutter::Shell::OnAnimatorDraw (that's when the Dart app renders something)
  2. Add a breakpoint in FlutterWindow::OnCreate where it sets the next frame callback
  3. Run the app using the debugger
  4. When the FlutterWindow::OnCreate breakpoint is hit, freeze the main thread
  5. Once the flutter:Shell::OnAnimatorDraw breakpoint has been hit twice, thaw the main thread

However, I haven't been able to reproduce this issue without a debugger. Do your apps have Windows plugins? Which ones? I suspect plugin initialization may be what's "slowing down" the main thread enough make it lose this race.

In any case, I'll work on a fix to remove this race condition.

loic-sharma avatar May 12 '23 23:05 loic-sharma

@loic-sharma you can use Windows 11 to create, build, and star the Flutter official demo called "counter". For example, you can create a project using the following command:

flutter create demo

Alternatively, you can use the binary program I packaged, which can be found at the following link:
https://github.com/AoEiuV020/FlutterDemo/releases/tag/3.7.7

Many people have reported reproducing this issue. It seems that the reproduction of this issue is tied to specific conditions. It may only occur on Windows 11 and specifically when running the binary program built with "flutter build". Additionally, it's worth noting that the official demo named "skeleton" does not exhibit this issue. The specific behavior is that the first launch is normal, but subsequent launches may not display the foreground window.

AoEiuV020 avatar May 14 '23 18:05 AoEiuV020

Thanks @AoEiuV020 for the link, I'm able to reproduce the issue with the app you shared! That'll help me verify the fix :)

loic-sharma avatar May 15 '23 22:05 loic-sharma

Hello, the Windows app template was fixed on the master channel by https://github.com/flutter/flutter/pull/127046. This fix will be available in the next non-hotfix Flutter release, likely Flutter 3.13 or higher.

Apps created using Flutter 3.7 or 3.10 will need to be migrated after they've upgraded to Flutter 3.13 or the master channel. This migration will be automatic if the Windows project has not been modified. If the Windows project has been modified, the following change can be applied to fix this bug:

diff --git a/examples/hello_world/windows/runner/flutter_window.cpp b/examples/hello_world/windows/runner/flutter_window.cpp
index f68aa9c26c0f5..7f66913a0293c 100644
--- a/examples/hello_world/windows/runner/flutter_window.cpp
+++ b/examples/hello_world/windows/runner/flutter_window.cpp
@@ -35,6 +35,11 @@ bool FlutterWindow::OnCreate() {
     this->Show();
   });
 
+  // Flutter can complete the first frame before the "show window" callback is
+  // registered. The following call ensures a frame is pending to ensure the
+  // window is shown. It is a no-op if the first frame hasn't completed yet.
+  flutter_controller_->ForceRedraw();
+
   return true;
 }

Warning The FlutterViewController::ForceRedraw API does not exist in Flutter 3.10. For now, you must switch to the the master channel to use this API. This API will be added in the next Flutter non-hotfix release, likely Flutter 3.13.

Note This migration will be done automatically if the Windows project has not been modified.

If needed, you can use this temporary workaround while on Flutter 3.10. This workaround will no longer be necessary once you upgrade to Flutter 3.13 or higher.

I'll close this issue as it is now fixed. Please let me know if you have any questions!

loic-sharma avatar May 30 '23 20:05 loic-sharma

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

github-actions[bot] avatar Jun 15 '23 19:06 github-actions[bot]