| 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"
7 #include "flutter/shell/platform/windows/window_manager.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 WindowCreationRequest* creation_request() { return &creation_request_; }
48
49 private:
50 std::unique_ptr<FlutterWindowsEngine> engine_;
51 std::optional<flutter::Isolate> isolate_;
52 WindowCreationRequest creation_request_{
53 .preferred_size =
54 {
55 .has_preferred_view_size = true,
56 .preferred_view_width = 800,
57 .preferred_view_height = 600,
58 },
59 };
60
61 FML_DISALLOW_COPY_AND_ASSIGN(WindowManagerTest);
62 };
63
64 } // namespace
65
66 TEST_F(WindowManagerTest, WindowingInitialize) {
67 IsolateScope isolate_scope(isolate());
68
69 static bool received_message = false;
70 WindowingInitRequest init_request{
71 .on_message = [](WindowsMessage* message) { received_message = true; }};
72
73 InternalFlutterWindows_WindowManager_Initialize(engine_id(), &init_request);
74 const int64_t view_id =
75 InternalFlutterWindows_WindowManager_CreateRegularWindow(
76 engine_id(), creation_request());
77 DestroyWindow(InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
78 engine_id(), view_id));
79
80 EXPECT_TRUE(received_message);
81 }
82
83 TEST_F(WindowManagerTest, HasTopLevelWindows) {
84 IsolateScope isolate_scope(isolate());
85
86 bool has_top_level_windows =
87 InternalFlutterWindows_WindowManager_HasTopLevelWindows(engine_id());
88 EXPECT_FALSE(has_top_level_windows);
89
90 InternalFlutterWindows_WindowManager_CreateRegularWindow(engine_id(),
91 creation_request());
92 has_top_level_windows =
93 InternalFlutterWindows_WindowManager_HasTopLevelWindows(engine_id());
94 EXPECT_TRUE(has_top_level_windows);
95 }
96
97 TEST_F(WindowManagerTest, CreateRegularWindow) {
98 IsolateScope isolate_scope(isolate());
99
100 const int64_t view_id =
101 InternalFlutterWindows_WindowManager_CreateRegularWindow(
102 engine_id(), creation_request());
103 EXPECT_EQ(view_id, 0);
104 }
105
106 TEST_F(WindowManagerTest, GetWindowHandle) {
107 IsolateScope isolate_scope(isolate());
108
109 const int64_t view_id =
110 InternalFlutterWindows_WindowManager_CreateRegularWindow(
111 engine_id(), creation_request());
112 const HWND window_handle =
113 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
114 view_id);
115 EXPECT_NE(window_handle, nullptr);
116 }
117
118 TEST_F(WindowManagerTest, GetWindowSize) {
119 IsolateScope isolate_scope(isolate());
120
121 const int64_t view_id =
122 InternalFlutterWindows_WindowManager_CreateRegularWindow(
123 engine_id(), creation_request());
124 const HWND window_handle =
125 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
126 view_id);
127
128 ActualWindowSize size =
129 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
130
131 EXPECT_EQ(size.width,
132 creation_request()->preferred_size.preferred_view_width);
133 EXPECT_EQ(size.height,
134 creation_request()->preferred_size.preferred_view_height);
135 }
136
137 TEST_F(WindowManagerTest, SetWindowSize) {
138 IsolateScope isolate_scope(isolate());
139
140 const int64_t view_id =
141 InternalFlutterWindows_WindowManager_CreateRegularWindow(
142 engine_id(), creation_request());
143 const HWND window_handle =
144 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
145 view_id);
146
147 WindowSizeRequest requestedSize{
148
149 .has_preferred_view_size = true,
150 .preferred_view_width = 640,
151 .preferred_view_height = 480,
152 };
153 InternalFlutterWindows_WindowManager_SetWindowSize(window_handle,
154 &requestedSize);
155
156 ActualWindowSize actual_size =
157 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
158 EXPECT_EQ(actual_size.width, 640);
159 EXPECT_EQ(actual_size.height, 480);
160 }
161
162 TEST_F(WindowManagerTest, CanConstrainByMinimiumSize) {
163 IsolateScope isolate_scope(isolate());
164
165 const int64_t view_id =
166 InternalFlutterWindows_WindowManager_CreateRegularWindow(
167 engine_id(), creation_request());
168 const HWND window_handle =
169 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
170 view_id);
171 WindowConstraints constraints{.has_view_constraints = true,
172 .view_min_width = 900,
173 .view_min_height = 700,
174 .view_max_width = 10000,
175 .view_max_height = 10000};
176 InternalFlutterWindows_WindowManager_SetWindowConstraints(window_handle,
177 &constraints);
178
179 ActualWindowSize actual_size =
180 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
181 EXPECT_EQ(actual_size.width, 900);
182 EXPECT_EQ(actual_size.height, 700);
183 }
184
185 TEST_F(WindowManagerTest, CanConstrainByMaximumSize) {
186 IsolateScope isolate_scope(isolate());
187
188 const int64_t view_id =
189 InternalFlutterWindows_WindowManager_CreateRegularWindow(
190 engine_id(), creation_request());
191 const HWND window_handle =
192 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
193 view_id);
194 WindowConstraints constraints{.has_view_constraints = true,
195 .view_min_width = 0,
196 .view_min_height = 0,
197 .view_max_width = 500,
198 .view_max_height = 500};
199 InternalFlutterWindows_WindowManager_SetWindowConstraints(window_handle,
200 &constraints);
201
202 ActualWindowSize actual_size =
203 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
204 EXPECT_EQ(actual_size.width, 500);
205 EXPECT_EQ(actual_size.height, 500);
206 }
207
208 TEST_F(WindowManagerTest, CanFullscreenWindow) {
209 IsolateScope isolate_scope(isolate());
210
211 const int64_t view_id =
212 InternalFlutterWindows_WindowManager_CreateRegularWindow(
213 engine_id(), creation_request());
214 const HWND window_handle =
215 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
216 view_id);
217
218 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
219 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
220
221 int screen_width = GetSystemMetrics(SM_CXSCREEN);
222 int screen_height = GetSystemMetrics(SM_CYSCREEN);
223 ActualWindowSize actual_size =
224 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
225 EXPECT_EQ(actual_size.width, screen_width);
226 EXPECT_EQ(actual_size.height, screen_height);
227 EXPECT_TRUE(
228 InternalFlutterWindows_WindowManager_GetFullscreen(window_handle));
229 }
230
231 TEST_F(WindowManagerTest, CanUnfullscreenWindow) {
232 IsolateScope isolate_scope(isolate());
233
234 const int64_t view_id =
235 InternalFlutterWindows_WindowManager_CreateRegularWindow(
236 engine_id(), creation_request());
237 const HWND window_handle =
238 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
239 view_id);
240
241 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
242 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
243
244 request.fullscreen = false;
245 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
246
247 ActualWindowSize actual_size =
248 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
249 EXPECT_EQ(actual_size.width, 800);
250 EXPECT_EQ(actual_size.height, 600);
251 EXPECT_FALSE(
252 InternalFlutterWindows_WindowManager_GetFullscreen(window_handle));
253 }
254
255 TEST_F(WindowManagerTest, CanSetWindowSizeWhileFullscreen) {
256 IsolateScope isolate_scope(isolate());
257
258 const int64_t view_id =
259 InternalFlutterWindows_WindowManager_CreateRegularWindow(
260 engine_id(), creation_request());
261 const HWND window_handle =
262 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
263 view_id);
264
265 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
266 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
267
268 WindowSizeRequest requestedSize{
269
270 .has_preferred_view_size = true,
271 .preferred_view_width = 500,
272 .preferred_view_height = 500,
273 };
274 InternalFlutterWindows_WindowManager_SetWindowSize(window_handle,
275 &requestedSize);
276
277 request.fullscreen = false;
278 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
279
280 ActualWindowSize actual_size =
281 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
282 EXPECT_EQ(actual_size.width, 500);
283 EXPECT_EQ(actual_size.height, 500);
284 }
285
286 TEST_F(WindowManagerTest, CanSetWindowConstraintsWhileFullscreen) {
287 IsolateScope isolate_scope(isolate());
288
289 const int64_t view_id =
290 InternalFlutterWindows_WindowManager_CreateRegularWindow(
291 engine_id(), creation_request());
292 const HWND window_handle =
293 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
294 view_id);
295
296 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
297 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
298
299 WindowConstraints constraints{.has_view_constraints = true,
300 .view_min_width = 0,
301 .view_min_height = 0,
302 .view_max_width = 500,
303 .view_max_height = 500};
304 InternalFlutterWindows_WindowManager_SetWindowConstraints(window_handle,
305 &constraints);
306
307 request.fullscreen = false;
308 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
309
310 ActualWindowSize actual_size =
311 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
312 EXPECT_EQ(actual_size.width, 500);
313 EXPECT_EQ(actual_size.height, 500);
314 }
315
316 } // namespace testing
317 } // namespace flutter
flutter::Isolate
Definition: isolate_scope.h:15
flutter::Isolate::Current
static Isolate Current()
Definition: isolate_scope.cc:9
flutter::IsolateScope
Definition: isolate_scope.h:33
message
Win32Message message
Definition: keyboard_unittests.cc:137
flutter::testing::TEST_F
TEST_F(CompositorOpenGLTest, CreateBackingStore)
Definition: compositor_opengl_unittests.cc:139
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::ActualWindowSize
Definition: window_manager.h:64
flutter::ActualWindowSize::width
double width
Definition: window_manager.h:65
flutter::ActualWindowSize::height
double height
Definition: window_manager.h:66
flutter::FullscreenRequest
Definition: window_manager.h:69
flutter::FullscreenRequest::fullscreen
bool fullscreen
Definition: window_manager.h:70
flutter::WindowConstraints
Definition: window_manager.h:33
flutter::WindowConstraints::has_view_constraints
bool has_view_constraints
Definition: window_manager.h:34
flutter::WindowSizeRequest
Definition: window_manager.h:26
flutter::WindowSizeRequest::has_preferred_view_size
bool has_preferred_view_size
Definition: window_manager.h:27
flutter::WindowingInitRequest
Definition: window_manager.h:58
flutter::WindowingInitRequest::on_message
void(* on_message)(WindowsMessage *)
Definition: window_manager.h:59
flutter::WindowsMessage
Definition: window_manager.h:48
InternalFlutterWindows_WindowManager_Initialize
void InternalFlutterWindows_WindowManager_Initialize(int64_t engine_id, const flutter::WindowingInitRequest *request)
Definition: window_manager.cc:102
InternalFlutterWindows_WindowManager_SetWindowConstraints
void InternalFlutterWindows_WindowManager_SetWindowConstraints(HWND hwnd, const flutter::WindowConstraints *constraints)
Definition: window_manager.cc:152
InternalFlutterWindows_WindowManager_GetFullscreen
bool InternalFlutterWindows_WindowManager_GetFullscreen(HWND hwnd)
Definition: window_manager.cc:174
InternalFlutterWindows_WindowManager_SetWindowSize
void InternalFlutterWindows_WindowManager_SetWindowSize(HWND hwnd, const flutter::WindowSizeRequest *size)
Definition: window_manager.cc:143
InternalFlutterWindows_WindowManager_SetFullscreen
void InternalFlutterWindows_WindowManager_SetFullscreen(HWND hwnd, const flutter::FullscreenRequest *request)
Definition: window_manager.cc:161
InternalFlutterWindows_WindowManager_GetWindowContentSize
flutter::ActualWindowSize InternalFlutterWindows_WindowManager_GetWindowContentSize(HWND hwnd)
Definition: window_manager.cc:139
InternalFlutterWindows_WindowManager_HasTopLevelWindows
bool InternalFlutterWindows_WindowManager_HasTopLevelWindows(int64_t engine_id)
Definition: window_manager.cc:110
InternalFlutterWindows_WindowManager_CreateRegularWindow
FlutterViewId InternalFlutterWindows_WindowManager_CreateRegularWindow(int64_t engine_id, const flutter::WindowCreationRequest *request)
Definition: window_manager.cc:117
InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle
HWND InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(int64_t engine_id, FlutterViewId view_id)
Definition: window_manager.cc:125
window_manager.h