Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
window_manager_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
8#include "gtest/gtest.h"
9
10namespace flutter {
11namespace testing {
12
13namespace {
14
15class WindowManagerTest : public WindowsTest {
16 public:
17 WindowManagerTest() = default;
18 virtual ~WindowManagerTest() = default;
19
20 protected:
21 void SetUp() override {
22 auto& context = GetContext();
23 FlutterWindowsEngineBuilder builder(context);
24 ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
25
26 engine_ = builder.Build();
27 ASSERT_TRUE(engine_);
28
29 engine_->SetRootIsolateCreateCallback(context.GetRootIsolateCallback());
30 ASSERT_TRUE(engine_->Run("testWindowController"));
31
32 bool signalled = false;
33 context.AddNativeFunction(
34 "Signal", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
35 isolate_ = flutter::Isolate::Current();
36 signalled = true;
37 }));
38 while (!signalled) {
39 engine_->task_runner()->ProcessTasks();
40 }
41 }
42
43 void TearDown() override { engine_->Stop(); }
44
45 int64_t engine_id() { return reinterpret_cast<int64_t>(engine_.get()); }
46 flutter::Isolate& isolate() { return *isolate_; }
47 RegularWindowCreationRequest* regular_creation_request() {
48 return &regular_creation_request_;
49 }
50
51 private:
52 std::unique_ptr<FlutterWindowsEngine> engine_;
53 std::optional<flutter::Isolate> isolate_;
54 RegularWindowCreationRequest regular_creation_request_{
55 .preferred_size =
56 {
57 .has_preferred_view_size = true,
58 .preferred_view_width = 800,
59 .preferred_view_height = 600,
60 },
61 };
62
63 FML_DISALLOW_COPY_AND_ASSIGN(WindowManagerTest);
64};
65
66} // namespace
67
68TEST_F(WindowManagerTest, WindowingInitialize) {
69 IsolateScope isolate_scope(isolate());
70
71 static bool received_message = false;
72 WindowingInitRequest init_request{
73 .on_message = [](WindowsMessage* message) { received_message = true; }};
74
75 InternalFlutterWindows_WindowManager_Initialize(engine_id(), &init_request);
76 const int64_t view_id =
78 engine_id(), regular_creation_request());
80 engine_id(), view_id));
81
82 EXPECT_TRUE(received_message);
83}
84
85TEST_F(WindowManagerTest, CreateRegularWindow) {
86 IsolateScope isolate_scope(isolate());
87
88 const int64_t view_id =
90 engine_id(), regular_creation_request());
91 EXPECT_EQ(view_id, 0);
92}
93
94TEST_F(WindowManagerTest, GetWindowHandle) {
95 IsolateScope isolate_scope(isolate());
96
97 const int64_t view_id =
99 engine_id(), regular_creation_request());
100 const HWND window_handle =
102 view_id);
103 EXPECT_NE(window_handle, nullptr);
104}
105
106TEST_F(WindowManagerTest, GetWindowSize) {
107 IsolateScope isolate_scope(isolate());
108
109 const int64_t view_id =
111 engine_id(), regular_creation_request());
112 const HWND window_handle =
114 view_id);
115
118
119 EXPECT_EQ(size.width,
120 regular_creation_request()->preferred_size.preferred_view_width);
121 EXPECT_EQ(size.height,
122 regular_creation_request()->preferred_size.preferred_view_height);
123}
124
125TEST_F(WindowManagerTest, SetWindowSize) {
126 IsolateScope isolate_scope(isolate());
127
128 const int64_t view_id =
130 engine_id(), regular_creation_request());
131 const HWND window_handle =
133 view_id);
134
135 WindowSizeRequest requestedSize{
136
138 .preferred_view_width = 640,
139 .preferred_view_height = 480,
140 };
142 &requestedSize);
143
144 ActualWindowSize actual_size =
146 EXPECT_EQ(actual_size.width, 640);
147 EXPECT_EQ(actual_size.height, 480);
148}
149
150TEST_F(WindowManagerTest, CanConstrainByMinimiumSize) {
151 IsolateScope isolate_scope(isolate());
152
153 const int64_t view_id =
155 engine_id(), regular_creation_request());
156 const HWND window_handle =
158 view_id);
159 WindowConstraints constraints{.has_view_constraints = true,
160 .view_min_width = 900,
161 .view_min_height = 700,
162 .view_max_width = 10000,
163 .view_max_height = 10000};
165 &constraints);
166
167 ActualWindowSize actual_size =
169 EXPECT_EQ(actual_size.width, 900);
170 EXPECT_EQ(actual_size.height, 700);
171}
172
173TEST_F(WindowManagerTest, CanConstrainByMaximumSize) {
174 IsolateScope isolate_scope(isolate());
175
176 const int64_t view_id =
178 engine_id(), regular_creation_request());
179 const HWND window_handle =
181 view_id);
182 WindowConstraints constraints{.has_view_constraints = true,
183 .view_min_width = 0,
184 .view_min_height = 0,
185 .view_max_width = 500,
186 .view_max_height = 500};
188 &constraints);
189
190 ActualWindowSize actual_size =
192 EXPECT_EQ(actual_size.width, 500);
193 EXPECT_EQ(actual_size.height, 500);
194}
195
196TEST_F(WindowManagerTest, CanFullscreenWindow) {
197 IsolateScope isolate_scope(isolate());
198
199 const int64_t view_id =
201 engine_id(), regular_creation_request());
202 const HWND window_handle =
204 view_id);
205
206 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
208
209 int screen_width = GetSystemMetrics(SM_CXSCREEN);
210 int screen_height = GetSystemMetrics(SM_CYSCREEN);
211 ActualWindowSize actual_size =
213 EXPECT_EQ(actual_size.width, screen_width);
214 EXPECT_EQ(actual_size.height, screen_height);
215 EXPECT_TRUE(
217}
218
219TEST_F(WindowManagerTest, CanUnfullscreenWindow) {
220 IsolateScope isolate_scope(isolate());
221
222 const int64_t view_id =
224 engine_id(), regular_creation_request());
225 const HWND window_handle =
227 view_id);
228
229 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
231
232 request.fullscreen = false;
234
235 ActualWindowSize actual_size =
237 EXPECT_EQ(actual_size.width, 800);
238 EXPECT_EQ(actual_size.height, 600);
239 EXPECT_FALSE(
241}
242
243TEST_F(WindowManagerTest, CanSetWindowSizeWhileFullscreen) {
244 IsolateScope isolate_scope(isolate());
245
246 const int64_t view_id =
248 engine_id(), regular_creation_request());
249 const HWND window_handle =
251 view_id);
252
253 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
255
256 WindowSizeRequest requestedSize{
257
259 .preferred_view_width = 500,
260 .preferred_view_height = 500,
261 };
263 &requestedSize);
264
265 request.fullscreen = false;
267
268 ActualWindowSize actual_size =
270 EXPECT_EQ(actual_size.width, 500);
271 EXPECT_EQ(actual_size.height, 500);
272}
273
274TEST_F(WindowManagerTest, CanSetWindowConstraintsWhileFullscreen) {
275 IsolateScope isolate_scope(isolate());
276
277 const int64_t view_id =
279 engine_id(), regular_creation_request());
280 const HWND window_handle =
282 view_id);
283
284 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
286
287 WindowConstraints constraints{.has_view_constraints = true,
288 .view_min_width = 0,
289 .view_min_height = 0,
290 .view_max_width = 500,
291 .view_max_height = 500};
293 &constraints);
294
295 request.fullscreen = false;
297
298 ActualWindowSize actual_size =
300 EXPECT_EQ(actual_size.width, 500);
301 EXPECT_EQ(actual_size.height, 500);
302}
303
304TEST_F(WindowManagerTest, CreateModelessDialogWindow) {
305 IsolateScope isolate_scope(isolate());
306 DialogWindowCreationRequest creation_request{
308 .preferred_view_width = 800,
309 .preferred_view_height = 600},
310 .preferred_constraints = {.has_view_constraints = false},
311 .title = L"Hello World",
312 .parent_or_null = nullptr};
313 const int64_t view_id =
315 engine_id(), &creation_request);
316 EXPECT_EQ(view_id, 0);
317}
318
319TEST_F(WindowManagerTest, CreateModalDialogWindow) {
320 IsolateScope isolate_scope(isolate());
321
322 const int64_t parent_view_id =
324 engine_id(), regular_creation_request());
325 const HWND parent_window_handle =
327 engine_id(), parent_view_id);
328
329 DialogWindowCreationRequest creation_request{
331 {
333 .preferred_view_width = 800,
334 .preferred_view_height = 600,
335 },
336 .preferred_constraints = {.has_view_constraints = false},
337 .title = L"Hello World",
338 .parent_or_null = parent_window_handle};
339
340 const int64_t view_id =
342 engine_id(), &creation_request);
343 EXPECT_EQ(view_id, 1);
344
345 const HWND window_handle =
347 view_id);
348 HostWindow* host_window = HostWindow::GetThisFromHandle(window_handle);
349 EXPECT_EQ(host_window->GetOwnerWindow()->GetWindowHandle(),
350 parent_window_handle);
351}
352
353TEST_F(WindowManagerTest, DialogCanNeverBeFullscreen) {
354 IsolateScope isolate_scope(isolate());
355
356 DialogWindowCreationRequest creation_request{
358 .preferred_view_width = 800,
359 .preferred_view_height = 600},
360 .preferred_constraints = {.has_view_constraints = false},
361 .title = L"Hello World",
362 .parent_or_null = nullptr};
363
364 const int64_t view_id =
366 engine_id(), &creation_request);
367 const HWND window_handle =
369 view_id);
370
371 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
373 EXPECT_FALSE(
375}
376
377} // namespace testing
378} // namespace flutter
HWND GetWindowHandle() const
HostWindow * GetOwnerWindow() const
static HostWindow * GetThisFromHandle(HWND hwnd)
static Isolate Current()
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS GBytes * message
G_BEGIN_DECLS FlutterViewId view_id
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
TEST_F(DisplayListTest, Defaults)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
void(* on_message)(WindowsMessage *)
#define CREATE_NATIVE_ENTRY(native_entry)
void InternalFlutterWindows_WindowManager_Initialize(int64_t engine_id, const flutter::WindowingInitRequest *request)
void InternalFlutterWindows_WindowManager_SetWindowConstraints(HWND hwnd, const flutter::WindowConstraints *constraints)
bool InternalFlutterWindows_WindowManager_GetFullscreen(HWND hwnd)
void InternalFlutterWindows_WindowManager_SetWindowSize(HWND hwnd, const flutter::WindowSizeRequest *size)
FlutterViewId InternalFlutterWindows_WindowManager_CreateRegularWindow(int64_t engine_id, const flutter::RegularWindowCreationRequest *request)
FLUTTER_EXPORT FlutterViewId InternalFlutterWindows_WindowManager_CreateDialogWindow(int64_t engine_id, const flutter::DialogWindowCreationRequest *request)
void InternalFlutterWindows_WindowManager_SetFullscreen(HWND hwnd, const flutter::FullscreenRequest *request)
flutter::ActualWindowSize InternalFlutterWindows_WindowManager_GetWindowContentSize(HWND hwnd)
HWND InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(int64_t engine_id, FlutterViewId view_id)