From 17e7f5a3082af543a1719e36da92d6c2ac02ec81 Mon Sep 17 00:00:00 2001 From: Matthew Kosarek Date: Fri, 26 Jul 2024 09:17:34 -0700 Subject: [PATCH] bugfix: making the engine code work --- .../flutter_window_controller.cc | 94 +++++++++++++------ .../flutter/flutter_window_controller.h | 26 +++-- 2 files changed, 87 insertions(+), 33 deletions(-) diff --git a/shell/platform/windows/client_wrapper/flutter_window_controller.cc b/shell/platform/windows/client_wrapper/flutter_window_controller.cc index b9e3503a3d48a..a02194f63fac2 100644 --- a/shell/platform/windows/client_wrapper/flutter_window_controller.cc +++ b/shell/platform/windows/client_wrapper/flutter_window_controller.cc @@ -356,10 +356,21 @@ void handleCreateRegularWindow( : flutter::Win32Window::Point{0, 0}; }()}; - if (auto const view_id{ + if (auto const data{ flutter::FlutterWindowController::instance() .createRegularWindow(L"regular", origin, size)}) { - result->Success(flutter::EncodableValue(*view_id)); + result->Success(flutter::EncodableValue(flutter::EncodableMap{ + {flutter::EncodableValue("viewId"), + flutter::EncodableValue(data->view_id)}, + {flutter::EncodableValue("parentViewId"), + data->parent_id ? flutter::EncodableValue(*data->parent_id) + : flutter::EncodableValue()}, + {flutter::EncodableValue("archetype"), + flutter::EncodableValue(static_cast(data->archetype))}, + {flutter::EncodableValue("width"), + flutter::EncodableValue(data->size.width)}, + {flutter::EncodableValue("height"), + flutter::EncodableValue((data->size.height))}})); } else { result->Error("UNAVAILABLE", "Can't create window."); } @@ -526,10 +537,21 @@ void handleCreatePopupWindow(flutter::MethodCall<> const& call, auto const& [origin, new_size]{applyPositioner(positioner, size, *parent)}; - if (auto const view_id{ + if (auto const data{ flutter::FlutterWindowController::instance().createPopupWindow( L"popup", origin, new_size, *parent)}) { - result->Success(flutter::EncodableValue(*view_id)); + result->Success(flutter::EncodableValue(flutter::EncodableMap{ + {flutter::EncodableValue("viewId"), + flutter::EncodableValue(data->view_id)}, + {flutter::EncodableValue("parentViewId"), + data->parent_id ? flutter::EncodableValue(*data->parent_id) + : flutter::EncodableValue()}, + {flutter::EncodableValue("archetype"), + flutter::EncodableValue(static_cast(data->archetype))}, + {flutter::EncodableValue("width"), + flutter::EncodableValue(data->size.width)}, + {flutter::EncodableValue("height"), + flutter::EncodableValue((data->size.height))}})); } else { result->Error("UNAVAILABLE", "Can't create window."); } @@ -597,12 +619,14 @@ void FlutterWindowController::initializeChannel() { void FlutterWindowController::setEngine(std::shared_ptr engine) { std::lock_guard const lock(mutex_); engine_ = std::move(engine); + initializeChannel(); } auto FlutterWindowController::createRegularWindow( std::wstring const& title, Win32Window::Point const& origin, - Win32Window::Size const& size) -> std::optional { + Win32Window::Size const& size) + -> std::optional { std::unique_lock lock(mutex_); if (!engine_) { std::cerr << "Cannot create window without an engine.\n"; @@ -631,9 +655,14 @@ auto FlutterWindowController::createRegularWindow( sendOnWindowCreated(FlutterWindowArchetype::regular, view_id, std::nullopt); lock.unlock(); + + FlutterWindowCreationResult result; + result.view_id = view_id; + result.archetype = FlutterWindowArchetype::regular; + result.size = getWindowSize(view_id); sendOnWindowResized(view_id); - return view_id; + return result; } auto FlutterWindowController::createPopupWindow( @@ -641,7 +670,7 @@ auto FlutterWindowController::createPopupWindow( Win32Window::Point const& origin, Win32Window::Size const& size, std::optional parent_view_id) - -> std::optional { + -> std::optional { std::unique_lock lock(mutex_); if (!engine_) { std::cerr << "Cannot create window without an engine.\n"; @@ -675,9 +704,15 @@ auto FlutterWindowController::createPopupWindow( parent_view_id ? *parent_view_id : -1); lock.unlock(); + + FlutterWindowCreationResult result; + result.view_id = view_id; + result.archetype = FlutterWindowArchetype::popup; + result.parent_id = parent_view_id; + result.size = getWindowSize(view_id); sendOnWindowResized(view_id); - return view_id; + return result; } auto FlutterWindowController::destroyWindow(FlutterViewId view_id, @@ -763,30 +798,35 @@ void FlutterWindowController::sendOnWindowDestroyed( void FlutterWindowController::sendOnWindowResized(FlutterViewId view_id) const { std::lock_guard const lock(mutex_); if (channel_) { - auto* const hwnd{windows_.at(view_id)->GetHandle()}; - RECT frame; - if (FAILED(DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, - sizeof(frame)))) { - GetWindowRect(hwnd, &frame); - } - - // Convert to logical coordinates - auto const dpr{FlutterDesktopGetDpiForHWND(hwnd) / base_dpi}; - frame.left = static_cast(frame.left / dpr); - frame.top = static_cast(frame.top / dpr); - frame.right = static_cast(frame.right / dpr); - frame.bottom = static_cast(frame.bottom / dpr); - - auto const width{frame.right - frame.left}; - auto const height{frame.bottom - frame.top}; + auto size = getWindowSize(view_id); channel_->InvokeMethod( "onWindowResized", std::make_unique(EncodableMap{ {EncodableValue("viewId"), EncodableValue(view_id)}, - {EncodableValue("width"), EncodableValue(static_cast(width))}, - {EncodableValue("height"), - EncodableValue(static_cast(height))}})); + {EncodableValue("width"), EncodableValue(size.width)}, + {EncodableValue("height"), EncodableValue(size.height)}})); } } +FlutterWindowSize FlutterWindowController::getWindowSize( + flutter::FlutterViewId view_id) const { + auto* const hwnd{windows_.at(view_id)->GetHandle()}; + RECT frame; + if (FAILED(DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, + sizeof(frame)))) { + GetWindowRect(hwnd, &frame); + } + + // Convert to logical coordinates + auto const dpr{FlutterDesktopGetDpiForHWND(hwnd) / base_dpi}; + frame.left = static_cast(frame.left / dpr); + frame.top = static_cast(frame.top / dpr); + frame.right = static_cast(frame.right / dpr); + frame.bottom = static_cast(frame.bottom / dpr); + + auto const width{frame.right - frame.left}; + auto const height{frame.bottom - frame.top}; + return {static_cast(width), static_cast(height)}; +} + } // namespace flutter diff --git a/shell/platform/windows/client_wrapper/include/flutter/flutter_window_controller.h b/shell/platform/windows/client_wrapper/include/flutter/flutter_window_controller.h index cadaf3326241d..f8b420268201a 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/flutter_window_controller.h +++ b/shell/platform/windows/client_wrapper/include/flutter/flutter_window_controller.h @@ -12,6 +12,18 @@ namespace flutter { +struct FlutterWindowSize { + int width = 0; + int height = 0; +}; + +struct FlutterWindowCreationResult { + FlutterViewId view_id; + std::optional parent_id = std::nullopt; + FlutterWindowArchetype archetype; + FlutterWindowSize size; +}; + // A singleton controller for Flutter windows. class FlutterWindowController { public: @@ -35,12 +47,13 @@ class FlutterWindowController { auto createRegularWindow(std::wstring const& title, Win32Window::Point const& origin, Win32Window::Size const& size) - -> std::optional; - auto createPopupWindow(std::wstring const& title, - Win32Window::Point const& origin, - Win32Window::Size const& size, - std::optional parent_view_id = - std::nullopt) -> std::optional; + -> std::optional; + auto createPopupWindow( + std::wstring const& title, + Win32Window::Point const& origin, + Win32Window::Size const& size, + std::optional parent_view_id = std::nullopt) + -> std::optional; auto destroyWindow(FlutterViewId view_id, bool destroy_native_window) -> bool; auto windows() const -> ViewWindowMap const&; auto channel() const -> std::unique_ptr> const&; @@ -57,6 +70,7 @@ class FlutterWindowController { void sendOnWindowDestroyed(FlutterViewId view_id) const; void sendOnWindowResized(FlutterViewId view_id) const; void cleanupClosedWindows(); + FlutterWindowSize getWindowSize(flutter::FlutterViewId view_id) const; mutable std::mutex mutex_; std::unique_ptr> channel_;