Flutter Windows Embedder
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 
5 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
6 #include "flutter/shell/platform/windows/testing/windows_test.h"
8 #include "gtest/gtest.h"
9 
10 namespace flutter {
11 namespace testing {
12 
13 namespace {
14 
15 class 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 
68 TEST_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 
85 TEST_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 
94 TEST_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 
106 TEST_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 
116  ActualWindowSize size =
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 
125 TEST_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 
137  .has_preferred_view_size = true,
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 
150 TEST_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 
173 TEST_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 
196 TEST_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 
219 TEST_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 
243 TEST_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 
258  .has_preferred_view_size = true,
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 
274 TEST_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 
304 TEST_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 
319 TEST_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{
330  .preferred_size =
331  {
332  .has_preferred_view_size = true,
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 
353 TEST_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
Definition: host_window.cc:342
HostWindow * GetOwnerWindow() const
Definition: host_window.cc:817
static HostWindow * GetThisFromHandle(HWND hwnd)
Definition: host_window.cc:327
static Isolate Current()
Definition: isolate_scope.cc:9
Win32Message message
TEST_F(AccessibilityPluginTest, DirectAnnounceCall)
void(* on_message)(WindowsMessage *)
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)