| 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/flutter_windows_view.h"
6 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
7 #include "flutter/shell/platform/windows/testing/windows_test.h"
8 #include "flutter/shell/platform/windows/window_manager.h"
9 #include "gtest/gtest.h"
10
11 namespace flutter {
12 namespace testing {
13
14 namespace {
15
16 class WindowManagerTest : public WindowsTest {
17 public:
18 WindowManagerTest() = default;
19 virtual ~WindowManagerTest() = default;
20
21 protected:
22 void SetUp() override {
23 auto& context = GetContext();
24 FlutterWindowsEngineBuilder builder(context);
25 ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
26
27 engine_ = builder.Build();
28 ASSERT_TRUE(engine_);
29
30 engine_->SetRootIsolateCreateCallback(context.GetRootIsolateCallback());
31 ASSERT_TRUE(engine_->Run("testWindowController"));
32
33 bool signalled = false;
34 context.AddNativeFunction(
35 "Signal", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
36 isolate_ = flutter::Isolate::Current();
37 signalled = true;
38 }));
39 while (!signalled) {
40 engine_->task_runner()->ProcessTasks();
41 }
42 }
43
44 void TearDown() override { engine_->Stop(); }
45
46 int64_t engine_id() { return reinterpret_cast<int64_t>(engine_.get()); }
47 flutter::Isolate& isolate() { return *isolate_; }
48 RegularWindowCreationRequest* regular_creation_request() {
49 return &regular_creation_request_;
50 }
51 FlutterWindowsEngine* engine() { return engine_.get(); }
52
53 private:
54 std::unique_ptr<FlutterWindowsEngine> engine_;
55 std::optional<flutter::Isolate> isolate_;
56 RegularWindowCreationRequest regular_creation_request_{
57 .preferred_size =
58 {
59 .has_preferred_view_size = true,
60 .preferred_view_width = 800,
61 .preferred_view_height = 600,
62 },
63 };
64
65 FML_DISALLOW_COPY_AND_ASSIGN(WindowManagerTest);
66 };
67
68 } // namespace
69
70 TEST_F(WindowManagerTest, WindowingInitialize) {
71 IsolateScope isolate_scope(isolate());
72
73 static bool received_message = false;
74 WindowingInitRequest init_request{
75 .on_message = [](WindowsMessage* message) { received_message = true; }};
76
77 InternalFlutterWindows_WindowManager_Initialize(engine_id(), &init_request);
78 const int64_t view_id =
79 InternalFlutterWindows_WindowManager_CreateRegularWindow(
80 engine_id(), regular_creation_request());
81 DestroyWindow(InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
82 engine_id(), view_id));
83
84 EXPECT_TRUE(received_message);
85 }
86
87 TEST_F(WindowManagerTest, CreateRegularWindow) {
88 IsolateScope isolate_scope(isolate());
89
90 const int64_t view_id =
91 InternalFlutterWindows_WindowManager_CreateRegularWindow(
92 engine_id(), regular_creation_request());
93 EXPECT_EQ(view_id, 0);
94 }
95
96 TEST_F(WindowManagerTest, GetWindowHandle) {
97 IsolateScope isolate_scope(isolate());
98
99 const int64_t view_id =
100 InternalFlutterWindows_WindowManager_CreateRegularWindow(
101 engine_id(), regular_creation_request());
102 const HWND window_handle =
103 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
104 view_id);
105 EXPECT_NE(window_handle, nullptr);
106 }
107
108 TEST_F(WindowManagerTest, GetWindowSize) {
109 IsolateScope isolate_scope(isolate());
110
111 const int64_t view_id =
112 InternalFlutterWindows_WindowManager_CreateRegularWindow(
113 engine_id(), regular_creation_request());
114 const HWND window_handle =
115 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
116 view_id);
117
118 ActualWindowSize size =
119 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
120
121 EXPECT_EQ(size.width,
122 regular_creation_request()->preferred_size.preferred_view_width);
123 EXPECT_EQ(size.height,
124 regular_creation_request()->preferred_size.preferred_view_height);
125 }
126
127 TEST_F(WindowManagerTest, SetWindowSize) {
128 IsolateScope isolate_scope(isolate());
129
130 const int64_t view_id =
131 InternalFlutterWindows_WindowManager_CreateRegularWindow(
132 engine_id(), regular_creation_request());
133 const HWND window_handle =
134 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
135 view_id);
136
137 WindowSizeRequest requestedSize{
138
139 .has_preferred_view_size = true,
140 .preferred_view_width = 640,
141 .preferred_view_height = 480,
142 };
143 InternalFlutterWindows_WindowManager_SetWindowSize(window_handle,
144 &requestedSize);
145
146 ActualWindowSize actual_size =
147 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
148 EXPECT_EQ(actual_size.width, 640);
149 EXPECT_EQ(actual_size.height, 480);
150 }
151
152 TEST_F(WindowManagerTest, CanConstrainByMinimiumSize) {
153 IsolateScope isolate_scope(isolate());
154
155 const int64_t view_id =
156 InternalFlutterWindows_WindowManager_CreateRegularWindow(
157 engine_id(), regular_creation_request());
158 const HWND window_handle =
159 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
160 view_id);
161 WindowConstraints constraints{.has_view_constraints = true,
162 .view_min_width = 900,
163 .view_min_height = 700,
164 .view_max_width = 10000,
165 .view_max_height = 10000};
166 InternalFlutterWindows_WindowManager_SetWindowConstraints(window_handle,
167 &constraints);
168
169 ActualWindowSize actual_size =
170 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
171 EXPECT_EQ(actual_size.width, 900);
172 EXPECT_EQ(actual_size.height, 700);
173 }
174
175 TEST_F(WindowManagerTest, CanConstrainByMaximumSize) {
176 IsolateScope isolate_scope(isolate());
177
178 const int64_t view_id =
179 InternalFlutterWindows_WindowManager_CreateRegularWindow(
180 engine_id(), regular_creation_request());
181 const HWND window_handle =
182 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
183 view_id);
184 WindowConstraints constraints{.has_view_constraints = true,
185 .view_min_width = 0,
186 .view_min_height = 0,
187 .view_max_width = 500,
188 .view_max_height = 500};
189 InternalFlutterWindows_WindowManager_SetWindowConstraints(window_handle,
190 &constraints);
191
192 ActualWindowSize actual_size =
193 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
194 EXPECT_EQ(actual_size.width, 500);
195 EXPECT_EQ(actual_size.height, 500);
196 }
197
198 TEST_F(WindowManagerTest, CanFullscreenWindow) {
199 IsolateScope isolate_scope(isolate());
200
201 const int64_t view_id =
202 InternalFlutterWindows_WindowManager_CreateRegularWindow(
203 engine_id(), regular_creation_request());
204 const HWND window_handle =
205 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
206 view_id);
207
208 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
209 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
210
211 int screen_width = GetSystemMetrics(SM_CXSCREEN);
212 int screen_height = GetSystemMetrics(SM_CYSCREEN);
213 ActualWindowSize actual_size =
214 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
215 EXPECT_EQ(actual_size.width, screen_width);
216 EXPECT_EQ(actual_size.height, screen_height);
217 EXPECT_TRUE(
218 InternalFlutterWindows_WindowManager_GetFullscreen(window_handle));
219 }
220
221 TEST_F(WindowManagerTest, CanUnfullscreenWindow) {
222 IsolateScope isolate_scope(isolate());
223
224 const int64_t view_id =
225 InternalFlutterWindows_WindowManager_CreateRegularWindow(
226 engine_id(), regular_creation_request());
227 const HWND window_handle =
228 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
229 view_id);
230
231 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
232 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
233
234 request.fullscreen = false;
235 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
236
237 ActualWindowSize actual_size =
238 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
239 EXPECT_EQ(actual_size.width, 800);
240 EXPECT_EQ(actual_size.height, 600);
241 EXPECT_FALSE(
242 InternalFlutterWindows_WindowManager_GetFullscreen(window_handle));
243 }
244
245 TEST_F(WindowManagerTest, CanSetWindowSizeWhileFullscreen) {
246 IsolateScope isolate_scope(isolate());
247
248 const int64_t view_id =
249 InternalFlutterWindows_WindowManager_CreateRegularWindow(
250 engine_id(), regular_creation_request());
251 const HWND window_handle =
252 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
253 view_id);
254
255 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
256 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
257
258 WindowSizeRequest requestedSize{
259
260 .has_preferred_view_size = true,
261 .preferred_view_width = 500,
262 .preferred_view_height = 500,
263 };
264 InternalFlutterWindows_WindowManager_SetWindowSize(window_handle,
265 &requestedSize);
266
267 request.fullscreen = false;
268 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
269
270 ActualWindowSize actual_size =
271 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
272 EXPECT_EQ(actual_size.width, 500);
273 EXPECT_EQ(actual_size.height, 500);
274 }
275
276 TEST_F(WindowManagerTest, CanSetWindowConstraintsWhileFullscreen) {
277 IsolateScope isolate_scope(isolate());
278
279 const int64_t view_id =
280 InternalFlutterWindows_WindowManager_CreateRegularWindow(
281 engine_id(), regular_creation_request());
282 const HWND window_handle =
283 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
284 view_id);
285
286 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
287 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
288
289 WindowConstraints constraints{.has_view_constraints = true,
290 .view_min_width = 0,
291 .view_min_height = 0,
292 .view_max_width = 500,
293 .view_max_height = 500};
294 InternalFlutterWindows_WindowManager_SetWindowConstraints(window_handle,
295 &constraints);
296
297 request.fullscreen = false;
298 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
299
300 ActualWindowSize actual_size =
301 InternalFlutterWindows_WindowManager_GetWindowContentSize(window_handle);
302 EXPECT_EQ(actual_size.width, 500);
303 EXPECT_EQ(actual_size.height, 500);
304 }
305
306 TEST_F(WindowManagerTest, CreateModelessDialogWindow) {
307 IsolateScope isolate_scope(isolate());
308 DialogWindowCreationRequest creation_request{
309 .preferred_size = {.has_preferred_view_size = true,
310 .preferred_view_width = 800,
311 .preferred_view_height = 600},
312 .preferred_constraints = {.has_view_constraints = false},
313 .title = L"Hello World",
314 .parent_or_null = nullptr};
315 const int64_t view_id =
316 InternalFlutterWindows_WindowManager_CreateDialogWindow(
317 engine_id(), &creation_request);
318 EXPECT_EQ(view_id, 0);
319 }
320
321 TEST_F(WindowManagerTest, CreateModalDialogWindow) {
322 IsolateScope isolate_scope(isolate());
323
324 const int64_t parent_view_id =
325 InternalFlutterWindows_WindowManager_CreateRegularWindow(
326 engine_id(), regular_creation_request());
327 const HWND parent_window_handle =
328 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
329 engine_id(), parent_view_id);
330
331 DialogWindowCreationRequest creation_request{
332 .preferred_size =
333 {
334 .has_preferred_view_size = true,
335 .preferred_view_width = 800,
336 .preferred_view_height = 600,
337 },
338 .preferred_constraints = {.has_view_constraints = false},
339 .title = L"Hello World",
340 .parent_or_null = parent_window_handle};
341
342 const int64_t view_id =
343 InternalFlutterWindows_WindowManager_CreateDialogWindow(
344 engine_id(), &creation_request);
345 EXPECT_EQ(view_id, 1);
346
347 const HWND window_handle =
348 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
349 view_id);
350 HostWindow* host_window = HostWindow::GetThisFromHandle(window_handle);
351 EXPECT_EQ(host_window->GetOwnerWindow()->GetWindowHandle(),
352 parent_window_handle);
353 }
354
355 TEST_F(WindowManagerTest, DialogCanNeverBeFullscreen) {
356 IsolateScope isolate_scope(isolate());
357
358 DialogWindowCreationRequest creation_request{
359 .preferred_size = {.has_preferred_view_size = true,
360 .preferred_view_width = 800,
361 .preferred_view_height = 600},
362 .preferred_constraints = {.has_view_constraints = false},
363 .title = L"Hello World",
364 .parent_or_null = nullptr};
365
366 const int64_t view_id =
367 InternalFlutterWindows_WindowManager_CreateDialogWindow(
368 engine_id(), &creation_request);
369 const HWND window_handle =
370 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(engine_id(),
371 view_id);
372
373 FullscreenRequest request{.fullscreen = true, .has_display_id = false};
374 InternalFlutterWindows_WindowManager_SetFullscreen(window_handle, &request);
375 EXPECT_FALSE(
376 InternalFlutterWindows_WindowManager_GetFullscreen(window_handle));
377 }
378
379 TEST_F(WindowManagerTest, CreateTooltipWindow) {
380 IsolateScope isolate_scope(isolate());
381
382 const int64_t parent_view_id =
383 InternalFlutterWindows_WindowManager_CreateRegularWindow(
384 engine_id(), regular_creation_request());
385 const HWND parent_window_handle =
386 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
387 engine_id(), parent_view_id);
388
389 auto position_callback = [](const WindowSize& child_size,
390 const WindowRect& parent_rect,
391 const WindowRect& output_rect) -> WindowRect* {
392 WindowRect* rect = static_cast<WindowRect*>(malloc(sizeof(WindowRect)));
393 rect->left = parent_rect.left + 10;
394 rect->top = parent_rect.top + 10;
395 rect->width = child_size.width;
396 rect->height = child_size.height;
397 return rect;
398 };
399
400 TooltipWindowCreationRequest creation_request{
401 .preferred_constraints = {.has_view_constraints = true,
402 .view_min_width = 100,
403 .view_min_height = 50,
404 .view_max_width = 300,
405 .view_max_height = 200},
406 .parent = parent_window_handle,
407 .get_position_callback = position_callback};
408
409 const int64_t tooltip_view_id =
410 InternalFlutterWindows_WindowManager_CreateTooltipWindow(
411 engine_id(), &creation_request);
412
413 EXPECT_NE(tooltip_view_id, -1);
414 HWND tooltip_window_handle =
415 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
416 engine_id(), tooltip_view_id);
417 EXPECT_NE(tooltip_window_handle, nullptr);
418 }
419
420 TEST_F(WindowManagerTest, TooltipWindowHasNoActivateStyle) {
421 IsolateScope isolate_scope(isolate());
422
423 const int64_t parent_view_id =
424 InternalFlutterWindows_WindowManager_CreateRegularWindow(
425 engine_id(), regular_creation_request());
426 const HWND parent_window_handle =
427 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
428 engine_id(), parent_view_id);
429
430 auto position_callback = [](const WindowSize& child_size,
431 const WindowRect& parent_rect,
432 const WindowRect& output_rect) -> WindowRect* {
433 WindowRect* rect = static_cast<WindowRect*>(malloc(sizeof(WindowRect)));
434 rect->left = parent_rect.left + 10;
435 rect->top = parent_rect.top + 10;
436 rect->width = child_size.width;
437 rect->height = child_size.height;
438 return rect;
439 };
440
441 TooltipWindowCreationRequest creation_request{
442 .preferred_constraints = {.has_view_constraints = true,
443 .view_min_width = 100,
444 .view_min_height = 50,
445 .view_max_width = 300,
446 .view_max_height = 200},
447 .parent = parent_window_handle,
448 .get_position_callback = position_callback};
449
450 const int64_t tooltip_view_id =
451 InternalFlutterWindows_WindowManager_CreateTooltipWindow(
452 engine_id(), &creation_request);
453
454 HWND tooltip_window_handle =
455 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
456 engine_id(), tooltip_view_id);
457
458 DWORD ex_style = GetWindowLong(tooltip_window_handle, GWL_EXSTYLE);
459 EXPECT_TRUE(ex_style & WS_EX_NOACTIVATE);
460 }
461
462 TEST_F(WindowManagerTest, TooltipWindowDoesNotStealFocus) {
463 IsolateScope isolate_scope(isolate());
464
465 const int64_t parent_view_id =
466 InternalFlutterWindows_WindowManager_CreateRegularWindow(
467 engine_id(), regular_creation_request());
468 const HWND parent_window_handle =
469 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
470 engine_id(), parent_view_id);
471
472 // Give focus to the parent window
473 SetFocus(parent_window_handle);
474 HWND focused_before = GetFocus();
475
476 auto position_callback = [](const WindowSize& child_size,
477 const WindowRect& parent_rect,
478 const WindowRect& output_rect) -> WindowRect* {
479 WindowRect* rect = static_cast<WindowRect*>(malloc(sizeof(WindowRect)));
480 rect->left = parent_rect.left + 10;
481 rect->top = parent_rect.top + 10;
482 rect->width = child_size.width;
483 rect->height = child_size.height;
484 return rect;
485 };
486
487 TooltipWindowCreationRequest creation_request{
488 .preferred_constraints = {.has_view_constraints = true,
489 .view_min_width = 100,
490 .view_min_height = 50,
491 .view_max_width = 300,
492 .view_max_height = 200},
493 .parent = parent_window_handle,
494 .get_position_callback = position_callback};
495
496 const int64_t tooltip_view_id =
497 InternalFlutterWindows_WindowManager_CreateTooltipWindow(
498 engine_id(), &creation_request);
499
500 HWND tooltip_window_handle =
501 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
502 engine_id(), tooltip_view_id);
503
504 // Verify focus remains with the parent window
505 HWND focused_after = GetFocus();
506 EXPECT_EQ(focused_before, focused_after);
507 EXPECT_NE(focused_after, tooltip_window_handle);
508 }
509
510 TEST_F(WindowManagerTest, TooltipWindowReturnsNoActivateOnMouseClick) {
511 IsolateScope isolate_scope(isolate());
512
513 const int64_t parent_view_id =
514 InternalFlutterWindows_WindowManager_CreateRegularWindow(
515 engine_id(), regular_creation_request());
516 const HWND parent_window_handle =
517 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
518 engine_id(), parent_view_id);
519
520 auto position_callback = [](const WindowSize& child_size,
521 const WindowRect& parent_rect,
522 const WindowRect& output_rect) -> WindowRect* {
523 WindowRect* rect = static_cast<WindowRect*>(malloc(sizeof(WindowRect)));
524 rect->left = parent_rect.left + 10;
525 rect->top = parent_rect.top + 10;
526 rect->width = child_size.width;
527 rect->height = child_size.height;
528 return rect;
529 };
530
531 TooltipWindowCreationRequest creation_request{
532 .preferred_constraints = {.has_view_constraints = true,
533 .view_min_width = 100,
534 .view_min_height = 50,
535 .view_max_width = 300,
536 .view_max_height = 200},
537 .parent = parent_window_handle,
538 .get_position_callback = position_callback};
539
540 const int64_t tooltip_view_id =
541 InternalFlutterWindows_WindowManager_CreateTooltipWindow(
542 engine_id(), &creation_request);
543
544 HWND tooltip_window_handle =
545 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
546 engine_id(), tooltip_view_id);
547
548 // Send WM_MOUSEACTIVATE message to the tooltip window
549 LRESULT result = SendMessage(tooltip_window_handle, WM_MOUSEACTIVATE,
550 reinterpret_cast<WPARAM>(parent_window_handle),
551 MAKELPARAM(HTCLIENT, WM_LBUTTONDOWN));
552
553 // Verify the tooltip returns MA_NOACTIVATE
554 EXPECT_EQ(result, MA_NOACTIVATE);
555 }
556
557 TEST_F(WindowManagerTest, TooltipWindowUpdatesPositionOnViewSizeChange) {
558 IsolateScope isolate_scope(isolate());
559
560 const int64_t parent_view_id =
561 InternalFlutterWindows_WindowManager_CreateRegularWindow(
562 engine_id(), regular_creation_request());
563 const HWND parent_window_handle =
564 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
565 engine_id(), parent_view_id);
566
567 // Track the child size passed to the callback
568 static int callback_count = 0;
569 static int last_width = 0;
570 static int last_height = 0;
571
572 auto position_callback = [](const WindowSize& child_size,
573 const WindowRect& parent_rect,
574 const WindowRect& output_rect) -> WindowRect* {
575 callback_count++;
576 last_width = child_size.width;
577 last_height = child_size.height;
578
579 // Use malloc since the caller will use free()
580 WindowRect* rect = static_cast<WindowRect*>(malloc(sizeof(WindowRect)));
581 rect->left = parent_rect.left + callback_count * 5;
582 rect->top = parent_rect.top + callback_count * 5;
583 rect->width = child_size.width;
584 rect->height = child_size.height;
585 return rect;
586 };
587
588 TooltipWindowCreationRequest creation_request{
589 .preferred_constraints = {.has_view_constraints = true,
590 .view_min_width = 100,
591 .view_min_height = 50,
592 .view_max_width = 300,
593 .view_max_height = 200},
594 .is_sized_to_content = true,
595 .parent = parent_window_handle,
596 .get_position_callback = position_callback};
597
598 // Reset callback tracking
599 callback_count = 0;
600 last_width = 0;
601 last_height = 0;
602
603 const int64_t tooltip_view_id =
604 InternalFlutterWindows_WindowManager_CreateTooltipWindow(
605 engine_id(), &creation_request);
606
607 HWND tooltip_window_handle =
608 InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(
609 engine_id(), tooltip_view_id);
610
611 // Get the view associated with the tooltip window
612 FlutterWindowsView* view =
613 engine()->GetViewFromTopLevelWindow(tooltip_window_handle);
614 ASSERT_NE(view, nullptr);
615
616 // Get initial position
617 RECT initial_rect;
618 GetWindowRect(tooltip_window_handle, &initial_rect);
619 int initial_callback_count = callback_count;
620
621 // Simulate a frame being generated with new dimensions
622 // This should trigger DidUpdateViewSize which calls UpdatePosition
623 view->OnFrameGenerated(150, 100);
624
625 // Process any pending tasks to ensure the callback is executed
626 engine()->task_runner()->ProcessTasks();
627
628 // Verify the callback was called again with the new dimensions
629 EXPECT_GT(callback_count, initial_callback_count);
630 EXPECT_EQ(last_width, 150);
631 EXPECT_EQ(last_height, 100);
632
633 // Get new position and verify it changed
634 RECT new_rect;
635 GetWindowRect(tooltip_window_handle, &new_rect);
636
637 // The position should have changed due to our callback logic
638 // (we offset by callback_count * 5)
639 EXPECT_NE(initial_rect.left, new_rect.left);
640 EXPECT_NE(initial_rect.top, new_rect.top);
641 }
642
643 } // namespace testing
644 } // namespace flutter
flutter::FlutterWindowsView
Definition: flutter_windows_view.h:46
flutter::FlutterWindowsView::OnFrameGenerated
bool OnFrameGenerated(size_t width, size_t height)
Definition: flutter_windows_view.cc:159
flutter::HostWindow
Definition: host_window.h:29
flutter::HostWindow::GetWindowHandle
HWND GetWindowHandle() const
Definition: host_window.cc:350
flutter::HostWindow::GetOwnerWindow
HostWindow * GetOwnerWindow() const
Definition: host_window.cc:829
flutter::HostWindow::GetThisFromHandle
static HostWindow * GetThisFromHandle(HWND hwnd)
Definition: host_window.cc:335
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
flutter_windows_view.h
message
Win32Message message
Definition: keyboard_unittests.cc:137
flutter::testing::TEST_F
TEST_F(AccessibilityPluginTest, DirectAnnounceCall)
Definition: accessibility_plugin_unittests.cc:102
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::ActualWindowSize
Definition: window_manager.h:96
flutter::ActualWindowSize::width
double width
Definition: window_manager.h:97
flutter::ActualWindowSize::height
double height
Definition: window_manager.h:98
flutter::DialogWindowCreationRequest
Definition: window_manager.h:62
flutter::DialogWindowCreationRequest::preferred_size
WindowSizeRequest preferred_size
Definition: window_manager.h:63
flutter::FullscreenRequest
Definition: window_manager.h:101
flutter::FullscreenRequest::fullscreen
bool fullscreen
Definition: window_manager.h:102
flutter::TooltipWindowCreationRequest
Definition: window_manager.h:73
flutter::TooltipWindowCreationRequest::preferred_constraints
WindowConstraints preferred_constraints
Definition: window_manager.h:74
flutter::WindowConstraints
Definition: window_manager.h:33
flutter::WindowConstraints::has_view_constraints
bool has_view_constraints
Definition: window_manager.h:34
flutter::WindowRect
Definition: window_manager.h:42
flutter::WindowRect::left
int32_t left
Definition: window_manager.h:43
flutter::WindowRect::height
int32_t height
Definition: window_manager.h:46
flutter::WindowRect::top
int32_t top
Definition: window_manager.h:44
flutter::WindowRect::width
int32_t width
Definition: window_manager.h:45
flutter::WindowSize
Definition: window_manager.h:50
flutter::WindowSize::width
int32_t width
Definition: window_manager.h:51
flutter::WindowSize::height
int32_t height
Definition: window_manager.h:52
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:90
flutter::WindowingInitRequest::on_message
void(* on_message)(WindowsMessage *)
Definition: window_manager.h:91
flutter::WindowsMessage
Definition: window_manager.h:80
InternalFlutterWindows_WindowManager_Initialize
void InternalFlutterWindows_WindowManager_Initialize(int64_t engine_id, const flutter::WindowingInitRequest *request)
Definition: window_manager.cc:132
InternalFlutterWindows_WindowManager_SetWindowConstraints
void InternalFlutterWindows_WindowManager_SetWindowConstraints(HWND hwnd, const flutter::WindowConstraints *constraints)
Definition: window_manager.cc:213
InternalFlutterWindows_WindowManager_GetFullscreen
bool InternalFlutterWindows_WindowManager_GetFullscreen(HWND hwnd)
Definition: window_manager.cc:235
InternalFlutterWindows_WindowManager_SetWindowSize
void InternalFlutterWindows_WindowManager_SetWindowSize(HWND hwnd, const flutter::WindowSizeRequest *size)
Definition: window_manager.cc:184
InternalFlutterWindows_WindowManager_CreateRegularWindow
FlutterViewId InternalFlutterWindows_WindowManager_CreateRegularWindow(int64_t engine_id, const flutter::RegularWindowCreationRequest *request)
Definition: window_manager.cc:140
InternalFlutterWindows_WindowManager_CreateDialogWindow
FLUTTER_EXPORT FlutterViewId InternalFlutterWindows_WindowManager_CreateDialogWindow(int64_t engine_id, const flutter::DialogWindowCreationRequest *request)
Definition: window_manager.cc:149
InternalFlutterWindows_WindowManager_SetFullscreen
void InternalFlutterWindows_WindowManager_SetFullscreen(HWND hwnd, const flutter::FullscreenRequest *request)
Definition: window_manager.cc:222
InternalFlutterWindows_WindowManager_GetWindowContentSize
flutter::ActualWindowSize InternalFlutterWindows_WindowManager_GetWindowContentSize(HWND hwnd)
Definition: window_manager.cc:180
InternalFlutterWindows_WindowManager_CreateTooltipWindow
FLUTTER_EXPORT FlutterViewId InternalFlutterWindows_WindowManager_CreateTooltipWindow(int64_t engine_id, const flutter::TooltipWindowCreationRequest *request)
Definition: window_manager.cc:158
InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle
HWND InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(int64_t engine_id, FlutterViewId view_id)
Definition: window_manager.cc:166
window_manager.h