Flutter Engine
 
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, HasTopLevelWindows) {
86 IsolateScope isolate_scope(isolate());
87
88 bool has_top_level_windows =
90 EXPECT_FALSE(has_top_level_windows);
91
93 engine_id(), regular_creation_request());
94 has_top_level_windows =
96 EXPECT_TRUE(has_top_level_windows);
97}
98
99TEST_F(WindowManagerTest, CreateRegularWindow) {
100 IsolateScope isolate_scope(isolate());
101
102 const int64_t view_id =
104 engine_id(), regular_creation_request());
105 EXPECT_EQ(view_id, 0);
106}
107
108TEST_F(WindowManagerTest, GetWindowHandle) {
109 IsolateScope isolate_scope(isolate());
110
111 const int64_t view_id =
113 engine_id(), regular_creation_request());
114 const HWND window_handle =
116 view_id);
117 EXPECT_NE(window_handle, nullptr);
118}
119
120TEST_F(WindowManagerTest, GetWindowSize) {
121 IsolateScope isolate_scope(isolate());
122
123 const int64_t view_id =
125 engine_id(), regular_creation_request());
126 const HWND window_handle =
128 view_id);
129
132
133 EXPECT_EQ(size.width,
134 regular_creation_request()->preferred_size.preferred_view_width);
135 EXPECT_EQ(size.height,
136 regular_creation_request()->preferred_size.preferred_view_height);
137}
138
139TEST_F(WindowManagerTest, SetWindowSize) {
140 IsolateScope isolate_scope(isolate());
141
142 const int64_t view_id =
144 engine_id(), regular_creation_request());
145 const HWND window_handle =
147 view_id);
148
149 WindowSizeRequest requestedSize{
150
152 .preferred_view_width = 640,
153 .preferred_view_height = 480,
154 };
156 &requestedSize);
157
158 ActualWindowSize actual_size =
160 EXPECT_EQ(actual_size.width, 640);
161 EXPECT_EQ(actual_size.height, 480);
162}
163
164TEST_F(WindowManagerTest, CanConstrainByMinimiumSize) {
165 IsolateScope isolate_scope(isolate());
166
167 const int64_t view_id =
169 engine_id(), regular_creation_request());
170 const HWND window_handle =
172 view_id);
173 WindowConstraints constraints{.has_view_constraints = true,
174 .view_min_width = 900,
175 .view_min_height = 700,
176 .view_max_width = 10000,
177 .view_max_height = 10000};
179 &constraints);
180
181 ActualWindowSize actual_size =
183 EXPECT_EQ(actual_size.width, 900);
184 EXPECT_EQ(actual_size.height, 700);
185}
186
187TEST_F(WindowManagerTest, CanConstrainByMaximumSize) {
188 IsolateScope isolate_scope(isolate());
189
190 const int64_t view_id =
192 engine_id(), regular_creation_request());
193 const HWND window_handle =
195 view_id);
196 WindowConstraints constraints{.has_view_constraints = true,
197 .view_min_width = 0,
198 .view_min_height = 0,
199 .view_max_width = 500,
200 .view_max_height = 500};
202 &constraints);
203
204 ActualWindowSize actual_size =
206 EXPECT_EQ(actual_size.width, 500);
207 EXPECT_EQ(actual_size.height, 500);
208}
209
210TEST_F(WindowManagerTest, CanFullscreenWindow) {
211 IsolateScope isolate_scope(isolate());
212
213 const int64_t view_id =
215 engine_id(), regular_creation_request());
216 const HWND window_handle =
218 view_id);
219
220 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
222
223 int screen_width = GetSystemMetrics(SM_CXSCREEN);
224 int screen_height = GetSystemMetrics(SM_CYSCREEN);
225 ActualWindowSize actual_size =
227 EXPECT_EQ(actual_size.width, screen_width);
228 EXPECT_EQ(actual_size.height, screen_height);
229 EXPECT_TRUE(
231}
232
233TEST_F(WindowManagerTest, CanUnfullscreenWindow) {
234 IsolateScope isolate_scope(isolate());
235
236 const int64_t view_id =
238 engine_id(), regular_creation_request());
239 const HWND window_handle =
241 view_id);
242
243 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
245
246 request.fullscreen = false;
248
249 ActualWindowSize actual_size =
251 EXPECT_EQ(actual_size.width, 800);
252 EXPECT_EQ(actual_size.height, 600);
253 EXPECT_FALSE(
255}
256
257TEST_F(WindowManagerTest, CanSetWindowSizeWhileFullscreen) {
258 IsolateScope isolate_scope(isolate());
259
260 const int64_t view_id =
262 engine_id(), regular_creation_request());
263 const HWND window_handle =
265 view_id);
266
267 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
269
270 WindowSizeRequest requestedSize{
271
273 .preferred_view_width = 500,
274 .preferred_view_height = 500,
275 };
277 &requestedSize);
278
279 request.fullscreen = false;
281
282 ActualWindowSize actual_size =
284 EXPECT_EQ(actual_size.width, 500);
285 EXPECT_EQ(actual_size.height, 500);
286}
287
288TEST_F(WindowManagerTest, CanSetWindowConstraintsWhileFullscreen) {
289 IsolateScope isolate_scope(isolate());
290
291 const int64_t view_id =
293 engine_id(), regular_creation_request());
294 const HWND window_handle =
296 view_id);
297
298 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
300
301 WindowConstraints constraints{.has_view_constraints = true,
302 .view_min_width = 0,
303 .view_min_height = 0,
304 .view_max_width = 500,
305 .view_max_height = 500};
307 &constraints);
308
309 request.fullscreen = false;
311
312 ActualWindowSize actual_size =
314 EXPECT_EQ(actual_size.width, 500);
315 EXPECT_EQ(actual_size.height, 500);
316}
317
318TEST_F(WindowManagerTest, CreateModelessDialogWindow) {
319 IsolateScope isolate_scope(isolate());
320 DialogWindowCreationRequest creation_request{
322 .preferred_view_width = 800,
323 .preferred_view_height = 600},
324 .preferred_constraints = {.has_view_constraints = false},
325 .title = L"Hello World",
326 .parent_or_null = nullptr};
327 const int64_t view_id =
329 engine_id(), &creation_request);
330 EXPECT_EQ(view_id, 0);
331}
332
333TEST_F(WindowManagerTest, CreateModalDialogWindow) {
334 IsolateScope isolate_scope(isolate());
335
336 const int64_t parent_view_id =
338 engine_id(), regular_creation_request());
339 const HWND parent_window_handle =
341 engine_id(), parent_view_id);
342
343 DialogWindowCreationRequest creation_request{
345 {
347 .preferred_view_width = 800,
348 .preferred_view_height = 600,
349 },
350 .preferred_constraints = {.has_view_constraints = false},
351 .title = L"Hello World",
352 .parent_or_null = parent_window_handle};
353
354 const int64_t view_id =
356 engine_id(), &creation_request);
357 EXPECT_EQ(view_id, 1);
358
359 const HWND window_handle =
361 view_id);
362 HostWindow* host_window = HostWindow::GetThisFromHandle(window_handle);
363 EXPECT_EQ(host_window->GetOwnerWindow()->GetWindowHandle(),
364 parent_window_handle);
365}
366
367TEST_F(WindowManagerTest, DialogCanNeverBeFullscreen) {
368 IsolateScope isolate_scope(isolate());
369
370 DialogWindowCreationRequest creation_request{
372 .preferred_view_width = 800,
373 .preferred_view_height = 600},
374 .preferred_constraints = {.has_view_constraints = false},
375 .title = L"Hello World",
376 .parent_or_null = nullptr};
377
378 const int64_t view_id =
380 engine_id(), &creation_request);
381 const HWND window_handle =
383 view_id);
384
385 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
387 EXPECT_FALSE(
389}
390
391} // namespace testing
392} // 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)
bool InternalFlutterWindows_WindowManager_HasTopLevelWindows(int64_t engine_id)
HWND InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(int64_t engine_id, FlutterViewId view_id)