Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 64a375d

Browse files
authored
[Windows] Make the engine own a map of views (#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 flutter/flutter#143765 Part of flutter/flutter#142845 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 73480bf commit 64a375d

File tree

4 files changed

+36
-14
lines changed

4 files changed

+36
-14
lines changed

shell/platform/windows/flutter_windows_engine.cc

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ std::unique_ptr<FlutterWindowsView> FlutterWindowsEngine::CreateView(
496496
auto view = std::make_unique<FlutterWindowsView>(
497497
kImplicitViewId, this, std::move(window), windows_proc_table_);
498498

499-
view_ = view.get();
499+
views_[kImplicitViewId] = view.get();
500500
InitializeKeyboard();
501501

502502
return std::move(view);
@@ -531,9 +531,12 @@ std::chrono::nanoseconds FlutterWindowsEngine::FrameInterval() {
531531
}
532532

533533
FlutterWindowsView* FlutterWindowsEngine::view(FlutterViewId view_id) const {
534-
FML_DCHECK(view_id == kImplicitViewId);
534+
auto iterator = views_.find(view_id);
535+
if (iterator == views_.end()) {
536+
return nullptr;
537+
}
535538

536-
return view_;
539+
return iterator->second;
537540
}
538541

539542
// Returns the currently configured Plugin Registrar.
@@ -672,7 +675,7 @@ void FlutterWindowsEngine::SendSystemLocales() {
672675
}
673676

674677
void FlutterWindowsEngine::InitializeKeyboard() {
675-
if (view_ == nullptr) {
678+
if (views_.empty()) {
676679
FML_LOG(ERROR) << "Cannot initialize keyboard on Windows headless mode.";
677680
}
678681

@@ -762,15 +765,15 @@ void FlutterWindowsEngine::UpdateSemanticsEnabled(bool enabled) {
762765
if (engine_ && semantics_enabled_ != enabled) {
763766
semantics_enabled_ = enabled;
764767
embedder_api_.UpdateSemanticsEnabled(engine_, enabled);
765-
if (view_) {
766-
view_->UpdateSemanticsEnabled(enabled);
768+
for (auto iterator = views_.begin(); iterator != views_.end(); iterator++) {
769+
iterator->second->UpdateSemanticsEnabled(enabled);
767770
}
768771
}
769772
}
770773

771774
void FlutterWindowsEngine::OnPreEngineRestart() {
772775
// Reset the keyboard's state on hot restart.
773-
if (view_) {
776+
if (!views_.empty()) {
774777
InitializeKeyboard();
775778
}
776779
}
@@ -827,7 +830,9 @@ void FlutterWindowsEngine::OnQuit(std::optional<HWND> hwnd,
827830
}
828831

829832
void FlutterWindowsEngine::OnDwmCompositionChanged() {
830-
view_->OnDwmCompositionChanged();
833+
for (auto iterator = views_.begin(); iterator != views_.end(); iterator++) {
834+
iterator->second->OnDwmCompositionChanged();
835+
}
831836
}
832837

833838
void FlutterWindowsEngine::OnWindowStateEvent(HWND hwnd,

shell/platform/windows/flutter_windows_engine.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <optional>
1212
#include <string>
1313
#include <string_view>
14+
#include <unordered_map>
1415
#include <vector>
1516

1617
#include "flutter/fml/closure.h"
@@ -119,12 +120,13 @@ class FlutterWindowsEngine {
119120
// Returns false if stopping the engine fails, or if it was not running.
120121
virtual bool Stop();
121122

122-
// Create the view that is displaying this engine's content.
123+
// Create a view that can display this engine's content.
123124
std::unique_ptr<FlutterWindowsView> CreateView(
124125
std::unique_ptr<WindowBindingHandler> window);
125126

126-
// The view displaying this engine's content, if any. This will be null for
127-
// headless engines.
127+
// Get a view that displays this engine's content.
128+
//
129+
// Returns null if the view does not exist.
128130
FlutterWindowsView* view(FlutterViewId view_id) const;
129131

130132
// Returns the currently configured Plugin Registrar.
@@ -349,8 +351,8 @@ class FlutterWindowsEngine {
349351
// AOT data, if any.
350352
UniqueAotDataPtr aot_data_;
351353

352-
// The view displaying the content running in this engine, if any.
353-
FlutterWindowsView* view_ = nullptr;
354+
// The views displaying the content running in this engine, if any.
355+
std::unordered_map<FlutterViewId, FlutterWindowsView*> views_;
354356

355357
// Task runner for tasks posted from the engine.
356358
std::unique_ptr<TaskRunner> task_runner_;

shell/platform/windows/flutter_windows_engine_unittests.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ using ::testing::Return;
3434

3535
class FlutterWindowsEngineTest : public WindowsTest {};
3636

37+
// The engine can be run without any views.
38+
TEST_F(FlutterWindowsEngineTest, RunHeadless) {
39+
FlutterWindowsEngineBuilder builder{GetContext()};
40+
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
41+
42+
EngineModifier modifier(engine.get());
43+
modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; };
44+
45+
ASSERT_TRUE(engine->Run());
46+
ASSERT_EQ(engine->view(kImplicitViewId), nullptr);
47+
ASSERT_EQ(engine->view(123), nullptr);
48+
}
49+
3750
TEST_F(FlutterWindowsEngineTest, RunDoesExpectedInitialization) {
3851
FlutterWindowsEngineBuilder builder{GetContext()};
3952
builder.AddDartEntrypointArgument("arg1");

shell/platform/windows/testing/engine_modifier.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ class EngineModifier {
3939

4040
// Override the engine's implicit view. This is the "default" view
4141
// that Flutter apps render to.
42-
void SetImplicitView(FlutterWindowsView* view) { engine_->view_ = view; }
42+
void SetImplicitView(FlutterWindowsView* view) {
43+
engine_->views_[kImplicitViewId] = view;
44+
}
4345

4446
/// Reset the start_time field that is used to align vsync events.
4547
void SetStartTime(uint64_t start_time_nanos) {

0 commit comments

Comments
 (0)