[Windows] Make the engine own a map of views (flutter/engine#51017)
Updates Windows engine's data structures to use a map of views. This is a refactoring with no semantic changes. Flutter Windows's APIs restrict users to 0 or 1 view only - it is not possible to create multiple views yet. _One small step for Windows. One giant leap for multi-view._ Part of https://github.com/flutter/flutter/issues/143765 Part of https://github.com/flutter/flutter/issues/142845 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
@@ -496,7 +496,7 @@ std::unique_ptr<FlutterWindowsView> FlutterWindowsEngine::CreateView(
|
||||
auto view = std::make_unique<FlutterWindowsView>(
|
||||
kImplicitViewId, this, std::move(window), windows_proc_table_);
|
||||
|
||||
view_ = view.get();
|
||||
views_[kImplicitViewId] = view.get();
|
||||
InitializeKeyboard();
|
||||
|
||||
return std::move(view);
|
||||
@@ -531,9 +531,12 @@ std::chrono::nanoseconds FlutterWindowsEngine::FrameInterval() {
|
||||
}
|
||||
|
||||
FlutterWindowsView* FlutterWindowsEngine::view(FlutterViewId view_id) const {
|
||||
FML_DCHECK(view_id == kImplicitViewId);
|
||||
auto iterator = views_.find(view_id);
|
||||
if (iterator == views_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return view_;
|
||||
return iterator->second;
|
||||
}
|
||||
|
||||
// Returns the currently configured Plugin Registrar.
|
||||
@@ -672,7 +675,7 @@ void FlutterWindowsEngine::SendSystemLocales() {
|
||||
}
|
||||
|
||||
void FlutterWindowsEngine::InitializeKeyboard() {
|
||||
if (view_ == nullptr) {
|
||||
if (views_.empty()) {
|
||||
FML_LOG(ERROR) << "Cannot initialize keyboard on Windows headless mode.";
|
||||
}
|
||||
|
||||
@@ -762,15 +765,15 @@ void FlutterWindowsEngine::UpdateSemanticsEnabled(bool enabled) {
|
||||
if (engine_ && semantics_enabled_ != enabled) {
|
||||
semantics_enabled_ = enabled;
|
||||
embedder_api_.UpdateSemanticsEnabled(engine_, enabled);
|
||||
if (view_) {
|
||||
view_->UpdateSemanticsEnabled(enabled);
|
||||
for (auto iterator = views_.begin(); iterator != views_.end(); iterator++) {
|
||||
iterator->second->UpdateSemanticsEnabled(enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FlutterWindowsEngine::OnPreEngineRestart() {
|
||||
// Reset the keyboard's state on hot restart.
|
||||
if (view_) {
|
||||
if (!views_.empty()) {
|
||||
InitializeKeyboard();
|
||||
}
|
||||
}
|
||||
@@ -827,7 +830,9 @@ void FlutterWindowsEngine::OnQuit(std::optional<HWND> hwnd,
|
||||
}
|
||||
|
||||
void FlutterWindowsEngine::OnDwmCompositionChanged() {
|
||||
view_->OnDwmCompositionChanged();
|
||||
for (auto iterator = views_.begin(); iterator != views_.end(); iterator++) {
|
||||
iterator->second->OnDwmCompositionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void FlutterWindowsEngine::OnWindowStateEvent(HWND hwnd,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "flutter/fml/closure.h"
|
||||
@@ -119,12 +120,13 @@ class FlutterWindowsEngine {
|
||||
// Returns false if stopping the engine fails, or if it was not running.
|
||||
virtual bool Stop();
|
||||
|
||||
// Create the view that is displaying this engine's content.
|
||||
// Create a view that can display this engine's content.
|
||||
std::unique_ptr<FlutterWindowsView> CreateView(
|
||||
std::unique_ptr<WindowBindingHandler> window);
|
||||
|
||||
// The view displaying this engine's content, if any. This will be null for
|
||||
// headless engines.
|
||||
// Get a view that displays this engine's content.
|
||||
//
|
||||
// Returns null if the view does not exist.
|
||||
FlutterWindowsView* view(FlutterViewId view_id) const;
|
||||
|
||||
// Returns the currently configured Plugin Registrar.
|
||||
@@ -349,8 +351,8 @@ class FlutterWindowsEngine {
|
||||
// AOT data, if any.
|
||||
UniqueAotDataPtr aot_data_;
|
||||
|
||||
// The view displaying the content running in this engine, if any.
|
||||
FlutterWindowsView* view_ = nullptr;
|
||||
// The views displaying the content running in this engine, if any.
|
||||
std::unordered_map<FlutterViewId, FlutterWindowsView*> views_;
|
||||
|
||||
// Task runner for tasks posted from the engine.
|
||||
std::unique_ptr<TaskRunner> task_runner_;
|
||||
|
||||
@@ -34,6 +34,19 @@ using ::testing::Return;
|
||||
|
||||
class FlutterWindowsEngineTest : public WindowsTest {};
|
||||
|
||||
// The engine can be run without any views.
|
||||
TEST_F(FlutterWindowsEngineTest, RunHeadless) {
|
||||
FlutterWindowsEngineBuilder builder{GetContext()};
|
||||
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
|
||||
|
||||
EngineModifier modifier(engine.get());
|
||||
modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; };
|
||||
|
||||
ASSERT_TRUE(engine->Run());
|
||||
ASSERT_EQ(engine->view(kImplicitViewId), nullptr);
|
||||
ASSERT_EQ(engine->view(123), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(FlutterWindowsEngineTest, RunDoesExpectedInitialization) {
|
||||
FlutterWindowsEngineBuilder builder{GetContext()};
|
||||
builder.AddDartEntrypointArgument("arg1");
|
||||
|
||||
@@ -39,7 +39,9 @@ class EngineModifier {
|
||||
|
||||
// Override the engine's implicit view. This is the "default" view
|
||||
// that Flutter apps render to.
|
||||
void SetImplicitView(FlutterWindowsView* view) { engine_->view_ = view; }
|
||||
void SetImplicitView(FlutterWindowsView* view) {
|
||||
engine_->views_[kImplicitViewId] = view;
|
||||
}
|
||||
|
||||
/// Reset the start_time field that is used to align vsync events.
|
||||
void SetStartTime(uint64_t start_time_nanos) {
|
||||
|
||||
Reference in New Issue
Block a user