12#include "gmock/gmock.h"
13#include "gtest/gtest.h"
19using ::testing::AnyNumber;
21using ::testing::Invoke;
22using ::testing::Return;
25static constexpr int32_t kDefaultPointerDeviceId = 0;
27class 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)
41 virtual ~MockFlutterWindow() {
42 if (reset_view_on_exit_) {
48 UINT GetDpi() {
return GetCurrentDPI(); }
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));
64 MOCK_METHOD(uint32_t, Win32MapVkToChar, (uint32_t), (
override));
65 MOCK_METHOD(HWND, GetWindowHandle, (), (
override));
67 GetAxFragmentRootDelegate,
74 LRESULT Win32DefWindowProc(HWND hWnd,
82 bool reset_view_on_exit_;
86LRESULT 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);
110class MockFlutterWindowsView :
public FlutterWindowsView {
113 std::unique_ptr<WindowBindingHandler> window_binding)
116 std::move(window_binding),
122 NotifyWinEventWrapper,
130class FlutterWindowTest :
public WindowsTest {};
134TEST_F(FlutterWindowTest, CreateDestroy) {
135 std::unique_ptr<FlutterWindowsEngine>
engine =
141TEST_F(FlutterWindowTest, OnBitmapSurfaceUpdated) {
142 std::unique_ptr<FlutterWindowsEngine>
engine =
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);
160TEST_F(FlutterWindowTest, OnCursorRectUpdatedRegularDPI) {
161 MockFlutterWindow win32window;
162 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.0));
165 EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);
167 win32window.OnCursorRectUpdated(cursor_rect);
173TEST_F(FlutterWindowTest, OnCursorRectUpdatedHighDPI) {
174 MockFlutterWindow win32window;
175 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.5));
178 EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);
181 win32window.OnCursorRectUpdated(cursor_rect);
184TEST_F(FlutterWindowTest, OnPointerStarSendsDeviceType) {
185 std::unique_ptr<FlutterWindowsEngine>
engine =
189 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
190 win32window.
SetView(&delegate);
193 EXPECT_CALL(delegate,
195 kDefaultPointerDeviceId, 0, 0, 0, 0))
197 EXPECT_CALL(delegate,
199 kDefaultPointerDeviceId, 0, 0, 0, 0))
201 EXPECT_CALL(delegate,
203 kDefaultPointerDeviceId, 0, 0, 0, 0))
207 EXPECT_CALL(delegate,
209 kDefaultPointerDeviceId,
212 EXPECT_CALL(delegate,
214 kDefaultPointerDeviceId,
217 EXPECT_CALL(delegate,
219 kDefaultPointerDeviceId,
225 kDefaultPointerDeviceId,
229 kDefaultPointerDeviceId,
233 kDefaultPointerDeviceId,
238 EXPECT_CALL(delegate,
240 kDefaultPointerDeviceId))
242 EXPECT_CALL(delegate,
244 kDefaultPointerDeviceId))
246 EXPECT_CALL(delegate,
248 kDefaultPointerDeviceId))
252 kDefaultPointerDeviceId, 0, 0, 0, 0);
254 kDefaultPointerDeviceId,
257 kDefaultPointerDeviceId,
260 kDefaultPointerDeviceId);
264 kDefaultPointerDeviceId, 0, 0, 0, 0);
266 kDefaultPointerDeviceId,
269 kDefaultPointerDeviceId,
272 kDefaultPointerDeviceId);
276 kDefaultPointerDeviceId, 0, 0, 0, 0);
278 kDefaultPointerDeviceId,
281 kDefaultPointerDeviceId,
284 kDefaultPointerDeviceId);
291TEST_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);
321 win32window.SetView(&delegate);
323 EXPECT_CALL(delegate,
325 kDefaultPointerDeviceId,
329 UINT32 pointerId = 1;
331 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
335TEST_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);
361 win32window.SetView(&delegate);
363 EXPECT_CALL(delegate,
365 kDefaultPointerDeviceId,
369 UINT32 pointerId = 1;
371 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 15,
375TEST_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);
408 win32window.SetView(&delegate);
410 EXPECT_CALL(delegate,
412 kDefaultPointerDeviceId,
416 kDefaultPointerDeviceId, 0))
419 UINT32 pointerId = 1;
421 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 25,
423 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUP, wparam, 25,
427TEST_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);
452 win32window.SetView(&delegate);
455 kDefaultPointerDeviceId))
458 UINT32 pointerId = 1;
460 InjectPointerMessageWithClientPoint(win32window, WM_POINTERLEAVE, wparam, 35,
464TEST_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);
504 win32window.SetView(&delegate);
507 EXPECT_CALL(delegate,
512 UINT32 pointerId = 1;
514 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 45,
523 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 45,
527TEST_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);
568 win32window.SetView(&delegate);
570 EXPECT_CALL(delegate,
572 kDefaultPointerDeviceId,
576 kDefaultPointerDeviceId, 0))
578 EXPECT_CALL(delegate,
580 kDefaultPointerDeviceId, 0, 0, 720, 0))
583 UINT32 pointerId = 1;
585 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
587 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUP, wparam, 10,
589 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 10,
593TEST_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);
618 win32window.SetView(&delegate);
620 EXPECT_CALL(delegate,
622 kDefaultPointerDeviceId,
628 UINT32 pointerId = 1;
630 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
634TEST_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);
659 win32window.SetView(&delegate);
661 EXPECT_CALL(delegate,
663 kDefaultPointerDeviceId,
669 UINT32 pointerId = 1;
671 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
675TEST_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);
700 win32window.SetView(&delegate);
702 EXPECT_CALL(delegate,
704 kDefaultPointerDeviceId,
708 UINT32 pointerId = 1;
710 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
714TEST_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);
747 win32window.SetView(&delegate);
749 EXPECT_CALL(delegate,
751 kDefaultPointerDeviceId,
754 EXPECT_CALL(delegate,
756 kDefaultPointerDeviceId,
762 UINT32 pointerId = 1;
764 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
766 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 10,
770TEST_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);
803 win32window.SetView(&delegate);
805 EXPECT_CALL(delegate,
807 kDefaultPointerDeviceId,
812 EXPECT_CALL(delegate,
814 kDefaultPointerDeviceId,
818 UINT32 pointerId = 1;
820 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
822 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 10,
826TEST_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);
843 win32window.SetView(&delegate);
846 kDefaultPointerDeviceId,
850 UINT32 pointerId = 1;
852 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 45,
856TEST_F(FlutterWindowTest, NonPrimaryMouseButtonCapturesPointer) {
857 MockFlutterWindow win32window(100, 100);
859 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
860 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
861 win32window.SetView(&delegate);
863 HWND window_handle = win32window.FlutterWindow::GetWindowHandle();
864 ASSERT_NE(window_handle,
nullptr);
866 ASSERT_EQ(GetCapture(),
nullptr);
868 EXPECT_CALL(delegate,
870 kDefaultPointerDeviceId,
873 win32window.InjectWindowMessage(WM_RBUTTONDOWN, MK_RBUTTON,
875 EXPECT_EQ(GetCapture(), window_handle);
878 kDefaultPointerDeviceId,
881 win32window.InjectWindowMessage(WM_RBUTTONUP, 0, MAKELPARAM(10, 10));
882 EXPECT_EQ(GetCapture(),
nullptr);
885TEST_F(FlutterWindowTest, MouseButtonCaptureReleasedAfterAllButtonsReleased) {
886 MockFlutterWindow win32window(100, 100);
888 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
889 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
890 win32window.SetView(&delegate);
892 HWND window_handle = win32window.FlutterWindow::GetWindowHandle();
893 ASSERT_NE(window_handle,
nullptr);
895 ASSERT_EQ(GetCapture(),
nullptr);
897 EXPECT_CALL(delegate,
899 kDefaultPointerDeviceId,
902 win32window.InjectWindowMessage(WM_RBUTTONDOWN, MK_RBUTTON,
904 EXPECT_EQ(GetCapture(), window_handle);
906 EXPECT_CALL(delegate,
908 kDefaultPointerDeviceId,
911 win32window.InjectWindowMessage(WM_LBUTTONDOWN, MK_LBUTTON | MK_RBUTTON,
913 EXPECT_EQ(GetCapture(), window_handle);
916 kDefaultPointerDeviceId,
919 win32window.InjectWindowMessage(WM_RBUTTONUP, MK_LBUTTON, MAKELPARAM(10, 10));
920 EXPECT_EQ(GetCapture(), window_handle);
923 kDefaultPointerDeviceId,
926 win32window.InjectWindowMessage(WM_LBUTTONUP, 0, MAKELPARAM(10, 10));
927 EXPECT_EQ(GetCapture(),
nullptr);
930TEST_F(FlutterWindowTest, OnTouchPointerDown) {
931 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
933 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
934 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
935 if (pointer_info !=
nullptr) {
936 pointer_info->pointerType = PT_TOUCH;
937 pointer_info->pointerId = pointer_id;
938 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT |
939 POINTER_FLAG_FIRSTBUTTON |
945 MockFlutterWindow win32window(100, 100, mock_proc_table);
947 win32window.SetView(&delegate);
950 kDefaultPointerDeviceId,
954 UINT32 pointerId = 1;
956 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 55,
960TEST_F(FlutterWindowTest, PointerMessageScreenCoordinatesAreConvertedToClient) {
961 constexpr int kClientX = 15;
962 constexpr int kClientY = 20;
964 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
966 EXPECT_CALL(*mock_proc_table, GetPointerInfo(_, _))
967 .WillRepeatedly([](UINT32 pointer_id, POINTER_INFO* pointer_info) {
968 if (pointer_info !=
nullptr) {
969 pointer_info->pointerType = PT_TOUCH;
970 pointer_info->pointerId = pointer_id;
971 pointer_info->pointerFlags = POINTER_FLAG_INCONTACT |
972 POINTER_FLAG_FIRSTBUTTON |
978 MockFlutterWindow win32window(100, 100, mock_proc_table);
980 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
981 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
982 win32window.SetView(&delegate);
985 CreateWindowEx(0, L
"STATIC", L
"", WS_POPUP, 100, 100, 300, 300,
nullptr,
986 nullptr, GetModuleHandle(
nullptr),
nullptr);
987 ASSERT_NE(parent_window,
nullptr);
989 HWND flutter_window = win32window.FlutterWindow::GetWindowHandle();
990 ASSERT_NE(flutter_window,
nullptr);
991 ASSERT_NE(SetParent(flutter_window, parent_window),
nullptr);
992 ASSERT_TRUE(SetWindowPos(flutter_window,
nullptr, 25, 35, 100, 100,
993 SWP_NOZORDER | SWP_NOACTIVATE));
995 POINT pointer_point = {kClientX, kClientY};
996 ASSERT_TRUE(ClientToScreen(flutter_window, &pointer_point));
998 EXPECT_CALL(delegate,
1000 kDefaultPointerDeviceId,
1004 win32window.InjectWindowMessage(WM_POINTERDOWN, 1,
1005 MAKELPARAM(pointer_point.x, pointer_point.y));
1007 EXPECT_NE(SetParent(flutter_window, HWND_MESSAGE),
nullptr);
1008 DestroyWindow(parent_window);
1013TEST_F(FlutterWindowTest, OnScrollCallsGetScrollOffsetMultiplier) {
1014 MockFlutterWindow win32window;
1016 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
1017 win32window.SetView(&delegate);
1019 EXPECT_CALL(win32window, GetWindowHandle).WillOnce([&win32window]() {
1020 return win32window.FlutterWindow::GetWindowHandle();
1022 EXPECT_CALL(win32window, GetScrollOffsetMultiplier).WillOnce(Return(120.0f));
1024 EXPECT_CALL(delegate,
1026 kDefaultPointerDeviceId))
1030 kDefaultPointerDeviceId);
1034 MockFlutterWindow win32window;
1036 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
1037 win32window.SetView(&delegate);
1039 EXPECT_CALL(delegate, OnWindowRepaint()).Times(1);
1041 win32window.InjectWindowMessage(WM_PAINT, 0, 0);
1045 MockFlutterWindow win32window;
1047 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
1048 win32window.SetView(&delegate);
1050 EXPECT_CALL(delegate, OnHighContrastChanged).Times(1);
1052 win32window.InjectWindowMessage(WM_THEMECHANGED, 0, 0);
1058TEST_F(FlutterWindowTest, AccessibilityNodeWithoutView) {
1059 MockFlutterWindow win32window;
1061 EXPECT_EQ(win32window.GetNativeViewAccessible(),
nullptr);
1067 std::unique_ptr<FlutterWindowsEngine>
engine =
1069 auto win32window = std::make_unique<MockFlutterWindow>();
1070 EXPECT_CALL(*win32window.get(), GetAxFragmentRootDelegate())
1071 .WillRepeatedly(Return(
nullptr));
1072 EXPECT_CALL(*win32window.get(), OnWindowStateEvent).Times(AnyNumber());
1073 EXPECT_CALL(*win32window.get(), GetWindowHandle).Times(AnyNumber());
1074 MockFlutterWindowsView
view{
engine.get(), std::move(win32window)};
1075 std::wstring
message = L
"Test alert";
1081 VARIANT
self{.vt = VT_I4, .lVal = CHILDID_SELF};
1083 alert->get_accName(
self, &strptr);
1086 alert->get_accDescription(
self, &strptr);
1089 alert->get_accValue(
self, &strptr);
1093 alert->get_accRole(
self, &role);
1094 EXPECT_EQ(role.vt, VT_I4);
1095 EXPECT_EQ(role.lVal, ROLE_SYSTEM_ALERT);
1098TEST_F(FlutterWindowTest, LifecycleFocusMessages) {
1099 MockFlutterWindow win32window;
1100 EXPECT_CALL(win32window, GetWindowHandle)
1101 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
1105 EXPECT_CALL(delegate, OnWindowStateEvent)
1109 EXPECT_CALL(win32window, OnWindowStateEvent)
1111 win32window.FlutterWindow::OnWindowStateEvent(event);
1113 EXPECT_CALL(win32window, OnResize).Times(AnyNumber());
1115 win32window.SetView(&delegate);
1117 win32window.InjectWindowMessage(WM_SIZE, 0, 0);
1120 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
1126 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
1132 win32window.InjectWindowMessage(WM_KILLFOCUS, 0, 0);
1136TEST_F(FlutterWindowTest, CachedLifecycleMessage) {
1137 MockFlutterWindow win32window;
1138 EXPECT_CALL(win32window, GetWindowHandle)
1139 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
1140 EXPECT_CALL(win32window, OnWindowStateEvent)
1142 win32window.FlutterWindow::OnWindowStateEvent(event);
1144 EXPECT_CALL(win32window, OnResize).Times(1);
1147 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
1150 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
1153 bool focused =
false;
1154 bool restored =
false;
1155 EXPECT_CALL(delegate, OnWindowStateEvent)
1167 win32window.SetView(&delegate);
1168 EXPECT_TRUE(focused);
1169 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)
std::unique_ptr< FlutterWindowsEngine > Build()
~MockFlutterWindowsView()
MOCK_METHOD(void, NotifyWinEventWrapper,(ui::AXPlatformNodeWin *, ax::mojom::Event),(override))
MockFlutterWindowsView(FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > wbh)
@ kUnfocused
Specifies that a view does not have platform focus.
@ kFocused
Specifies that a view has platform focus.
@ kFlutterPointerButtonMousePrimary
@ kFlutterPointerButtonMouseSecondary
@ kFlutterPointerButtonStylusSecondary
@ kFlutterPointerButtonStylusPrimary
@ kFlutterPointerButtonStylusContact
@ kFlutterPointerDeviceKindTouch
@ kFlutterPointerDeviceKindInvertedStylus
@ kFlutterPointerDeviceKindStylus
@ kFlutterPointerDeviceKindMouse
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
TEST_F(DisplayListTest, Defaults)
constexpr LRESULT kWmResultDefault
constexpr int64_t kImplicitViewId
WindowStateEvent
An event representing a change in window state that may update the.