#include "flutter_window.h" #include #include #include #include "flutter/generated_plugin_registrant.h" #include "utils.h" FlutterWindow::FlutterWindow(const flutter::DartProject& project) : project_(project) {} FlutterWindow::~FlutterWindow() {} bool FlutterWindow::OnCreate() { if (!Win32Window::OnCreate()) { return false; } RECT frame = GetClientArea(); // The size here must match the window dimensions to avoid unnecessary surface // creation / destruction in the startup path. flutter_controller_ = std::make_unique( frame.right - frame.left, frame.bottom - frame.top, project_); // Ensure that basic setup of the controller was successful. if (!flutter_controller_->engine() || !flutter_controller_->view()) { return false; } RegisterPlugins(flutter_controller_->engine()); SetChildContent(flutter_controller_->view()->GetNativeWindow()); flutter_controller_->engine()->SetNextFrameCallback([&]() { 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; } void FlutterWindow::OnDestroy() { if (flutter_controller_) { flutter_controller_ = nullptr; } Win32Window::OnDestroy(); } LRESULT FlutterWindow::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept { // OAuth handoff diagnostics: the app_links plugin consumes WM_COPYDATA // tagged with its own dwData (WM_USER + 2 == 1026). Log every WM_COPYDATA // so the protocol log shows whether a link reached this instance. if (message == WM_COPYDATA) { const auto* cds = reinterpret_cast(lparam); std::string detail = "WM_COPYDATA received"; if (cds != nullptr) { detail += "; dwData=" + std::to_string(cds->dwData); detail += " bytes=" + std::to_string(cds->cbData); if (cds->lpData != nullptr && cds->cbData > 0) { const char* payload = static_cast(cds->lpData); detail += " payload="; detail.append(payload, strnlen(payload, cds->cbData)); } } LogAppLink(detail); } // Give Flutter, including plugins, an opportunity to handle window messages. if (flutter_controller_) { std::optional result = flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, lparam); if (result) { return *result; } } switch (message) { case WM_FONTCHANGE: flutter_controller_->engine()->ReloadSystemFonts(); break; } return Win32Window::MessageHandler(hwnd, message, wparam, lparam); }