4 #include "flutter/fml/macros.h"
6 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
7 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler_delegate.h"
8 #include "flutter/shell/platform/windows/testing/mock_windows_proc_table.h"
9 #include "flutter/shell/platform/windows/testing/windows_test.h"
10 #include "flutter/shell/platform/windows/testing/wm_builders.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
19 using ::testing::AnyNumber;
21 using ::testing::Invoke;
22 using ::testing::Return;
25 static constexpr int32_t kDefaultPointerDeviceId = 0;
27 class MockFlutterWindow :
public FlutterWindow {
29 explicit MockFlutterWindow(
bool reset_view_on_exit =
true)
30 : reset_view_on_exit_(reset_view_on_exit) {
31 ON_CALL(*
this, GetDpiScale())
36 MockFlutterWindow(
int width,
38 std::shared_ptr<WindowsProcTable> proc_table =
nullptr)
39 : FlutterWindow(width, height, nullptr, std::move(proc_table)) {}
41 virtual ~MockFlutterWindow() {
42 if (reset_view_on_exit_) {
48 UINT GetDpi() {
return GetCurrentDPI(); }
50 LRESULT InjectWindowMessage(UINT
const message,
52 LPARAM
const lparam) {
53 return HandleMessage(
message, wparam, lparam);
56 MOCK_METHOD(
void, OnDpiScale, (
unsigned int), (
override));
57 MOCK_METHOD(
void, OnResize, (
unsigned int,
unsigned int), (
override));
58 MOCK_METHOD(
float, GetScrollOffsetMultiplier, (), (
override));
59 MOCK_METHOD(
float, GetDpiScale, (), (
override));
60 MOCK_METHOD(
void, UpdateCursorRect, (
const Rect&), (
override));
61 MOCK_METHOD(
void, OnResetImeComposing, (), (
override));
62 MOCK_METHOD(UINT, Win32DispatchMessage, (UINT, WPARAM, LPARAM), (
override));
63 MOCK_METHOD(BOOL, Win32PeekMessage, (LPMSG, UINT, UINT, UINT), (
override));
64 MOCK_METHOD(uint32_t, Win32MapVkToChar, (uint32_t), (
override));
65 MOCK_METHOD(HWND, GetWindowHandle, (), (
override));
66 MOCK_METHOD(ui::AXFragmentRootDelegateWin*,
67 GetAxFragmentRootDelegate,
74 LRESULT Win32DefWindowProc(HWND hWnd,
77 LPARAM lParam)
override {
78 return kWmResultDefault;
82 bool reset_view_on_exit_;
83 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindow);
86 LRESULT InjectPointerMessageWithClientPoint(MockFlutterWindow& window,
91 HWND flutter_window = window.FlutterWindow::GetWindowHandle();
93 CreateWindowEx(0, L
"STATIC", L
"", WS_POPUP, 100, 100, 300, 300,
nullptr,
94 nullptr, GetModuleHandle(
nullptr),
nullptr);
95 EXPECT_NE(parent_window,
nullptr);
96 EXPECT_NE(SetParent(flutter_window, parent_window),
nullptr);
97 EXPECT_TRUE(SetWindowPos(flutter_window,
nullptr, 0, 0, 100, 100,
98 SWP_NOZORDER | SWP_NOACTIVATE));
100 POINT point = {x, y};
101 EXPECT_TRUE(ClientToScreen(flutter_window, &point));
103 window.InjectWindowMessage(
message, wparam, MAKELPARAM(point.x, point.y));
105 EXPECT_NE(SetParent(flutter_window, HWND_MESSAGE),
nullptr);
106 DestroyWindow(parent_window);
110 class MockFlutterWindowsView :
public FlutterWindowsView {
113 std::unique_ptr<WindowBindingHandler> window_binding)
116 std::move(window_binding),
122 NotifyWinEventWrapper,
123 (ui::AXPlatformNodeWin*, ax::mojom::Event),
127 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
130 class FlutterWindowTest :
public WindowsTest {};
134 TEST_F(FlutterWindowTest, CreateDestroy) {
135 std::unique_ptr<FlutterWindowsEngine> engine =
136 FlutterWindowsEngineBuilder{GetContext()}.Build();
141 TEST_F(FlutterWindowTest, OnBitmapSurfaceUpdated) {
142 std::unique_ptr<FlutterWindowsEngine> engine =
143 FlutterWindowsEngineBuilder{GetContext()}.Build();
144 FlutterWindow win32window(100, 100, engine->display_manager());
145 int old_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
147 constexpr
size_t row_bytes = 100 * 4;
148 constexpr
size_t height = 100;
149 std::array<char, row_bytes * height> allocation;
152 int new_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
154 EXPECT_EQ(old_handle_count, new_handle_count);
160 TEST_F(FlutterWindowTest, OnCursorRectUpdatedRegularDPI) {
161 MockFlutterWindow win32window;
162 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.0));
164 Rect cursor_rect(Point(10, 20), Size(30, 40));
165 EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);
167 win32window.OnCursorRectUpdated(cursor_rect);
173 TEST_F(FlutterWindowTest, OnCursorRectUpdatedHighDPI) {
174 MockFlutterWindow win32window;
175 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.5));
177 Rect expected_cursor_rect(Point(15, 30), Size(45, 60));
178 EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);
180 Rect cursor_rect(Point(10, 20), Size(30, 40));
181 win32window.OnCursorRectUpdated(cursor_rect);
184 TEST_F(FlutterWindowTest, OnPointerStarSendsDeviceType) {
185 std::unique_ptr<FlutterWindowsEngine> engine =
186 FlutterWindowsEngineBuilder{GetContext()}.Build();
187 FlutterWindow win32window(100, 100, engine->display_manager());
188 MockWindowBindingHandlerDelegate delegate;
189 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
190 win32window.
SetView(&delegate);
193 EXPECT_CALL(delegate,
194 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
195 kDefaultPointerDeviceId, 0, 0, 0, 0))
197 EXPECT_CALL(delegate,
198 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
199 kDefaultPointerDeviceId, 0, 0, 0, 0))
201 EXPECT_CALL(delegate,
202 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
203 kDefaultPointerDeviceId, 0, 0, 0, 0))
207 EXPECT_CALL(delegate,
208 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
209 kDefaultPointerDeviceId,
210 kFlutterPointerButtonMousePrimary, 0, 0))
212 EXPECT_CALL(delegate,
213 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
214 kDefaultPointerDeviceId,
215 kFlutterPointerButtonMousePrimary, 0, 0))
217 EXPECT_CALL(delegate,
218 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
219 kDefaultPointerDeviceId,
220 kFlutterPointerButtonMousePrimary, 0, 0))
224 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
225 kDefaultPointerDeviceId,
226 kFlutterPointerButtonMousePrimary))
228 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
229 kDefaultPointerDeviceId,
230 kFlutterPointerButtonMousePrimary))
232 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
233 kDefaultPointerDeviceId,
234 kFlutterPointerButtonMousePrimary))
238 EXPECT_CALL(delegate,
239 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
240 kDefaultPointerDeviceId))
242 EXPECT_CALL(delegate,
243 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
244 kDefaultPointerDeviceId))
246 EXPECT_CALL(delegate,
247 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
248 kDefaultPointerDeviceId))
251 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
252 kDefaultPointerDeviceId, 0, 0, 0, 0);
253 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
254 kDefaultPointerDeviceId,
255 kFlutterPointerButtonMousePrimary, 0, 0);
256 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
257 kDefaultPointerDeviceId,
258 kFlutterPointerButtonMousePrimary);
259 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
260 kDefaultPointerDeviceId);
263 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
264 kDefaultPointerDeviceId, 0, 0, 0, 0);
265 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
266 kDefaultPointerDeviceId,
267 kFlutterPointerButtonMousePrimary, 0, 0);
268 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
269 kDefaultPointerDeviceId,
270 kFlutterPointerButtonMousePrimary);
271 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
272 kDefaultPointerDeviceId);
275 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
276 kDefaultPointerDeviceId, 0, 0, 0, 0);
277 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
278 kDefaultPointerDeviceId,
279 kFlutterPointerButtonMousePrimary, 0, 0);
280 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
281 kDefaultPointerDeviceId,
282 kFlutterPointerButtonMousePrimary);
283 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
284 kDefaultPointerDeviceId);
291 TEST_F(FlutterWindowTest, OnStylusPointerDown) {
292 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
295 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
296 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
297 if (pointer_info !=
nullptr) {
298 pointer_info->pointerType = PT_PEN;
299 pointer_info->pointerId = pointer_id;
300 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT;
305 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
306 .WillRepeatedly([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
307 if (pen_info !=
nullptr) {
308 pen_info->pressure = 720;
309 pen_info->rotation = 10;
310 pen_info->penFlags = 0;
315 POINTER_INFO test_pointer_info = {};
316 BOOL result = mock_proc_table->GetPointerInfo(1, &test_pointer_info);
318 MockFlutterWindow win32window(100, 100, mock_proc_table);
319 MockWindowBindingHandlerDelegate delegate;
321 win32window.SetView(&delegate);
323 EXPECT_CALL(delegate,
324 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
325 kDefaultPointerDeviceId,
326 kFlutterPointerButtonStylusContact, 10, 720))
329 UINT32 pointerId = 1;
330 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
331 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
335 TEST_F(FlutterWindowTest, OnStylusPointerMove) {
336 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
338 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
339 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
340 if (pointer_info !=
nullptr) {
341 pointer_info->pointerType = PT_PEN;
342 pointer_info->pointerId = pointer_id;
343 pointer_info->pointerFlags =
344 POINTER_FLAG_INCONTACT | POINTER_FLAG_UPDATE;
349 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
350 .WillRepeatedly([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
351 if (pen_info !=
nullptr) {
352 pen_info->pressure = 720;
353 pen_info->rotation = 10;
354 pen_info->penFlags = 0;
359 MockFlutterWindow win32window(100, 100, mock_proc_table);
360 MockWindowBindingHandlerDelegate delegate;
361 win32window.SetView(&delegate);
363 EXPECT_CALL(delegate,
364 OnPointerMove(15, 20, kFlutterPointerDeviceKindStylus,
365 kDefaultPointerDeviceId,
366 kFlutterPointerButtonStylusContact, 10, 720, 0))
369 UINT32 pointerId = 1;
370 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
371 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 15,
375 TEST_F(FlutterWindowTest, OnStylusPointerUp) {
376 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
378 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
379 .WillOnce([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
380 if (pointer_info !=
nullptr) {
381 pointer_info->pointerType = PT_PEN;
382 pointer_info->pointerId = pointer_id;
383 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT;
387 .WillOnce([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
388 if (pointer_info !=
nullptr) {
389 pointer_info->pointerType = PT_PEN;
390 pointer_info->pointerId = pointer_id;
391 pointer_info->pointerFlags = POINTER_FLAG_UP;
396 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
397 .WillRepeatedly([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
398 if (pen_info !=
nullptr) {
399 pen_info->pressure = 720;
400 pen_info->rotation = 0;
401 pen_info->penFlags = 0;
406 MockFlutterWindow win32window(100, 100, mock_proc_table);
407 MockWindowBindingHandlerDelegate delegate;
408 win32window.SetView(&delegate);
410 EXPECT_CALL(delegate,
411 OnPointerDown(25, 30, kFlutterPointerDeviceKindStylus,
412 kDefaultPointerDeviceId,
413 kFlutterPointerButtonStylusContact, 0, 720))
415 EXPECT_CALL(delegate, OnPointerUp(25, 30, kFlutterPointerDeviceKindStylus,
416 kDefaultPointerDeviceId, 0))
419 UINT32 pointerId = 1;
420 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
421 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 25,
423 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUP, wparam, 25,
427 TEST_F(FlutterWindowTest, OnStylusPointerLeave) {
428 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
430 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
431 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
432 if (pointer_info !=
nullptr) {
433 pointer_info->pointerType = PT_PEN;
434 pointer_info->pointerId = pointer_id;
435 pointer_info->pointerFlags = POINTER_FLAG_UP;
440 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
441 .WillRepeatedly([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
442 if (pen_info !=
nullptr) {
443 pen_info->pressure = 720;
444 pen_info->rotation = 0;
445 pen_info->penFlags = 0;
450 MockFlutterWindow win32window(100, 100, mock_proc_table);
451 MockWindowBindingHandlerDelegate delegate;
452 win32window.SetView(&delegate);
454 EXPECT_CALL(delegate, OnPointerLeave(35, 40, kFlutterPointerDeviceKindStylus,
455 kDefaultPointerDeviceId))
458 UINT32 pointerId = 1;
459 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
460 InjectPointerMessageWithClientPoint(win32window, WM_POINTERLEAVE, wparam, 35,
464 TEST_F(FlutterWindowTest, OnStylusPointerHover) {
467 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
469 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
470 .WillOnce([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
471 if (pointer_info !=
nullptr) {
472 pointer_info->pointerId = 1;
473 pointer_info->pointerType = PT_PEN;
474 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT;
475 pointer_info->ptPixelLocation.x = 45;
476 pointer_info->ptPixelLocation.y = 50;
480 .WillOnce([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
481 if (pointer_info !=
nullptr) {
482 pointer_info->pointerId = 1;
483 pointer_info->pointerType = PT_PEN;
485 pointer_info->pointerFlags = POINTER_FLAG_UPDATE;
486 pointer_info->ptPixelLocation.x = 45;
487 pointer_info->ptPixelLocation.y = 50;
492 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
493 .WillRepeatedly([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
494 if (pen_info !=
nullptr) {
495 pen_info->pressure = 0;
496 pen_info->rotation = 0;
497 pen_info->penFlags = 0;
502 MockFlutterWindow win32window(100, 100, mock_proc_table);
503 MockWindowBindingHandlerDelegate delegate;
504 win32window.SetView(&delegate);
507 EXPECT_CALL(delegate,
508 OnPointerDown(45, 50, kFlutterPointerDeviceKindStylus, 0,
509 kFlutterPointerButtonStylusContact, 0, 0))
512 UINT32 pointerId = 1;
513 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
514 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 45,
518 EXPECT_CALL(delegate, OnPointerMove(45, 50, kFlutterPointerDeviceKindStylus,
523 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 45,
527 TEST_F(FlutterWindowTest, OnStylusHoverAfterPointerUp) {
528 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
530 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
531 .WillOnce([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
532 if (pointer_info !=
nullptr) {
533 pointer_info->pointerType = PT_PEN;
534 pointer_info->pointerId = pointer_id;
535 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT;
539 .WillOnce([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
540 if (pointer_info !=
nullptr) {
541 pointer_info->pointerType = PT_PEN;
542 pointer_info->pointerId = pointer_id;
543 pointer_info->pointerFlags = POINTER_FLAG_UP;
547 .WillOnce([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
548 if (pointer_info !=
nullptr) {
549 pointer_info->pointerType = PT_PEN;
550 pointer_info->pointerId = pointer_id;
551 pointer_info->pointerFlags = POINTER_FLAG_UPDATE;
556 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
557 .WillRepeatedly([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
558 if (pen_info !=
nullptr) {
559 pen_info->pressure = 720;
560 pen_info->rotation = 0;
561 pen_info->penFlags = 0;
566 MockFlutterWindow win32window(100, 100, mock_proc_table);
567 MockWindowBindingHandlerDelegate delegate;
568 win32window.SetView(&delegate);
570 EXPECT_CALL(delegate,
571 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
572 kDefaultPointerDeviceId,
573 kFlutterPointerButtonStylusContact, 0, 720))
575 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
576 kDefaultPointerDeviceId, 0))
578 EXPECT_CALL(delegate,
579 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
580 kDefaultPointerDeviceId, 0, 0, 720, 0))
583 UINT32 pointerId = 1;
584 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
585 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
587 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUP, wparam, 10,
589 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 10,
593 TEST_F(FlutterWindowTest, OnStylusBarrelButtonUsesPenFlags) {
594 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
596 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
597 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
598 if (pointer_info !=
nullptr) {
599 pointer_info->pointerType = PT_PEN;
600 pointer_info->pointerId = pointer_id;
601 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT;
606 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
607 .WillRepeatedly([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
608 if (pen_info !=
nullptr) {
609 pen_info->pressure = 720;
610 pen_info->rotation = 0;
611 pen_info->penFlags = PEN_FLAG_BARREL;
616 MockFlutterWindow win32window(100, 100, mock_proc_table);
617 MockWindowBindingHandlerDelegate delegate;
618 win32window.SetView(&delegate);
620 EXPECT_CALL(delegate,
621 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
622 kDefaultPointerDeviceId,
623 kFlutterPointerButtonStylusContact |
624 kFlutterPointerButtonStylusPrimary,
628 UINT32 pointerId = 1;
629 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
630 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
634 TEST_F(FlutterWindowTest, OnStylusEraserButtonUsesPenFlags) {
635 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
637 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
638 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
639 if (pointer_info !=
nullptr) {
640 pointer_info->pointerType = PT_PEN;
641 pointer_info->pointerId = pointer_id;
642 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT;
647 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
648 .WillRepeatedly([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
649 if (pen_info !=
nullptr) {
650 pen_info->pressure = 720;
651 pen_info->rotation = 0;
652 pen_info->penFlags = PEN_FLAG_ERASER;
657 MockFlutterWindow win32window(100, 100, mock_proc_table);
658 MockWindowBindingHandlerDelegate delegate;
659 win32window.SetView(&delegate);
661 EXPECT_CALL(delegate,
662 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
663 kDefaultPointerDeviceId,
664 kFlutterPointerButtonStylusContact |
665 kFlutterPointerButtonStylusSecondary,
669 UINT32 pointerId = 1;
670 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
671 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
675 TEST_F(FlutterWindowTest, OnInvertedStylusPointerDownUsesDeviceKind) {
676 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
678 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
679 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
680 if (pointer_info !=
nullptr) {
681 pointer_info->pointerType = PT_PEN;
682 pointer_info->pointerId = pointer_id;
683 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT;
688 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
689 .WillRepeatedly([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
690 if (pen_info !=
nullptr) {
691 pen_info->pressure = 720;
692 pen_info->rotation = 0;
693 pen_info->penFlags = PEN_FLAG_INVERTED;
698 MockFlutterWindow win32window(100, 100, mock_proc_table);
699 MockWindowBindingHandlerDelegate delegate;
700 win32window.SetView(&delegate);
702 EXPECT_CALL(delegate,
703 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindInvertedStylus,
704 kDefaultPointerDeviceId,
705 kFlutterPointerButtonStylusContact, 0, 720))
708 UINT32 pointerId = 1;
709 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
710 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
714 TEST_F(FlutterWindowTest, OnStylusBarrelButtonUpdateMovesWithUpdatedButtons) {
715 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
717 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
718 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
719 if (pointer_info !=
nullptr) {
720 pointer_info->pointerType = PT_PEN;
721 pointer_info->pointerId = pointer_id;
722 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT;
727 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
728 .WillOnce([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
729 if (pen_info !=
nullptr) {
730 pen_info->pressure = 720;
731 pen_info->rotation = 0;
732 pen_info->penFlags = 0;
736 .WillOnce([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
737 if (pen_info !=
nullptr) {
738 pen_info->pressure = 720;
739 pen_info->rotation = 0;
740 pen_info->penFlags = PEN_FLAG_BARREL;
745 MockFlutterWindow win32window(100, 100, mock_proc_table);
746 MockWindowBindingHandlerDelegate delegate;
747 win32window.SetView(&delegate);
749 EXPECT_CALL(delegate,
750 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
751 kDefaultPointerDeviceId,
752 kFlutterPointerButtonStylusContact, 0, 720))
754 EXPECT_CALL(delegate,
755 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
756 kDefaultPointerDeviceId,
757 kFlutterPointerButtonStylusContact |
758 kFlutterPointerButtonStylusPrimary,
762 UINT32 pointerId = 1;
763 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
764 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
766 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 10,
770 TEST_F(FlutterWindowTest, OnStylusBarrelButtonUpdateMovesWithReleasedButton) {
771 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
773 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
774 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
775 if (pointer_info !=
nullptr) {
776 pointer_info->pointerType = PT_PEN;
777 pointer_info->pointerId = pointer_id;
778 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT;
783 EXPECT_CALL(*mock_proc_table, GetPointerPenInfo(_, _))
784 .WillOnce([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
785 if (pen_info !=
nullptr) {
786 pen_info->pressure = 720;
787 pen_info->rotation = 0;
788 pen_info->penFlags = PEN_FLAG_BARREL;
792 .WillOnce([](UINT32 pointer_id, POINTER_PEN_INFO* pen_info) {
793 if (pen_info !=
nullptr) {
794 pen_info->pressure = 720;
795 pen_info->rotation = 0;
796 pen_info->penFlags = 0;
801 MockFlutterWindow win32window(100, 100, mock_proc_table);
802 MockWindowBindingHandlerDelegate delegate;
803 win32window.SetView(&delegate);
805 EXPECT_CALL(delegate,
806 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
807 kDefaultPointerDeviceId,
808 kFlutterPointerButtonStylusContact |
809 kFlutterPointerButtonStylusPrimary,
812 EXPECT_CALL(delegate,
813 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
814 kDefaultPointerDeviceId,
815 kFlutterPointerButtonStylusContact, 0, 720, 0))
818 UINT32 pointerId = 1;
819 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
820 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
822 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 10,
826 TEST_F(FlutterWindowTest, OnMousePointerDown) {
827 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
829 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
830 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
831 if (pointer_info !=
nullptr) {
832 pointer_info->pointerType = PT_MOUSE;
833 pointer_info->pointerId = pointer_id;
834 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT |
835 POINTER_FLAG_FIRSTBUTTON |
841 MockFlutterWindow win32window(100, 100, mock_proc_table);
842 MockWindowBindingHandlerDelegate delegate;
843 win32window.SetView(&delegate);
845 EXPECT_CALL(delegate, OnPointerDown(45, 50, kFlutterPointerDeviceKindMouse,
846 kDefaultPointerDeviceId,
847 kFlutterPointerButtonMousePrimary, 0, 0))
850 UINT32 pointerId = 1;
851 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
852 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 45,
856 TEST_F(FlutterWindowTest, OnTouchPointerDown) {
857 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
859 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
860 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
861 if (pointer_info !=
nullptr) {
862 pointer_info->pointerType = PT_TOUCH;
863 pointer_info->pointerId = pointer_id;
864 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT |
865 POINTER_FLAG_FIRSTBUTTON |
871 MockFlutterWindow win32window(100, 100, mock_proc_table);
872 MockWindowBindingHandlerDelegate delegate;
873 win32window.SetView(&delegate);
875 EXPECT_CALL(delegate, OnPointerDown(55, 60, kFlutterPointerDeviceKindTouch,
876 kDefaultPointerDeviceId,
877 kFlutterPointerButtonMousePrimary, 0, 0))
880 UINT32 pointerId = 1;
881 WPARAM wparam =
static_cast<WPARAM
>(pointerId);
882 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 55,
886 TEST_F(FlutterWindowTest, PointerMessageScreenCoordinatesAreConvertedToClient) {
887 constexpr
int kClientX = 15;
888 constexpr
int kClientY = 20;
890 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
892 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
893 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
894 if (pointer_info !=
nullptr) {
895 pointer_info->pointerType = PT_TOUCH;
896 pointer_info->pointerId = pointer_id;
897 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT |
898 POINTER_FLAG_FIRSTBUTTON |
904 MockFlutterWindow win32window(100, 100, mock_proc_table);
905 MockWindowBindingHandlerDelegate delegate;
906 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
907 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
908 win32window.SetView(&delegate);
911 CreateWindowEx(0, L
"STATIC", L
"", WS_POPUP, 100, 100, 300, 300,
nullptr,
912 nullptr, GetModuleHandle(
nullptr),
nullptr);
913 ASSERT_NE(parent_window,
nullptr);
915 HWND flutter_window = win32window.FlutterWindow::GetWindowHandle();
916 ASSERT_NE(flutter_window,
nullptr);
917 ASSERT_NE(SetParent(flutter_window, parent_window),
nullptr);
918 ASSERT_TRUE(SetWindowPos(flutter_window,
nullptr, 25, 35, 100, 100,
919 SWP_NOZORDER | SWP_NOACTIVATE));
921 POINT pointer_point = {kClientX, kClientY};
922 ASSERT_TRUE(ClientToScreen(flutter_window, &pointer_point));
924 EXPECT_CALL(delegate,
925 OnPointerDown(kClientX, kClientY, kFlutterPointerDeviceKindTouch,
926 kDefaultPointerDeviceId,
927 kFlutterPointerButtonMousePrimary, 0, 0))
930 win32window.InjectWindowMessage(WM_POINTERDOWN, 1,
931 MAKELPARAM(pointer_point.x, pointer_point.y));
933 EXPECT_NE(SetParent(flutter_window, HWND_MESSAGE),
nullptr);
934 DestroyWindow(parent_window);
939 TEST_F(FlutterWindowTest, OnScrollCallsGetScrollOffsetMultiplier) {
940 MockFlutterWindow win32window;
941 MockWindowBindingHandlerDelegate delegate;
942 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
943 win32window.SetView(&delegate);
945 EXPECT_CALL(win32window, GetWindowHandle).WillOnce([&win32window]() {
946 return win32window.FlutterWindow::GetWindowHandle();
948 EXPECT_CALL(win32window, GetScrollOffsetMultiplier).WillOnce(Return(120.0f));
950 EXPECT_CALL(delegate,
951 OnScroll(_, _, 0, 0, 120.0f, kFlutterPointerDeviceKindMouse,
952 kDefaultPointerDeviceId))
955 win32window.OnScroll(0.0f, 0.0f, kFlutterPointerDeviceKindMouse,
956 kDefaultPointerDeviceId);
959 TEST_F(FlutterWindowTest, OnWindowRepaint) {
960 MockFlutterWindow win32window;
961 MockWindowBindingHandlerDelegate delegate;
962 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
963 win32window.SetView(&delegate);
965 EXPECT_CALL(delegate, OnWindowRepaint()).Times(1);
967 win32window.InjectWindowMessage(WM_PAINT, 0, 0);
970 TEST_F(FlutterWindowTest, OnThemeChange) {
971 MockFlutterWindow win32window;
972 MockWindowBindingHandlerDelegate delegate;
973 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
974 win32window.SetView(&delegate);
976 EXPECT_CALL(delegate, OnHighContrastChanged).Times(1);
978 win32window.InjectWindowMessage(WM_THEMECHANGED, 0, 0);
984 TEST_F(FlutterWindowTest, AccessibilityNodeWithoutView) {
985 MockFlutterWindow win32window;
987 EXPECT_EQ(win32window.GetNativeViewAccessible(),
nullptr);
993 std::unique_ptr<FlutterWindowsEngine> engine =
994 FlutterWindowsEngineBuilder{GetContext()}.Build();
995 auto win32window = std::make_unique<MockFlutterWindow>();
996 EXPECT_CALL(*win32window.get(), GetAxFragmentRootDelegate())
997 .WillRepeatedly(Return(
nullptr));
998 EXPECT_CALL(*win32window.get(), OnWindowStateEvent).Times(AnyNumber());
999 EXPECT_CALL(*win32window.get(), GetWindowHandle).Times(AnyNumber());
1000 MockFlutterWindowsView view{engine.get(), std::move(win32window)};
1001 std::wstring
message = L
"Test alert";
1002 EXPECT_CALL(view, NotifyWinEventWrapper(_, ax::mojom::Event::kAlert))
1007 VARIANT
self{.vt = VT_I4, .lVal = CHILDID_SELF};
1009 alert->get_accName(
self, &strptr);
1012 alert->get_accDescription(
self, &strptr);
1015 alert->get_accValue(
self, &strptr);
1019 alert->get_accRole(
self, &role);
1020 EXPECT_EQ(role.vt, VT_I4);
1021 EXPECT_EQ(role.lVal, ROLE_SYSTEM_ALERT);
1024 TEST_F(FlutterWindowTest, LifecycleFocusMessages) {
1025 MockFlutterWindow win32window;
1026 EXPECT_CALL(win32window, GetWindowHandle)
1027 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
1028 MockWindowBindingHandlerDelegate delegate;
1031 EXPECT_CALL(delegate, OnWindowStateEvent)
1035 EXPECT_CALL(win32window, OnWindowStateEvent)
1037 win32window.FlutterWindow::OnWindowStateEvent(event);
1039 EXPECT_CALL(win32window, OnResize).Times(AnyNumber());
1041 win32window.SetView(&delegate);
1043 win32window.InjectWindowMessage(WM_SIZE, 0, 0);
1046 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
1049 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kFocused),
1050 Eq(FlutterViewFocusDirection::kUndefined)))
1052 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
1055 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kUnfocused),
1056 Eq(FlutterViewFocusDirection::kUndefined)))
1058 win32window.InjectWindowMessage(WM_KILLFOCUS, 0, 0);
1062 TEST_F(FlutterWindowTest, CachedLifecycleMessage) {
1063 MockFlutterWindow win32window;
1064 EXPECT_CALL(win32window, GetWindowHandle)
1065 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
1066 EXPECT_CALL(win32window, OnWindowStateEvent)
1068 win32window.FlutterWindow::OnWindowStateEvent(event);
1070 EXPECT_CALL(win32window, OnResize).Times(1);
1073 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
1076 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
1078 MockWindowBindingHandlerDelegate delegate;
1079 bool focused =
false;
1080 bool restored =
false;
1081 EXPECT_CALL(delegate, OnWindowStateEvent)
1090 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kFocused),
1091 Eq(FlutterViewFocusDirection::kUndefined)))
1093 win32window.SetView(&delegate);
1094 EXPECT_TRUE(focused);
1095 EXPECT_TRUE(restored);
virtual void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)
virtual bool OnBitmapSurfaceUpdated(const void *allocation, size_t row_bytes, size_t height) override
virtual void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint64_t buttons, uint32_t rotation, uint32_t pressure)
virtual void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint64_t buttons, uint32_t rotation, uint32_t pressure, int modifiers_state)
virtual void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint64_t buttons)
virtual void SetView(WindowBindingHandlerDelegate *view) override
virtual float GetDpiScale() override
FlutterWindowsView(FlutterViewId view_id, FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > window_binding, bool is_sized_to_content, const BoxConstraints &box_constraints, FlutterWindowsViewSizingDelegate *sizing_delegate=nullptr, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr)
MOCK_METHOD(void, NotifyWinEventWrapper,(ui::AXPlatformNodeWin *, ax::mojom::Event),(override))
MockFlutterWindowsView(FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > wbh)
TEST_F(AccessibilityPluginTest, DirectAnnounceCall)
WindowStateEvent
An event representing a change in window state that may update the.
constexpr FlutterViewId kImplicitViewId