Skip to content

desktop_webview_window: fix crash on app exit on Windows - #557

Merged
boyan01 merged 2 commits into
MixinNetwork:mainfrom
tecarta:desktop_webview_window/windows-exit-crash
Nov 13, 2026
Merged

boyan01 merged 2 commits into
MixinNetwork:mainfrom
tecarta:desktop_webview_window/windows-exit-crash

Conversation

@mtallenca

Copy link
Copy Markdown
Contributor

Problem

On Windows, every app that registers the plugin crashes when its main window is closed, whether or not a webview was ever opened. It is an access violation (read at 0x1e8) inside flutter_windows.dll:

std::unique_ptr<T>::get
flutter::FlutterWindowsEngine::message_dispatcher   flutter_windows_engine.h:163
FlutterDesktopMessengerSetCallback                  flutter_windows.cc:444
flutter::BinaryMessengerImpl::SetMessageHandler     core_implementations.cc:120
flutter::MethodChannel<T>::SetMethodCallHandler     method_channel.h:101
WebviewWindowPlugin::~WebviewWindowPlugin           web_view_window_plugin.cc:70
flutter::PluginRegistrar::ClearPlugins              plugin_registrar.cc:43
flutter::PluginRegistrarManager::OnRegistrarDestroyed
flutter::FlutterWindowsEngine::Stop                 flutter_windows_engine.cc:563
flutter::FlutterWindowsEngine::~FlutterWindowsEngine
FlutterDesktopViewControllerDestroy
FlutterWindow::OnDestroy

Cause

The destructor added in #518 calls channel_->SetMethodCallHandler(nullptr). The plugin is destroyed from the registrar's destruction callback, and the engine has already detached its messenger by then:

FlutterWindowsEngine::~FlutterWindowsEngine() {
  messenger_->SetEngine(nullptr);
  Stop();   // runs the plugin registrar destruction callbacks
}

FlutterDesktopMessengerSetCallback then calls GetEngine()->message_dispatcher() on the null engine. Its availability check is an FML_DCHECK, which is compiled out of shipped engines.

Fix

Leave the handler registered. The engine is shutting down and dispatches nothing more to it, and the rest of the destructor (resetting lifetime_, closing the windows) is unchanged.

Verification

Flutter 3.47.9, Windows 11, x64 debug build of an app that depends on 0.4.2. Launch, wait for the first frame, close the main window, read the process exit code:

Build Exit code Application event log
0.4.2 0xC000041D, 2 of 2 runs APPCRASH, faulting module flutter_windows.dll
this change 0, 2 of 2 runs nothing

No test is added: the crash happens while the process is exiting, after the integration test harness has gone.

Since 0.4.0 the Windows plugin's destructor called
channel_->SetMethodCallHandler(nullptr). A plugin is destroyed from the
registrar's destruction callback, which ~FlutterWindowsEngine runs after
it has already detached the messenger from the engine
(messenger_->SetEngine(nullptr); Stop();). FlutterDesktopMessengerSetCallback
then dereferences the null engine, so every app that registers the plugin
crashed with an access violation in flutter_windows.dll when its main
window was closed, whether or not a webview had ever been opened.

The handler is now left registered: the engine is shutting down and
dispatches nothing more to it.
Leftover build output from a package that no longer exists on main;
the only intended change is windows/web_view_window_plugin.cc.
@mtallenca

Copy link
Copy Markdown
Contributor Author

A note on the red checks: they come from the Flutter stable rollover rather than from this change. CI installs the current stable, and main last passed on 2026-11-09 with Flutter 3.47.9; this PR ran on 3.50.0.

  • Validate Workspace: dart pub get under 3.50 rewrites the root pubspec.lock (analyzer 10.0.1 → 14.7.0, test 1.31.1 → 1.32.0, …), and the job fails on any lockfile diff. This PR does not touch pubspec.lock.
  • desktop_webview_window / windows, macos, linux: flutter analyze exits non-zero on four deprecated_member_use infos for package:flutter/material.dart in the example app (3.50 points it at package:material_ui), so the build and integration tests never start.

Both should affect any PR against main at the moment. I left them out of this PR to keep it to the 6-line crash fix, but I am happy to add the lockfile refresh and the example migration here, or send them separately, if you would prefer.

Also: the first commit accidentally included generated files under packages/string_tokenizer/. The second commit removes them, so the diff is now only windows/web_view_window_plugin.cc.

@boyan01
boyan01 merged commit b2c41d0 into MixinNetwork:main Nov 13, 2026
1 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants