Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
flutter_window_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.
11
12#include "gmock/gmock.h"
13#include "gtest/gtest.h"
14
15namespace flutter {
16namespace testing {
17
18using ::testing::_;
19using ::testing::AnyNumber;
20using ::testing::Eq;
21using ::testing::Invoke;
22using ::testing::Return;
23
24namespace {
25static constexpr int32_t kDefaultPointerDeviceId = 0;
26
27class MockFlutterWindow : public FlutterWindow {
28 public:
29 explicit MockFlutterWindow(bool reset_view_on_exit = true)
30 : reset_view_on_exit_(reset_view_on_exit) {
31 ON_CALL(*this, GetDpiScale())
32 .WillByDefault(Return(this->FlutterWindow::GetDpiScale()));
33 }
34
35 // Used for injecting a proc_table to override calls to the windows API
36 MockFlutterWindow(int width,
37 int height,
38 std::shared_ptr<WindowsProcTable> proc_table = nullptr)
39 : FlutterWindow(width, height, nullptr, std::move(proc_table)) {}
40
41 virtual ~MockFlutterWindow() {
42 if (reset_view_on_exit_) {
43 SetView(nullptr);
44 }
45 }
46
47 // Wrapper for GetCurrentDPI() which is a protected method.
48 UINT GetDpi() { return GetCurrentDPI(); }
49 // Simulates a WindowProc message from the OS.
50 LRESULT InjectWindowMessage(UINT const message,
51 WPARAM const wparam,
52 LPARAM const lparam) {
53 return HandleMessage(message, wparam, lparam);
54 }
55
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));
67 GetAxFragmentRootDelegate,
68 (),
69 (override));
70 MOCK_METHOD(void, OnWindowStateEvent, (WindowStateEvent), (override));
71
72 protected:
73 // |KeyboardManager::WindowDelegate|
74 LRESULT Win32DefWindowProc(HWND hWnd,
75 UINT Msg,
76 WPARAM wParam,
77 LPARAM lParam) override {
78 return kWmResultDefault;
79 }
80
81 private:
82 bool reset_view_on_exit_;
83 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindow);
84};
85
86LRESULT InjectPointerMessageWithClientPoint(MockFlutterWindow& window,
88 WPARAM wparam,
89 int x,
90 int y) {
91 HWND flutter_window = window.FlutterWindow::GetWindowHandle();
92 HWND parent_window =
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));
99
100 POINT point = {x, y};
101 EXPECT_TRUE(ClientToScreen(flutter_window, &point));
102 LRESULT result =
103 window.InjectWindowMessage(message, wparam, MAKELPARAM(point.x, point.y));
104
105 EXPECT_NE(SetParent(flutter_window, HWND_MESSAGE), nullptr);
106 DestroyWindow(parent_window);
107 return result;
108}
109
110class MockFlutterWindowsView : public FlutterWindowsView {
111 public:
112 MockFlutterWindowsView(FlutterWindowsEngine* engine,
113 std::unique_ptr<WindowBindingHandler> window_binding)
115 engine,
116 std::move(window_binding),
117 false,
118 BoxConstraints()) {}
120
121 MOCK_METHOD(void,
122 NotifyWinEventWrapper,
123 (ui::AXPlatformNodeWin*, ax::mojom::Event),
124 (override));
125
126 private:
127 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
128};
129
130class FlutterWindowTest : public WindowsTest {};
131
132} // namespace
133
134TEST_F(FlutterWindowTest, CreateDestroy) {
135 std::unique_ptr<FlutterWindowsEngine> engine =
136 FlutterWindowsEngineBuilder{GetContext()}.Build();
137 FlutterWindow window(800, 600, engine->display_manager());
138 ASSERT_TRUE(TRUE);
139}
140
141TEST_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);
146
147 constexpr size_t row_bytes = 100 * 4;
148 constexpr size_t height = 100;
149 std::array<char, row_bytes * height> allocation;
150 win32window.OnBitmapSurfaceUpdated(allocation.data(), row_bytes, height);
151
152 int new_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
153 // Check GDI resources leak
154 EXPECT_EQ(old_handle_count, new_handle_count);
155}
156
157// Tests that composing rect updates are transformed from Flutter logical
158// coordinates to device coordinates and passed to the text input manager
159// when the DPI scale is 100% (96 DPI).
160TEST_F(FlutterWindowTest, OnCursorRectUpdatedRegularDPI) {
161 MockFlutterWindow win32window;
162 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.0));
163
164 Rect cursor_rect(Point(10, 20), Size(30, 40));
165 EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);
166
167 win32window.OnCursorRectUpdated(cursor_rect);
168}
169
170// Tests that composing rect updates are transformed from Flutter logical
171// coordinates to device coordinates and passed to the text input manager
172// when the DPI scale is 150% (144 DPI).
173TEST_F(FlutterWindowTest, OnCursorRectUpdatedHighDPI) {
174 MockFlutterWindow win32window;
175 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.5));
176
177 Rect expected_cursor_rect(Point(15, 30), Size(45, 60));
178 EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);
179
180 Rect cursor_rect(Point(10, 20), Size(30, 40));
181 win32window.OnCursorRectUpdated(cursor_rect);
182}
183
184TEST_F(FlutterWindowTest, OnPointerStarSendsDeviceType) {
185 std::unique_ptr<FlutterWindowsEngine> engine =
186 FlutterWindowsEngineBuilder{GetContext()}.Build();
187 FlutterWindow win32window(100, 100, engine->display_manager());
189 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
190 win32window.SetView(&delegate);
191
192 // Move
193 EXPECT_CALL(delegate,
194 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
195 kDefaultPointerDeviceId, 0, 0, 0, 0))
196 .Times(1);
197 EXPECT_CALL(delegate,
198 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
199 kDefaultPointerDeviceId, 0, 0, 0, 0))
200 .Times(1);
201 EXPECT_CALL(delegate,
202 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
203 kDefaultPointerDeviceId, 0, 0, 0, 0))
204 .Times(1);
205
206 // Down
207 EXPECT_CALL(delegate,
208 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
209 kDefaultPointerDeviceId,
211 .Times(1);
212 EXPECT_CALL(delegate,
213 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
214 kDefaultPointerDeviceId,
216 .Times(1);
217 EXPECT_CALL(delegate,
218 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
219 kDefaultPointerDeviceId,
221 .Times(1);
222
223 // Up
224 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
225 kDefaultPointerDeviceId,
227 .Times(1);
228 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
229 kDefaultPointerDeviceId,
231 .Times(1);
232 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
233 kDefaultPointerDeviceId,
235 .Times(1);
236
237 // Leave
238 EXPECT_CALL(delegate,
239 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
240 kDefaultPointerDeviceId))
241 .Times(1);
242 EXPECT_CALL(delegate,
243 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
244 kDefaultPointerDeviceId))
245 .Times(1);
246 EXPECT_CALL(delegate,
247 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
248 kDefaultPointerDeviceId))
249 .Times(1);
250
251 win32window.OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
252 kDefaultPointerDeviceId, 0, 0, 0, 0);
253 win32window.OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
254 kDefaultPointerDeviceId,
256 win32window.OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
257 kDefaultPointerDeviceId,
259 win32window.OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
260 kDefaultPointerDeviceId);
261
262 // Touch
263 win32window.OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
264 kDefaultPointerDeviceId, 0, 0, 0, 0);
265 win32window.OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
266 kDefaultPointerDeviceId,
268 win32window.OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
269 kDefaultPointerDeviceId,
271 win32window.OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
272 kDefaultPointerDeviceId);
273
274 // Pen
275 win32window.OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
276 kDefaultPointerDeviceId, 0, 0, 0, 0);
277 win32window.OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
278 kDefaultPointerDeviceId,
280 win32window.OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
281 kDefaultPointerDeviceId,
283 win32window.OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
284 kDefaultPointerDeviceId);
285
286 // Destruction of win32window sends a HIDE update. In situ, the window is
287 // owned by the delegate, and so is destructed first. Not so here.
288 win32window.SetView(nullptr);
289}
290
291TEST_F(FlutterWindowTest, OnStylusPointerDown) {
292 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
293
294 // Set up expectations for the mock
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;
301 }
302 return TRUE;
303 });
304
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; // Non-zero pressure for contact events
309 pen_info->rotation = 0;
310 pen_info->penFlags = 0;
311 }
312 return TRUE;
313 });
314
315 POINTER_INFO test_pointer_info = {};
316 BOOL result = mock_proc_table->GetPointerInfo(1, &test_pointer_info);
317
318 MockFlutterWindow win32window(100, 100, mock_proc_table);
320
321 win32window.SetView(&delegate);
322
323 EXPECT_CALL(delegate,
324 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
325 kDefaultPointerDeviceId,
327 .Times(1);
328
329 UINT32 pointerId = 1;
330 WPARAM wparam = static_cast<WPARAM>(pointerId);
331 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
332 10);
333}
334
335TEST_F(FlutterWindowTest, OnStylusPointerMove) {
336 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
337
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;
345 }
346 return TRUE;
347 });
348
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; // Non-zero pressure for contact events
353 pen_info->rotation = 10; // This is PRE-transformation to radians.
354 pen_info->penFlags = 0;
355 }
356 return TRUE;
357 });
358
359 MockFlutterWindow win32window(100, 100, mock_proc_table);
361 win32window.SetView(&delegate);
362
363 EXPECT_CALL(delegate,
364 OnPointerMove(15, 20, kFlutterPointerDeviceKindStylus,
365 kDefaultPointerDeviceId,
367 .Times(1);
368
369 UINT32 pointerId = 1;
370 WPARAM wparam = static_cast<WPARAM>(pointerId);
371 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 15,
372 20);
373}
374
375TEST_F(FlutterWindowTest, OnStylusPointerUp) {
376 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
377
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;
384 }
385 return TRUE;
386 })
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;
392 }
393 return TRUE;
394 });
395
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;
402 }
403 return TRUE;
404 });
405
406 MockFlutterWindow win32window(100, 100, mock_proc_table);
408 win32window.SetView(&delegate);
409
410 EXPECT_CALL(delegate,
411 OnPointerDown(25, 30, kFlutterPointerDeviceKindStylus,
412 kDefaultPointerDeviceId,
414 .Times(1);
415 EXPECT_CALL(delegate, OnPointerUp(25, 30, kFlutterPointerDeviceKindStylus,
416 kDefaultPointerDeviceId, 0))
417 .Times(1);
418
419 UINT32 pointerId = 1;
420 WPARAM wparam = static_cast<WPARAM>(pointerId);
421 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 25,
422 30);
423 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUP, wparam, 25,
424 30);
425}
426
427TEST_F(FlutterWindowTest, OnStylusPointerLeave) {
428 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
429
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;
436 }
437 return TRUE;
438 });
439
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;
446 }
447 return TRUE;
448 });
449
450 MockFlutterWindow win32window(100, 100, mock_proc_table);
452 win32window.SetView(&delegate);
453
454 EXPECT_CALL(delegate, OnPointerLeave(35, 40, kFlutterPointerDeviceKindStylus,
455 kDefaultPointerDeviceId))
456 .Times(1);
457
458 UINT32 pointerId = 1;
459 WPARAM wparam = static_cast<WPARAM>(pointerId);
460 InjectPointerMessageWithClientPoint(win32window, WM_POINTERLEAVE, wparam, 35,
461 40);
462}
463
464TEST_F(FlutterWindowTest, OnStylusPointerHover) {
465 // Test that WM_POINTERUPDATE without POINTER_FLAG_INCONTACT (hover) is
466 // handled
467 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
468
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;
477 }
478 return TRUE;
479 })
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;
484 // No POINTER_FLAG_INCONTACT - this simulates a hover event
485 pointer_info->pointerFlags = POINTER_FLAG_UPDATE;
486 pointer_info->ptPixelLocation.x = 45;
487 pointer_info->ptPixelLocation.y = 50;
488 }
489 return TRUE;
490 });
491
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;
498 }
499 return TRUE;
500 });
501
502 MockFlutterWindow win32window(100, 100, mock_proc_table);
504 win32window.SetView(&delegate);
505
506 // First establish the pointer with WM_POINTERDOWN
507 EXPECT_CALL(delegate,
508 OnPointerDown(45, 50, kFlutterPointerDeviceKindStylus, 0,
510 .Times(1);
511
512 UINT32 pointerId = 1;
513 WPARAM wparam = static_cast<WPARAM>(pointerId);
514 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 45,
515 50);
516
517 // Now expect OnPointerMove to be called for hover events
518 EXPECT_CALL(delegate, OnPointerMove(45, 50, kFlutterPointerDeviceKindStylus,
519 0, 0, 0, 0, 0))
520 .Times(1);
521
522 // Inject WM_POINTERUPDATE message (hover event)
523 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 45,
524 50);
525}
526
527TEST_F(FlutterWindowTest, OnStylusHoverAfterPointerUp) {
528 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
529
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;
536 }
537 return TRUE;
538 })
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;
544 }
545 return TRUE;
546 })
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;
552 }
553 return TRUE;
554 });
555
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;
562 }
563 return TRUE;
564 });
565
566 MockFlutterWindow win32window(100, 100, mock_proc_table);
568 win32window.SetView(&delegate);
569
570 EXPECT_CALL(delegate,
571 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
572 kDefaultPointerDeviceId,
574 .Times(1);
575 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
576 kDefaultPointerDeviceId, 0))
577 .Times(1);
578 EXPECT_CALL(delegate,
579 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
580 kDefaultPointerDeviceId, 0, 0, 720, 0))
581 .Times(1);
582
583 UINT32 pointerId = 1;
584 WPARAM wparam = static_cast<WPARAM>(pointerId);
585 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
586 10);
587 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUP, wparam, 10,
588 10);
589 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 10,
590 10);
591}
592
593TEST_F(FlutterWindowTest, OnStylusBarrelButtonUsesPenFlags) {
594 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
595
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;
602 }
603 return TRUE;
604 });
605
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;
612 }
613 return TRUE;
614 });
615
616 MockFlutterWindow win32window(100, 100, mock_proc_table);
618 win32window.SetView(&delegate);
619
620 EXPECT_CALL(delegate,
621 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
622 kDefaultPointerDeviceId,
625 720, 0))
626 .Times(1);
627
628 UINT32 pointerId = 1;
629 WPARAM wparam = static_cast<WPARAM>(pointerId);
630 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
631 10);
632}
633
634TEST_F(FlutterWindowTest, OnStylusEraserButtonUsesPenFlags) {
635 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
636
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;
643 }
644 return TRUE;
645 });
646
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;
653 }
654 return TRUE;
655 });
656
657 MockFlutterWindow win32window(100, 100, mock_proc_table);
659 win32window.SetView(&delegate);
660
661 EXPECT_CALL(delegate,
662 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
663 kDefaultPointerDeviceId,
666 720, 0))
667 .Times(1);
668
669 UINT32 pointerId = 1;
670 WPARAM wparam = static_cast<WPARAM>(pointerId);
671 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
672 10);
673}
674
675TEST_F(FlutterWindowTest, OnInvertedStylusPointerDownUsesDeviceKind) {
676 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
677
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;
684 }
685 return TRUE;
686 });
687
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;
694 }
695 return TRUE;
696 });
697
698 MockFlutterWindow win32window(100, 100, mock_proc_table);
700 win32window.SetView(&delegate);
701
702 EXPECT_CALL(delegate,
703 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindInvertedStylus,
704 kDefaultPointerDeviceId,
706 .Times(1);
707
708 UINT32 pointerId = 1;
709 WPARAM wparam = static_cast<WPARAM>(pointerId);
710 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
711 10);
712}
713
714TEST_F(FlutterWindowTest, OnStylusBarrelButtonUpdateMovesWithUpdatedButtons) {
715 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
716
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;
723 }
724 return TRUE;
725 });
726
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;
733 }
734 return TRUE;
735 })
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;
741 }
742 return TRUE;
743 });
744
745 MockFlutterWindow win32window(100, 100, mock_proc_table);
747 win32window.SetView(&delegate);
748
749 EXPECT_CALL(delegate,
750 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
751 kDefaultPointerDeviceId,
753 .Times(1);
754 EXPECT_CALL(delegate,
755 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
756 kDefaultPointerDeviceId,
759 0, 720, 0))
760 .Times(1);
761
762 UINT32 pointerId = 1;
763 WPARAM wparam = static_cast<WPARAM>(pointerId);
764 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
765 10);
766 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 10,
767 10);
768}
769
770TEST_F(FlutterWindowTest, OnStylusBarrelButtonUpdateMovesWithReleasedButton) {
771 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
772
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;
779 }
780 return TRUE;
781 });
782
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;
789 }
790 return TRUE;
791 })
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;
797 }
798 return TRUE;
799 });
800
801 MockFlutterWindow win32window(100, 100, mock_proc_table);
803 win32window.SetView(&delegate);
804
805 EXPECT_CALL(delegate,
806 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
807 kDefaultPointerDeviceId,
810 720, 0))
811 .Times(1);
812 EXPECT_CALL(delegate,
813 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
814 kDefaultPointerDeviceId,
816 .Times(1);
817
818 UINT32 pointerId = 1;
819 WPARAM wparam = static_cast<WPARAM>(pointerId);
820 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 10,
821 10);
822 InjectPointerMessageWithClientPoint(win32window, WM_POINTERUPDATE, wparam, 10,
823 10);
824}
825
826TEST_F(FlutterWindowTest, OnMousePointerDown) {
827 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
828
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 |
836 POINTER_FLAG_DOWN;
837 }
838 return TRUE;
839 });
840
841 MockFlutterWindow win32window(100, 100, mock_proc_table);
843 win32window.SetView(&delegate);
844
845 EXPECT_CALL(delegate, OnPointerDown(45, 50, kFlutterPointerDeviceKindMouse,
846 kDefaultPointerDeviceId,
848 .Times(1);
849
850 UINT32 pointerId = 1;
851 WPARAM wparam = static_cast<WPARAM>(pointerId);
852 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 45,
853 50);
854}
855
856TEST_F(FlutterWindowTest, OnTouchPointerDown) {
857 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
858
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 |
866 POINTER_FLAG_DOWN;
867 }
868 return TRUE;
869 });
870
871 MockFlutterWindow win32window(100, 100, mock_proc_table);
873 win32window.SetView(&delegate);
874
875 EXPECT_CALL(delegate, OnPointerDown(55, 60, kFlutterPointerDeviceKindTouch,
876 kDefaultPointerDeviceId,
878 .Times(1);
879
880 UINT32 pointerId = 1;
881 WPARAM wparam = static_cast<WPARAM>(pointerId);
882 InjectPointerMessageWithClientPoint(win32window, WM_POINTERDOWN, wparam, 55,
883 60);
884}
885
886TEST_F(FlutterWindowTest, PointerMessageScreenCoordinatesAreConvertedToClient) {
887 constexpr int kClientX = 15;
888 constexpr int kClientY = 20;
889
890 auto mock_proc_table = std::make_shared<MockWindowsProcTable>();
891
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 |
899 POINTER_FLAG_DOWN;
900 }
901 return TRUE;
902 });
903
904 MockFlutterWindow win32window(100, 100, mock_proc_table);
906 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
907 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
908 win32window.SetView(&delegate);
909
910 HWND parent_window =
911 CreateWindowEx(0, L"STATIC", L"", WS_POPUP, 100, 100, 300, 300, nullptr,
912 nullptr, GetModuleHandle(nullptr), nullptr);
913 ASSERT_NE(parent_window, nullptr);
914
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));
920
921 POINT pointer_point = {kClientX, kClientY};
922 ASSERT_TRUE(ClientToScreen(flutter_window, &pointer_point));
923
924 EXPECT_CALL(delegate,
925 OnPointerDown(kClientX, kClientY, kFlutterPointerDeviceKindTouch,
926 kDefaultPointerDeviceId,
928 .Times(1);
929
930 win32window.InjectWindowMessage(WM_POINTERDOWN, /*wparam=*/1,
931 MAKELPARAM(pointer_point.x, pointer_point.y));
932
933 EXPECT_NE(SetParent(flutter_window, HWND_MESSAGE), nullptr);
934 DestroyWindow(parent_window);
935}
936
937// Tests that calls to OnScroll in turn calls GetScrollOffsetMultiplier
938// for mapping scroll ticks to pixels.
939TEST_F(FlutterWindowTest, OnScrollCallsGetScrollOffsetMultiplier) {
940 MockFlutterWindow win32window;
942 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
943 win32window.SetView(&delegate);
944
945 EXPECT_CALL(win32window, GetWindowHandle).WillOnce([&win32window]() {
946 return win32window.FlutterWindow::GetWindowHandle();
947 });
948 EXPECT_CALL(win32window, GetScrollOffsetMultiplier).WillOnce(Return(120.0f));
949
950 EXPECT_CALL(delegate,
951 OnScroll(_, _, 0, 0, 120.0f, kFlutterPointerDeviceKindMouse,
952 kDefaultPointerDeviceId))
953 .Times(1);
954
955 win32window.OnScroll(0.0f, 0.0f, kFlutterPointerDeviceKindMouse,
956 kDefaultPointerDeviceId);
957}
958
959TEST_F(FlutterWindowTest, OnWindowRepaint) {
960 MockFlutterWindow win32window;
962 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
963 win32window.SetView(&delegate);
964
965 EXPECT_CALL(delegate, OnWindowRepaint()).Times(1);
966
967 win32window.InjectWindowMessage(WM_PAINT, 0, 0);
968}
969
970TEST_F(FlutterWindowTest, OnThemeChange) {
971 MockFlutterWindow win32window;
973 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
974 win32window.SetView(&delegate);
975
976 EXPECT_CALL(delegate, OnHighContrastChanged).Times(1);
977
978 win32window.InjectWindowMessage(WM_THEMECHANGED, 0, 0);
979}
980
981// The window should return no root accessibility node if
982// it isn't attached to a view.
983// Regression test for https://github.com/flutter/flutter/issues/129791
984TEST_F(FlutterWindowTest, AccessibilityNodeWithoutView) {
985 MockFlutterWindow win32window;
986
987 EXPECT_EQ(win32window.GetNativeViewAccessible(), nullptr);
988}
989
990// Ensure that announcing the alert propagates the message to the alert node.
991// Different screen readers use different properties for alerts.
992TEST_F(FlutterWindowTest, AlertNode) {
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))
1003 .Times(1);
1004 view.AnnounceAlert(message);
1005
1006 IAccessible* alert = view.AlertNode();
1007 VARIANT self{.vt = VT_I4, .lVal = CHILDID_SELF};
1008 BSTR strptr;
1009 alert->get_accName(self, &strptr);
1010 EXPECT_EQ(message, strptr);
1011
1012 alert->get_accDescription(self, &strptr);
1013 EXPECT_EQ(message, strptr);
1014
1015 alert->get_accValue(self, &strptr);
1016 EXPECT_EQ(message, strptr);
1017
1018 VARIANT role;
1019 alert->get_accRole(self, &role);
1020 EXPECT_EQ(role.vt, VT_I4);
1021 EXPECT_EQ(role.lVal, ROLE_SYSTEM_ALERT);
1022}
1023
1024TEST_F(FlutterWindowTest, LifecycleFocusMessages) {
1025 MockFlutterWindow win32window;
1026 EXPECT_CALL(win32window, GetWindowHandle)
1027 .WillRepeatedly(Return(reinterpret_cast<HWND>(1)));
1029
1030 WindowStateEvent last_event;
1031 EXPECT_CALL(delegate, OnWindowStateEvent)
1032 .WillRepeatedly([&last_event](HWND hwnd, WindowStateEvent event) {
1033 last_event = event;
1034 });
1035 EXPECT_CALL(win32window, OnWindowStateEvent)
1036 .WillRepeatedly([&](WindowStateEvent event) {
1037 win32window.FlutterWindow::OnWindowStateEvent(event);
1038 });
1039 EXPECT_CALL(win32window, OnResize).Times(AnyNumber());
1040
1041 win32window.SetView(&delegate);
1042
1043 win32window.InjectWindowMessage(WM_SIZE, 0, 0);
1044 EXPECT_EQ(last_event, WindowStateEvent::kHide);
1045
1046 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
1047 EXPECT_EQ(last_event, WindowStateEvent::kShow);
1048
1049 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kFocused),
1051 .Times(1);
1052 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
1053 EXPECT_EQ(last_event, WindowStateEvent::kFocus);
1054
1055 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kUnfocused),
1057 .Times(1);
1058 win32window.InjectWindowMessage(WM_KILLFOCUS, 0, 0);
1059 EXPECT_EQ(last_event, WindowStateEvent::kUnfocus);
1060}
1061
1062TEST_F(FlutterWindowTest, CachedLifecycleMessage) {
1063 MockFlutterWindow win32window;
1064 EXPECT_CALL(win32window, GetWindowHandle)
1065 .WillRepeatedly(Return(reinterpret_cast<HWND>(1)));
1066 EXPECT_CALL(win32window, OnWindowStateEvent)
1067 .WillRepeatedly([&](WindowStateEvent event) {
1068 win32window.FlutterWindow::OnWindowStateEvent(event);
1069 });
1070 EXPECT_CALL(win32window, OnResize).Times(1);
1071
1072 // Restore
1073 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
1074
1075 // Focus
1076 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
1077
1079 bool focused = false;
1080 bool restored = false;
1081 EXPECT_CALL(delegate, OnWindowStateEvent)
1082 .WillRepeatedly([&](HWND hwnd, WindowStateEvent event) {
1083 if (event == WindowStateEvent::kFocus) {
1084 focused = true;
1085 } else if (event == WindowStateEvent::kShow) {
1086 restored = true;
1087 }
1088 });
1089
1090 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kFocused),
1092 .Times(1);
1093 win32window.SetView(&delegate);
1094 EXPECT_TRUE(focused);
1095 EXPECT_TRUE(restored);
1096}
1097
1098} // namespace testing
1099} // namespace flutter
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)
int32_t x
@ kUnfocused
Specifies that a view does not have platform focus.
Definition embedder.h:1221
@ kFocused
Specifies that a view has platform focus.
Definition embedder.h:1224
@ kUndefined
Definition embedder.h:1205
@ kFlutterPointerButtonMousePrimary
Definition embedder.h:1320
@ kFlutterPointerButtonStylusSecondary
Definition embedder.h:1341
@ kFlutterPointerButtonStylusPrimary
Definition embedder.h:1338
@ kFlutterPointerButtonStylusContact
Definition embedder.h:1335
@ kFlutterPointerDeviceKindTouch
Definition embedder.h:1311
@ kFlutterPointerDeviceKindInvertedStylus
Definition embedder.h:1314
@ kFlutterPointerDeviceKindStylus
Definition embedder.h:1312
@ kFlutterPointerDeviceKindMouse
Definition embedder.h:1310
GLFWwindow * window
Definition main.cc:60
FlutterEngine engine
Definition main.cc:84
FlView * view
const char * message
return TRUE
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
double y
TEST_F(DisplayListTest, Defaults)
constexpr LRESULT kWmResultDefault
Definition wm_builders.h:15
constexpr int64_t kImplicitViewId
WindowStateEvent
An event representing a change in window state that may update the.
Definition ref_ptr.h:261
int32_t height
int32_t width
int BOOL
struct tagMSG * LPMSG
LONG_PTR LRESULT
unsigned int UINT
LONG_PTR LPARAM
UINT_PTR WPARAM