| Flutter Windows Embedder |

flutter_window.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/shell/platform/windows/flutter_window.h"
6
7 #include <WinUser.h>
8 #include <dwmapi.h>
9
10 #include <chrono>
11 #include <map>
12
13 #include "flutter/fml/logging.h"
14 #include "flutter/shell/platform/embedder/embedder.h"
15 #include "flutter/shell/platform/windows/display_manager.h"
16 #include "flutter/shell/platform/windows/dpi_utils.h"
17 #include "flutter/shell/platform/windows/flutter_windows_engine.h"
18 #include "flutter/shell/platform/windows/flutter_windows_view.h"
19 #include "flutter/shell/platform/windows/keyboard_utils.h"
20
21 namespace flutter {
22
23 namespace {
24
25 // The Windows DPI system is based on this
26 // constant for machines running at 100% scaling.
27 constexpr int base_dpi = 96;
28
29 static const int kMinTouchDeviceId = 0;
30 static const int kMaxTouchDeviceId = 128;
31
32 static const int kLinesPerScrollWindowsDefault = 3;
33
34 static constexpr int32_t kDefaultPointerDeviceId = 0;
35
36 // This method is only valid during a window message related to mouse/touch
37 // input.
38 // See
39 // https://docs.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages?redirectedfrom=MSDN#distinguishing-pen-input-from-mouse-and-touch.
40 static FlutterPointerDeviceKind GetFlutterPointerDeviceKind() {
41 constexpr LPARAM kTouchOrPenSignature = 0xFF515700;
42 constexpr LPARAM kTouchSignature = kTouchOrPenSignature | 0x80;
43 constexpr LPARAM kSignatureMask = 0xFFFFFF00;
44 LPARAM info = GetMessageExtraInfo();
45 if ((info & kSignatureMask) == kTouchOrPenSignature) {
46 if ((info & kTouchSignature) == kTouchSignature) {
47 return kFlutterPointerDeviceKindTouch;
48 }
49 return kFlutterPointerDeviceKindStylus;
50 }
51 return kFlutterPointerDeviceKindMouse;
52 }
53
54 // Translates button codes from Win32 API to FlutterPointerMouseButtons.
55 static uint64_t ConvertWinButtonToFlutterButton(UINT button) {
56 switch (button) {
57 case WM_LBUTTONDOWN:
58 case WM_LBUTTONUP:
59 return kFlutterPointerButtonMousePrimary;
60 case WM_RBUTTONDOWN:
61 case WM_RBUTTONUP:
62 return kFlutterPointerButtonMouseSecondary;
63 case WM_MBUTTONDOWN:
64 case WM_MBUTTONUP:
65 return kFlutterPointerButtonMouseMiddle;
66 case XBUTTON1:
67 return kFlutterPointerButtonMouseBack;
68 case XBUTTON2:
69 return kFlutterPointerButtonMouseForward;
70 }
71 FML_LOG(WARNING) << "Mouse button not recognized: " << button;
72 return 0;
73 }
74
75 } // namespace
76
77 FlutterWindow::FlutterWindow(
78 int width,
79 int height,
80 std::shared_ptr<DisplayManagerWin32> const& display_manager,
81 std::shared_ptr<WindowsProcTable> windows_proc_table,
82 std::unique_ptr<TextInputManager> text_input_manager)
83 : touch_id_generator_(kMinTouchDeviceId, kMaxTouchDeviceId),
84 display_manager_(display_manager),
85 windows_proc_table_(std::move(windows_proc_table)),
86 text_input_manager_(std::move(text_input_manager)),
87 ax_fragment_root_(nullptr) {
88 // Get the DPI of the primary monitor as the initial DPI. If Per-Monitor V2 is
89 // supported, |current_dpi_| should be updated in the
90 // kWmDpiChangedBeforeParent message.
91 current_dpi_ = GetDpiForHWND(nullptr);
92
93 // Get initial value for wheel scroll lines
94 // TODO: Listen to changes for this value
95 // https://github.com/flutter/flutter/issues/107248
96 UpdateScrollOffsetMultiplier();
97
98 if (windows_proc_table_ == nullptr) {
99 windows_proc_table_ = std::make_unique<WindowsProcTable>();
100 }
101 if (text_input_manager_ == nullptr) {
102 text_input_manager_ = std::make_unique<TextInputManager>();
103 }
104 keyboard_manager_ = std::make_unique<KeyboardManager>(this);
105
106 InitializeChild("FLUTTERVIEW", width, height);
107 }
108
109 // Base constructor for mocks
110 FlutterWindow::FlutterWindow()
111 : touch_id_generator_(kMinTouchDeviceId, kMaxTouchDeviceId) {}
112
113 FlutterWindow::~FlutterWindow() {
114 Destroy();
115 }
116
117 void FlutterWindow::SetView(WindowBindingHandlerDelegate* window) {
118 binding_handler_delegate_ = window;
119 if (direct_manipulation_owner_) {
120 direct_manipulation_owner_->SetBindingHandlerDelegate(window);
121 }
122 if (restored_ && window) {
123 OnWindowStateEvent(WindowStateEvent::kShow);
124 }
125 if (focused_ && window) {
126 OnWindowStateEvent(WindowStateEvent::kFocus);
127 }
128 }
129
130 float FlutterWindow::GetDpiScale() {
131 return static_cast<float>(GetCurrentDPI()) / static_cast<float>(base_dpi);
132 }
133
134 PhysicalWindowBounds FlutterWindow::GetPhysicalWindowBounds() {
135 return {GetCurrentWidth(), GetCurrentHeight()};
136 }
137
138 bool FlutterWindow::Focus() {
139 auto hwnd = GetWindowHandle();
140 if (hwnd == nullptr) {
141 return false;
142 }
143
144 HWND prevFocus = ::SetFocus(hwnd);
145 if (prevFocus == nullptr) {
146 return false;
147 }
148
149 return true;
150 }
151
152 void FlutterWindow::OnDpiScale(unsigned int dpi) {};
153
154 // When DesktopWindow notifies that a WM_Size message has come in
155 // lets FlutterEngine know about the new size.
156 void FlutterWindow::OnResize(unsigned int width, unsigned int height) {
157 if (binding_handler_delegate_ != nullptr) {
158 binding_handler_delegate_->OnWindowSizeChanged(width, height);
159 }
160 }
161
162 void FlutterWindow::OnPaint() {
163 if (binding_handler_delegate_ != nullptr) {
164 binding_handler_delegate_->OnWindowRepaint();
165 }
166 }
167
168 void FlutterWindow::OnPointerMove(double x,
169 double y,
170 FlutterPointerDeviceKind device_kind,
171 int32_t device_id,
172 uint32_t rotation,
173 uint32_t pressure,
174 int modifiers_state) {
175 binding_handler_delegate_->OnPointerMove(x, y, device_kind, device_id,
176 rotation, pressure, modifiers_state);
177 }
178
179 void FlutterWindow::OnPointerDown(double x,
180 double y,
181 FlutterPointerDeviceKind device_kind,
182 int32_t device_id,
183 UINT button,
184 uint32_t pressure,
185 uint32_t rotation) {
186 uint64_t flutter_button = ConvertWinButtonToFlutterButton(button);
187 if (flutter_button != 0) {
188 binding_handler_delegate_->OnPointerDown(
189 x, y, device_kind, device_id,
190 static_cast<FlutterPointerMouseButtons>(flutter_button), rotation,
191 pressure);
192 }
193 }
194
195 void FlutterWindow::OnPointerUp(double x,
196 double y,
197 FlutterPointerDeviceKind device_kind,
198 int32_t device_id,
199 UINT button) {
200 uint64_t flutter_button = ConvertWinButtonToFlutterButton(button);
201 if (flutter_button != 0) {
202 binding_handler_delegate_->OnPointerUp(
203 x, y, device_kind, device_id,
204 static_cast<FlutterPointerMouseButtons>(flutter_button));
205 }
206 }
207
208 void FlutterWindow::OnPointerLeave(double x,
209 double y,
210 FlutterPointerDeviceKind device_kind,
211 int32_t device_id) {
212 binding_handler_delegate_->OnPointerLeave(x, y, device_kind, device_id);
213 }
214
215 void FlutterWindow::OnText(const std::u16string& text) {
216 binding_handler_delegate_->OnText(text);
217 }
218
219 void FlutterWindow::OnKey(int key,
220 int scancode,
221 int action,
222 char32_t character,
223 bool extended,
224 bool was_down,
225 KeyEventCallback callback) {
226 binding_handler_delegate_->OnKey(key, scancode, action, character, extended,
227 was_down, std::move(callback));
228 }
229
230 void FlutterWindow::OnComposeBegin() {
231 binding_handler_delegate_->OnComposeBegin();
232 }
233
234 void FlutterWindow::OnComposeCommit() {
235 binding_handler_delegate_->OnComposeCommit();
236 }
237
238 void FlutterWindow::OnComposeEnd() {
239 binding_handler_delegate_->OnComposeEnd();
240 }
241
242 void FlutterWindow::OnComposeChange(const std::u16string& text,
243 int cursor_pos) {
244 binding_handler_delegate_->OnComposeChange(text, cursor_pos);
245 }
246
247 void FlutterWindow::OnUpdateSemanticsEnabled(bool enabled) {
248 binding_handler_delegate_->OnUpdateSemanticsEnabled(enabled);
249 }
250
251 void FlutterWindow::OnScroll(double delta_x,
252 double delta_y,
253 FlutterPointerDeviceKind device_kind,
254 int32_t device_id) {
255 POINT point;
256 GetCursorPos(&point);
257
258 ScreenToClient(GetWindowHandle(), &point);
259 binding_handler_delegate_->OnScroll(point.x, point.y, delta_x, delta_y,
260 GetScrollOffsetMultiplier(), device_kind,
261 device_id);
262 }
263
264 void FlutterWindow::OnCursorRectUpdated(const Rect& rect) {
265 // Convert the rect from Flutter logical coordinates to device coordinates.
266 auto scale = GetDpiScale();
267 Point origin(rect.left() * scale, rect.top() * scale);
268 Size size(rect.width() * scale, rect.height() * scale);
269 UpdateCursorRect(Rect(origin, size));
270 }
271
272 void FlutterWindow::OnResetImeComposing() {
273 AbortImeComposing();
274 }
275
276 bool FlutterWindow::OnBitmapSurfaceCleared() {
277 HDC dc = ::GetDC(GetWindowHandle());
278 bool result = ::PatBlt(dc, 0, 0, current_width_, current_height_, BLACKNESS);
279 ::ReleaseDC(GetWindowHandle(), dc);
280 return result;
281 }
282
283 bool FlutterWindow::OnBitmapSurfaceUpdated(const void* allocation,
284 size_t row_bytes,
285 size_t height) {
286 HDC dc = ::GetDC(GetWindowHandle());
287 BITMAPINFO bmi = {};
288 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
289 bmi.bmiHeader.biWidth = row_bytes / 4;
290 bmi.bmiHeader.biHeight = -height;
291 bmi.bmiHeader.biPlanes = 1;
292 bmi.bmiHeader.biBitCount = 32;
293 bmi.bmiHeader.biCompression = BI_RGB;
294 bmi.bmiHeader.biSizeImage = 0;
295 int ret = ::SetDIBitsToDevice(dc, 0, 0, row_bytes / 4, height, 0, 0, 0,
296 height, allocation, &bmi, DIB_RGB_COLORS);
297 ::ReleaseDC(GetWindowHandle(), dc);
298 return ret != 0;
299 }
300
301 gfx::NativeViewAccessible FlutterWindow::GetNativeViewAccessible() {
302 if (binding_handler_delegate_ == nullptr) {
303 return nullptr;
304 }
305
306 return binding_handler_delegate_->GetNativeViewAccessible();
307 }
308
309 PointerLocation FlutterWindow::GetPrimaryPointerLocation() {
310 POINT point;
311 GetCursorPos(&point);
312 ScreenToClient(GetWindowHandle(), &point);
313 return {(size_t)point.x, (size_t)point.y};
314 }
315
316 FlutterEngineDisplayId FlutterWindow::GetDisplayId() {
317 FlutterEngineDisplayId const display_id =
318 reinterpret_cast<FlutterEngineDisplayId>(
319 MonitorFromWindow(GetWindowHandle(), MONITOR_DEFAULTTONEAREST));
320 if (!display_manager_->FindById(display_id)) {
321 FML_LOG(ERROR) << "Current monitor not found in display list.";
322 }
323 return display_id;
324 }
325
326 void FlutterWindow::OnThemeChange() {
327 binding_handler_delegate_->OnHighContrastChanged();
328 }
329
330 ui::AXFragmentRootDelegateWin* FlutterWindow::GetAxFragmentRootDelegate() {
331 return binding_handler_delegate_->GetAxFragmentRootDelegate();
332 }
333
334 AlertPlatformNodeDelegate* FlutterWindow::GetAlertDelegate() {
335 CreateAxFragmentRoot();
336 return alert_delegate_.get();
337 }
338
339 ui::AXPlatformNodeWin* FlutterWindow::GetAlert() {
340 CreateAxFragmentRoot();
341 return alert_node_.get();
342 }
343
344 void FlutterWindow::OnWindowStateEvent(WindowStateEvent event) {
345 switch (event) {
346 case WindowStateEvent::kShow:
347 restored_ = true;
348 break;
349 case WindowStateEvent::kHide:
350 restored_ = false;
351 focused_ = false;
352 break;
353 case WindowStateEvent::kFocus:
354 focused_ = true;
355 if (binding_handler_delegate_) {
356 binding_handler_delegate_->OnFocus(
357 FlutterViewFocusState::kFocused,
358 FlutterViewFocusDirection::kUndefined);
359 }
360 break;
361 case WindowStateEvent::kUnfocus:
362 focused_ = false;
363 if (binding_handler_delegate_) {
364 binding_handler_delegate_->OnFocus(
365 FlutterViewFocusState::kUnfocused,
366 FlutterViewFocusDirection::kUndefined);
367 }
368 break;
369 }
370 HWND hwnd = GetWindowHandle();
371 if (hwnd && binding_handler_delegate_) {
372 binding_handler_delegate_->OnWindowStateEvent(hwnd, event);
373 }
374 }
375
376 void FlutterWindow::TrackMouseLeaveEvent(HWND hwnd) {
377 if (!tracking_mouse_leave_) {
378 TRACKMOUSEEVENT tme;
379 tme.cbSize = sizeof(tme);
380 tme.hwndTrack = hwnd;
381 tme.dwFlags = TME_LEAVE;
382 TrackMouseEvent(&tme);
383 tracking_mouse_leave_ = true;
384 }
385 }
386
387 void FlutterWindow::HandleResize(UINT width, UINT height) {
388 current_width_ = width;
389 current_height_ = height;
390 if (direct_manipulation_owner_) {
391 direct_manipulation_owner_->ResizeViewport(width, height);
392 }
393 OnResize(width, height);
394 }
395
396 FlutterWindow* FlutterWindow::GetThisFromHandle(HWND const window) noexcept {
397 return reinterpret_cast<FlutterWindow*>(
398 GetWindowLongPtr(window, GWLP_USERDATA));
399 }
400
401 void FlutterWindow::UpdateScrollOffsetMultiplier() {
402 UINT lines_per_scroll = kLinesPerScrollWindowsDefault;
403
404 // Get lines per scroll wheel value from Windows
405 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines_per_scroll, 0);
406
407 // This logic is based off Chromium's implementation
408 // https://source.chromium.org/chromium/chromium/src/+/main:ui/events/blink/web_input_event_builders_win.cc;l=319-331
409 scroll_offset_multiplier_ =
410 static_cast<float>(lines_per_scroll) * 100.0 / 3.0;
411 }
412
413 void FlutterWindow::InitializeChild(const char* title,
414 unsigned int width,
415 unsigned int height) {
416 Destroy();
417 std::wstring converted_title = NarrowToWide(title);
418
419 WNDCLASS window_class = RegisterWindowClass(converted_title);
420
421 auto* result = CreateWindowEx(
422 0, window_class.lpszClassName, converted_title.c_str(),
423 WS_CHILD | WS_VISIBLE, CW_DEFAULT, CW_DEFAULT, width, height,
424 HWND_MESSAGE, nullptr, window_class.hInstance, this);
425
426 if (result == nullptr) {
427 auto error = GetLastError();
428 LPWSTR message = nullptr;
429 size_t size = FormatMessageW(
430 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
431 FORMAT_MESSAGE_IGNORE_INSERTS,
432 NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
433 reinterpret_cast<LPWSTR>(&message), 0, NULL);
434 OutputDebugString(message);
435 LocalFree(message);
436 }
437 SetUserObjectInformationA(GetCurrentProcess(),
438 UOI_TIMERPROC_EXCEPTION_SUPPRESSION, FALSE, 1);
439 // SetTimer is not precise, if a 16 ms interval is requested, it will instead
440 // often fire in an interval of 32 ms. Providing a value of 14 will ensure it
441 // runs every 16 ms, which will allow for 60 Hz trackpad gesture events, which
442 // is the maximal frequency supported by SetTimer.
443 SetTimer(result, kDirectManipulationTimer, 14, nullptr);
444 direct_manipulation_owner_ = std::make_unique<DirectManipulationOwner>(this);
445 direct_manipulation_owner_->Init(width, height);
446 }
447
448 HWND FlutterWindow::GetWindowHandle() {
449 return window_handle_;
450 }
451
452 BOOL FlutterWindow::Win32PeekMessage(LPMSG lpMsg,
453 UINT wMsgFilterMin,
454 UINT wMsgFilterMax,
455 UINT wRemoveMsg) {
456 return ::PeekMessage(lpMsg, window_handle_, wMsgFilterMin, wMsgFilterMax,
457 wRemoveMsg);
458 }
459
460 uint32_t FlutterWindow::Win32MapVkToChar(uint32_t virtual_key) {
461 return ::MapVirtualKey(virtual_key, MAPVK_VK_TO_CHAR);
462 }
463
464 UINT FlutterWindow::Win32DispatchMessage(UINT Msg,
465 WPARAM wParam,
466 LPARAM lParam) {
467 return ::SendMessage(window_handle_, Msg, wParam, lParam);
468 }
469
470 std::wstring FlutterWindow::NarrowToWide(const char* source) {
471 size_t length = strlen(source);
472 size_t outlen = 0;
473 std::wstring wideTitle(length, L'#');
474 mbstowcs_s(&outlen, &wideTitle[0], length + 1, source, length);
475 return wideTitle;
476 }
477
478 WNDCLASS FlutterWindow::RegisterWindowClass(std::wstring& title) {
479 window_class_name_ = title;
480
481 WNDCLASS window_class{};
482 window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
483 window_class.lpszClassName = title.c_str();
484 window_class.style = CS_HREDRAW | CS_VREDRAW;
485 window_class.cbClsExtra = 0;
486 window_class.cbWndExtra = 0;
487 window_class.hInstance = GetModuleHandle(nullptr);
488 window_class.hIcon = nullptr;
489 window_class.hbrBackground = 0;
490 window_class.lpszMenuName = nullptr;
491 window_class.lpfnWndProc = WndProc;
492 RegisterClass(&window_class);
493 return window_class;
494 }
495
496 LRESULT CALLBACK FlutterWindow::WndProc(HWND const window,
497 UINT const message,
498 WPARAM const wparam,
499 LPARAM const lparam) noexcept {
500 if (message == WM_NCCREATE) {
501 auto cs = reinterpret_cast<CREATESTRUCT*>(lparam);
502 SetWindowLongPtr(window, GWLP_USERDATA,
503 reinterpret_cast<LONG_PTR>(cs->lpCreateParams));
504
505 auto that = static_cast<FlutterWindow*>(cs->lpCreateParams);
506 that->window_handle_ = window;
507 that->text_input_manager_->SetWindowHandle(window);
508 } else if (FlutterWindow* that = GetThisFromHandle(window)) {
509 return that->HandleMessage(message, wparam, lparam);
510 }
511
512 return DefWindowProc(window, message, wparam, lparam);
513 }
514
515 LRESULT
516 FlutterWindow::HandleMessage(UINT const message,
517 WPARAM const wparam,
518 LPARAM const lparam) noexcept {
519 LPARAM result_lparam = lparam;
520 int x_pos = 0, y_pos = 0;
521 UINT width = 0, height = 0;
522 UINT button_pressed = 0;
523 FlutterPointerDeviceKind device_kind;
524
525 switch (message) {
526 case kWmDpiChangedBeforeParent:
527 current_dpi_ = GetDpiForHWND(window_handle_);
528 OnDpiScale(current_dpi_);
529 return 0;
530 case WM_SIZE:
531 width = LOWORD(lparam);
532 height = HIWORD(lparam);
533
534 current_width_ = width;
535 current_height_ = height;
536 HandleResize(width, height);
537
538 OnWindowStateEvent(width == 0 && height == 0 ? WindowStateEvent::kHide
539 : WindowStateEvent::kShow);
540 break;
541 case WM_PAINT:
542 OnPaint();
543 break;
544 case WM_POINTERDOWN:
545 case WM_POINTERUPDATE:
546 case WM_POINTERUP:
547 case WM_POINTERLEAVE: {
548 x_pos = GET_X_LPARAM(lparam);
549 y_pos = GET_Y_LPARAM(lparam);
550 auto const x = static_cast<double>(x_pos);
551 auto const y = static_cast<double>(y_pos);
552 auto const pointerId = GET_POINTERID_WPARAM(wparam);
553 POINTER_INFO pointerInfo;
554 if (windows_proc_table_->GetPointerInfo(pointerId, &pointerInfo)) {
555 UINT32 pressure = 0;
556 UINT32 rotation = 0;
557 if (pointerInfo.pointerType == PT_PEN) {
558 POINTER_PEN_INFO penInfo;
559 if (windows_proc_table_->GetPointerPenInfo(pointerId, &penInfo)) {
560 pressure = penInfo.pressure;
561 rotation = penInfo.rotation;
562 }
563 }
564 auto touch_id = touch_id_generator_.GetGeneratedId(pointerId);
565 FlutterPointerDeviceKind device_kind = kFlutterPointerDeviceKindMouse;
566 switch (pointerInfo.pointerType) {
567 case PT_TOUCH:
568 device_kind = kFlutterPointerDeviceKindTouch;
569 break;
570 case PT_PEN:
571 device_kind = kFlutterPointerDeviceKindStylus;
572 break;
573 case PT_MOUSE:
574 device_kind = kFlutterPointerDeviceKindMouse;
575 break;
576 case PT_TOUCHPAD:
577 device_kind = kFlutterPointerDeviceKindTrackpad;
578 break;
579 default:
580 FML_LOG(ERROR) << "Unrecognized device key "
581 << pointerInfo.pointerType;
582 break;
583 }
584 if (message == WM_POINTERDOWN) {
585 OnPointerDown(x, y, device_kind, touch_id, WM_LBUTTONDOWN, rotation,
586 pressure);
587 } else if (message == WM_POINTERUPDATE) {
588 OnPointerMove(x, y, device_kind, touch_id, rotation, pressure,
589 /* modifiers_state=*/0);
590 } else if (message == WM_POINTERUP) {
591 OnPointerUp(x, y, device_kind, touch_id, WM_LBUTTONUP);
592 // keep tracking the pointer (especially important for stylus)
593 // This allows a stylus to "hover" over the window
594 } else if (message == WM_POINTERLEAVE) {
595 OnPointerLeave(x, y, device_kind, touch_id);
596 touch_id_generator_.ReleaseNumber(pointerId);
597 }
598 }
599 break;
600 }
601 case WM_MOUSEMOVE:
602 device_kind = GetFlutterPointerDeviceKind();
603 if (device_kind == kFlutterPointerDeviceKindMouse) {
604 TrackMouseLeaveEvent(window_handle_);
605
606 x_pos = GET_X_LPARAM(lparam);
607 y_pos = GET_Y_LPARAM(lparam);
608 mouse_x_ = static_cast<double>(x_pos);
609 mouse_y_ = static_cast<double>(y_pos);
610
611 int mods = 0;
612 if (wparam & MK_CONTROL) {
613 mods |= kControl;
614 }
615 if (wparam & MK_SHIFT) {
616 mods |= kShift;
617 }
618 OnPointerMove(mouse_x_, mouse_y_, device_kind, kDefaultPointerDeviceId,
619 /*rotation=*/0, /*pressure=*/0, mods);
620 }
621 break;
622 case WM_MOUSELEAVE:
623 device_kind = GetFlutterPointerDeviceKind();
624 if (device_kind == kFlutterPointerDeviceKindMouse) {
625 OnPointerLeave(mouse_x_, mouse_y_, device_kind,
626 kDefaultPointerDeviceId);
627 }
628
629 // Once the tracked event is received, the TrackMouseEvent function
630 // resets. Set to false to make sure it's called once mouse movement is
631 // detected again.
632 tracking_mouse_leave_ = false;
633 break;
634 case WM_SETCURSOR: {
635 UINT hit_test_result = LOWORD(lparam);
636 if (hit_test_result == HTCLIENT) {
637 // Halt further processing to prevent DefWindowProc from setting the
638 // cursor back to the registered class cursor.
639 return TRUE;
640 }
641 break;
642 }
643 case WM_SETFOCUS:
644 OnWindowStateEvent(WindowStateEvent::kFocus);
645 ::CreateCaret(window_handle_, nullptr, 1, 1);
646 break;
647 case WM_KILLFOCUS:
648 OnWindowStateEvent(WindowStateEvent::kUnfocus);
649 ::DestroyCaret();
650 break;
651 case WM_LBUTTONDOWN:
652 case WM_RBUTTONDOWN:
653 case WM_MBUTTONDOWN:
654 case WM_XBUTTONDOWN:
655 device_kind = GetFlutterPointerDeviceKind();
656 if (device_kind != kFlutterPointerDeviceKindMouse) {
657 break;
658 }
659
660 if (message == WM_LBUTTONDOWN) {
661 // Capture the pointer in case the user drags outside the client area.
662 // In this case, the "mouse leave" event is delayed until the user
663 // releases the button. It's only activated on left click given that
664 // it's more common for apps to handle dragging with only the left
665 // button.
666 SetCapture(window_handle_);
667 }
668 button_pressed = message;
669 if (message == WM_XBUTTONDOWN) {
670 button_pressed = GET_XBUTTON_WPARAM(wparam);
671 }
672 x_pos = GET_X_LPARAM(lparam);
673 y_pos = GET_Y_LPARAM(lparam);
674 OnPointerDown(static_cast<double>(x_pos), static_cast<double>(y_pos),
675 device_kind, kDefaultPointerDeviceId, button_pressed,
676 /*rotation=*/0, /*pressure=*/0);
677 break;
678 case WM_LBUTTONUP:
679 case WM_RBUTTONUP:
680 case WM_MBUTTONUP:
681 case WM_XBUTTONUP:
682 device_kind = GetFlutterPointerDeviceKind();
683 if (device_kind != kFlutterPointerDeviceKindMouse) {
684 break;
685 }
686
687 if (message == WM_LBUTTONUP) {
688 ReleaseCapture();
689 }
690 button_pressed = message;
691 if (message == WM_XBUTTONUP) {
692 button_pressed = GET_XBUTTON_WPARAM(wparam);
693 }
694 x_pos = GET_X_LPARAM(lparam);
695 y_pos = GET_Y_LPARAM(lparam);
696 OnPointerUp(static_cast<double>(x_pos), static_cast<double>(y_pos),
697 device_kind, kDefaultPointerDeviceId, button_pressed);
698 break;
699 case WM_MOUSEWHEEL:
700 OnScroll(0.0,
701 -(static_cast<short>(HIWORD(wparam)) /
702 static_cast<double>(WHEEL_DELTA)),
703 kFlutterPointerDeviceKindMouse, kDefaultPointerDeviceId);
704 break;
705 case WM_MOUSEHWHEEL:
706 OnScroll((static_cast<short>(HIWORD(wparam)) /
707 static_cast<double>(WHEEL_DELTA)),
708 0.0, kFlutterPointerDeviceKindMouse, kDefaultPointerDeviceId);
709 break;
710 case WM_GETOBJECT: {
711 LRESULT lresult = OnGetObject(message, wparam, lparam);
712 if (lresult) {
713 return lresult;
714 }
715 break;
716 }
717 case WM_TIMER:
718 if (wparam == kDirectManipulationTimer) {
719 direct_manipulation_owner_->Update();
720 return 0;
721 }
722 break;
723 case DM_POINTERHITTEST: {
724 if (direct_manipulation_owner_) {
725 UINT contact_id = GET_POINTERID_WPARAM(wparam);
726 POINTER_INPUT_TYPE pointer_type;
727 if (windows_proc_table_->GetPointerType(contact_id, &pointer_type) &&
728 pointer_type == PT_TOUCHPAD) {
729 direct_manipulation_owner_->SetContact(contact_id);
730 }
731 }
732 break;
733 }
734 case WM_INPUTLANGCHANGE:
735 // TODO(cbracken): pass this to TextInputManager to aid with
736 // language-specific issues.
737 break;
738 case WM_IME_SETCONTEXT:
739 OnImeSetContext(message, wparam, lparam);
740 // Strip the ISC_SHOWUICOMPOSITIONWINDOW bit from lparam before passing
741 // it to DefWindowProc() so that the composition window is hidden since
742 // Flutter renders the composing string itself.
743 result_lparam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
744 break;
745 case WM_IME_STARTCOMPOSITION:
746 OnImeStartComposition(message, wparam, lparam);
747 // Suppress further processing by DefWindowProc() so that the default
748 // system IME style isn't used, but rather the one set in the
749 // WM_IME_SETCONTEXT handler.
750 return TRUE;
751 case WM_IME_COMPOSITION:
752 OnImeComposition(message, wparam, lparam);
753 if (lparam & GCS_RESULTSTR || lparam & GCS_COMPSTR) {
754 // Suppress further processing by DefWindowProc() since otherwise it
755 // will emit the result string as WM_CHAR messages on commit. Instead,
756 // committing the composing text to the EditableText string is handled
757 // in TextInputModel::CommitComposing, triggered by
758 // OnImeEndComposition().
759 return TRUE;
760 }
761 break;
762 case WM_IME_ENDCOMPOSITION:
763 OnImeEndComposition(message, wparam, lparam);
764 return TRUE;
765 case WM_IME_REQUEST:
766 OnImeRequest(message, wparam, lparam);
767 break;
768 case WM_UNICHAR: {
769 // Tell third-pary app, we can support Unicode.
770 if (wparam == UNICODE_NOCHAR)
771 return TRUE;
772 // DefWindowProc will send WM_CHAR for this WM_UNICHAR.
773 break;
774 }
775 case WM_THEMECHANGED:
776 OnThemeChange();
777 break;
778 case WM_DEADCHAR:
779 case WM_SYSDEADCHAR:
780 case WM_CHAR:
781 case WM_SYSCHAR:
782 case WM_KEYDOWN:
783 case WM_SYSKEYDOWN:
784 case WM_KEYUP:
785 case WM_SYSKEYUP:
786 if (keyboard_manager_->HandleMessage(message, wparam, lparam)) {
787 return 0;
788 }
789 break;
790 }
791
792 return Win32DefWindowProc(window_handle_, message, wparam, result_lparam);
793 }
794
795 LRESULT FlutterWindow::OnGetObject(UINT const message,
796 WPARAM const wparam,
797 LPARAM const lparam) {
798 LRESULT reference_result = static_cast<LRESULT>(0L);
799
800 // Only the lower 32 bits of lparam are valid when checking the object id
801 // because it sometimes gets sign-extended incorrectly (but not always).
802 DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(lparam));
803
804 bool is_uia_request = static_cast<DWORD>(UiaRootObjectId) == obj_id;
805 bool is_msaa_request = static_cast<DWORD>(OBJID_CLIENT) == obj_id;
806
807 if (is_uia_request || is_msaa_request) {
808 // On Windows, we don't get a notification that the screen reader has been
809 // enabled or disabled. There is an API to query for screen reader state,
810 // but that state isn't set by all screen readers, including by Narrator,
811 // the screen reader that ships with Windows:
812 // https://docs.microsoft.com/en-us/windows/win32/winauto/screen-reader-parameter
813 //
814 // Instead, we enable semantics in Flutter if Windows issues queries for
815 // Microsoft Active Accessibility (MSAA) COM objects.
816 OnUpdateSemanticsEnabled(true);
817 }
818
819 gfx::NativeViewAccessible root_view = GetNativeViewAccessible();
820 // TODO(schectman): UIA is currently disabled by default.
821 // https://github.com/flutter/flutter/issues/114547
822 if (root_view) {
823 CreateAxFragmentRoot();
824 if (is_uia_request) {
825 #ifdef FLUTTER_ENGINE_USE_UIA
826 // Retrieve UIA object for the root view.
827 Microsoft::WRL::ComPtr<IRawElementProviderSimple> root;
828 if (SUCCEEDED(
829 ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(
830 IID_PPV_ARGS(&root)))) {
831 // Return the UIA object via UiaReturnRawElementProvider(). See:
832 // https://docs.microsoft.com/en-us/windows/win32/winauto/wm-getobject
833 reference_result = UiaReturnRawElementProvider(window_handle_, wparam,
834 lparam, root.Get());
835 } else {
836 FML_LOG(ERROR) << "Failed to query AX fragment root.";
837 }
838 #endif // FLUTTER_ENGINE_USE_UIA
839 } else if (is_msaa_request) {
840 // Create the accessibility root if it does not already exist.
841 // Return the IAccessible for the root view.
842 Microsoft::WRL::ComPtr<IAccessible> root;
843 ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(
844 IID_PPV_ARGS(&root));
845 reference_result = LresultFromObject(IID_IAccessible, wparam, root.Get());
846 }
847 }
848 return reference_result;
849 }
850
851 void FlutterWindow::OnImeSetContext(UINT const message,
852 WPARAM const wparam,
853 LPARAM const lparam) {
854 if (wparam != 0) {
855 text_input_manager_->CreateImeWindow();
856 }
857 }
858
859 void FlutterWindow::OnImeStartComposition(UINT const message,
860 WPARAM const wparam,
861 LPARAM const lparam) {
862 text_input_manager_->CreateImeWindow();
863 OnComposeBegin();
864 }
865
866 void FlutterWindow::OnImeComposition(UINT const message,
867 WPARAM const wparam,
868 LPARAM const lparam) {
869 // Update the IME window position.
870 text_input_manager_->UpdateImeWindow();
871
872 if (lparam == 0) {
873 OnComposeChange(u"", 0);
874 OnComposeCommit();
875 }
876
877 // Process GCS_RESULTSTR at fisrt, because Google Japanese Input and ATOK
878 // send both GCS_RESULTSTR and GCS_COMPSTR to commit composed text and send
879 // new composing text.
880 if (lparam & GCS_RESULTSTR) {
881 // Commit but don't end composing.
882 // Read the committed composing string.
883 long pos = text_input_manager_->GetComposingCursorPosition();
884 std::optional<std::u16string> text = text_input_manager_->GetResultString();
885 if (text) {
886 OnComposeChange(text.value(), pos);
887 OnComposeCommit();
888 }
889 }
890 if (lparam & GCS_COMPSTR) {
891 // Read the in-progress composing string.
892 long pos = text_input_manager_->GetComposingCursorPosition();
893 std::optional<std::u16string> text =
894 text_input_manager_->GetComposingString();
895 if (text) {
896 OnComposeChange(text.value(), pos);
897 }
898 }
899 }
900
901 void FlutterWindow::OnImeEndComposition(UINT const message,
902 WPARAM const wparam,
903 LPARAM const lparam) {
904 text_input_manager_->DestroyImeWindow();
905 OnComposeEnd();
906 }
907
908 void FlutterWindow::OnImeRequest(UINT const message,
909 WPARAM const wparam,
910 LPARAM const lparam) {
911 // TODO(cbracken): Handle IMR_RECONVERTSTRING, IMR_DOCUMENTFEED,
912 // and IMR_QUERYCHARPOSITION messages.
913 // https://github.com/flutter/flutter/issues/74547
914 }
915
916 void FlutterWindow::AbortImeComposing() {
917 text_input_manager_->AbortComposing();
918 }
919
920 void FlutterWindow::UpdateCursorRect(const Rect& rect) {
921 text_input_manager_->UpdateCaretRect(rect);
922 }
923
924 UINT FlutterWindow::GetCurrentDPI() {
925 return current_dpi_;
926 }
927
928 UINT FlutterWindow::GetCurrentWidth() {
929 return current_width_;
930 }
931
932 UINT FlutterWindow::GetCurrentHeight() {
933 return current_height_;
934 }
935
936 float FlutterWindow::GetScrollOffsetMultiplier() {
937 return scroll_offset_multiplier_;
938 }
939
940 LRESULT FlutterWindow::Win32DefWindowProc(HWND hWnd,
941 UINT Msg,
942 WPARAM wParam,
943 LPARAM lParam) {
944 return ::DefWindowProc(hWnd, Msg, wParam, lParam);
945 }
946
947 void FlutterWindow::Destroy() {
948 if (window_handle_) {
949 text_input_manager_->SetWindowHandle(nullptr);
950 DestroyWindow(window_handle_);
951 window_handle_ = nullptr;
952 }
953
954 UnregisterClass(window_class_name_.c_str(), nullptr);
955 }
956
957 void FlutterWindow::CreateAxFragmentRoot() {
958 if (ax_fragment_root_) {
959 return;
960 }
961 ax_fragment_root_ = std::make_unique<ui::AXFragmentRootWin>(
962 window_handle_, GetAxFragmentRootDelegate());
963 alert_delegate_ =
964 std::make_unique<AlertPlatformNodeDelegate>(*ax_fragment_root_);
965 ui::AXPlatformNode* alert_node =
966 ui::AXPlatformNodeWin::Create(alert_delegate_.get());
967 alert_node_.reset(static_cast<ui::AXPlatformNodeWin*>(alert_node));
968 ax_fragment_root_->SetAlertNode(alert_node_.get());
969 }
970
971 } // namespace flutter
flutter::AlertPlatformNodeDelegate
Definition: alert_platform_node_delegate.h:18
flutter::FlutterWindow::OnCursorRectUpdated
virtual void OnCursorRectUpdated(const Rect &rect) override
Definition: flutter_window.cc:264
flutter::FlutterWindow::OnPointerMove
virtual void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint32_t rotation, uint32_t pressure, int modifiers_state)
Definition: flutter_window.cc:168
flutter::FlutterWindow::OnPointerLeave
virtual void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)
Definition: flutter_window.cc:208
flutter::FlutterWindow::FlutterWindow
FlutterWindow()
Definition: flutter_window.cc:110
flutter::FlutterWindow::GetScrollOffsetMultiplier
virtual float GetScrollOffsetMultiplier()
Definition: flutter_window.cc:936
flutter::FlutterWindow::Focus
virtual bool Focus() override
Definition: flutter_window.cc:138
flutter::FlutterWindow::GetAlert
virtual ui::AXPlatformNodeWin * GetAlert() override
Definition: flutter_window.cc:339
flutter::FlutterWindow::OnText
virtual void OnText(const std::u16string &text) override
Definition: flutter_window.cc:215
flutter::FlutterWindow::Win32DispatchMessage
virtual UINT Win32DispatchMessage(UINT Msg, WPARAM wParam, LPARAM lParam) override
Definition: flutter_window.cc:464
flutter::FlutterWindow::Win32PeekMessage
virtual BOOL Win32PeekMessage(LPMSG lpMsg, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) override
Definition: flutter_window.cc:452
flutter::FlutterWindow::OnThemeChange
virtual void OnThemeChange()
Definition: flutter_window.cc:326
flutter::FlutterWindow::alert_delegate_
std::unique_ptr< AlertPlatformNodeDelegate > alert_delegate_
Definition: flutter_window.h:278
flutter::FlutterWindow::OnBitmapSurfaceUpdated
virtual bool OnBitmapSurfaceUpdated(const void *allocation, size_t row_bytes, size_t height) override
Definition: flutter_window.cc:283
flutter::FlutterWindow::OnPointerDown
virtual void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button, uint32_t rotation, uint32_t pressure)
Definition: flutter_window.cc:179
flutter::FlutterWindow::OnImeRequest
virtual void OnImeRequest(UINT const message, WPARAM const wparam, LPARAM const lparam)
Definition: flutter_window.cc:908
flutter::FlutterWindow::Win32DefWindowProc
virtual LRESULT Win32DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: flutter_window.cc:940
flutter::FlutterWindow::OnImeStartComposition
virtual void OnImeStartComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
Definition: flutter_window.cc:859
flutter::FlutterWindow::NarrowToWide
std::wstring NarrowToWide(const char *source)
Definition: flutter_window.cc:470
flutter::FlutterWindow::GetDisplayId
virtual FlutterEngineDisplayId GetDisplayId() override
Definition: flutter_window.cc:316
flutter::FlutterWindow::GetAxFragmentRootDelegate
virtual ui::AXFragmentRootDelegateWin * GetAxFragmentRootDelegate()
Definition: flutter_window.cc:330
flutter::FlutterWindow::OnScroll
virtual void OnScroll(double delta_x, double delta_y, FlutterPointerDeviceKind device_kind, int32_t device_id)
Definition: flutter_window.cc:251
flutter::FlutterWindow::OnPointerUp
virtual void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button)
Definition: flutter_window.cc:195
flutter::FlutterWindow::InitializeChild
void InitializeChild(const char *title, unsigned int width, unsigned int height)
Definition: flutter_window.cc:413
flutter::FlutterWindow::OnPaint
virtual void OnPaint()
Definition: flutter_window.cc:162
flutter::FlutterWindow::GetAlertDelegate
virtual AlertPlatformNodeDelegate * GetAlertDelegate() override
Definition: flutter_window.cc:334
flutter::FlutterWindow::direct_manipulation_owner_
std::unique_ptr< DirectManipulationOwner > direct_manipulation_owner_
Definition: flutter_window.h:285
flutter::FlutterWindow::GetWindowHandle
virtual HWND GetWindowHandle() override
Definition: flutter_window.cc:448
flutter::FlutterWindow::GetCurrentWidth
UINT GetCurrentWidth()
Definition: flutter_window.cc:928
flutter::FlutterWindow::OnComposeCommit
virtual void OnComposeCommit()
Definition: flutter_window.cc:234
flutter::FlutterWindow::UpdateCursorRect
virtual void UpdateCursorRect(const Rect &rect)
Definition: flutter_window.cc:920
flutter::FlutterWindow::GetPhysicalWindowBounds
virtual PhysicalWindowBounds GetPhysicalWindowBounds() override
Definition: flutter_window.cc:134
flutter::FlutterWindow::OnImeSetContext
virtual void OnImeSetContext(UINT const message, WPARAM const wparam, LPARAM const lparam)
Definition: flutter_window.cc:851
flutter::FlutterWindow::OnWindowStateEvent
virtual void OnWindowStateEvent(WindowStateEvent event)
Definition: flutter_window.cc:344
flutter::FlutterWindow::OnKey
virtual void OnKey(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback) override
Definition: flutter_window.cc:219
flutter::FlutterWindow::alert_node_
std::unique_ptr< ui::AXPlatformNodeWin > alert_node_
Definition: flutter_window.h:281
flutter::FlutterWindow::GetPrimaryPointerLocation
virtual PointerLocation GetPrimaryPointerLocation() override
Definition: flutter_window.cc:309
flutter::FlutterWindow::GetCurrentHeight
UINT GetCurrentHeight()
Definition: flutter_window.cc:932
flutter::FlutterWindow::OnComposeEnd
virtual void OnComposeEnd()
Definition: flutter_window.cc:238
flutter::FlutterWindow::SetView
virtual void SetView(WindowBindingHandlerDelegate *view) override
Definition: flutter_window.cc:117
flutter::FlutterWindow::~FlutterWindow
virtual ~FlutterWindow()
Definition: flutter_window.cc:113
flutter::FlutterWindow::HandleMessage
LRESULT HandleMessage(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept
Definition: flutter_window.cc:516
flutter::FlutterWindow::OnComposeChange
virtual void OnComposeChange(const std::u16string &text, int cursor_pos)
Definition: flutter_window.cc:242
flutter::FlutterWindow::OnResetImeComposing
virtual void OnResetImeComposing() override
Definition: flutter_window.cc:272
flutter::FlutterWindow::Win32MapVkToChar
virtual uint32_t Win32MapVkToChar(uint32_t virtual_key) override
Definition: flutter_window.cc:460
flutter::FlutterWindow::OnImeComposition
virtual void OnImeComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
Definition: flutter_window.cc:866
flutter::FlutterWindow::GetCurrentDPI
UINT GetCurrentDPI()
Definition: flutter_window.cc:924
flutter::FlutterWindow::OnDpiScale
virtual void OnDpiScale(unsigned int dpi)
Definition: flutter_window.cc:152
flutter::FlutterWindow::AbortImeComposing
virtual void AbortImeComposing()
Definition: flutter_window.cc:916
flutter::FlutterWindow::GetDpiScale
virtual float GetDpiScale() override
Definition: flutter_window.cc:130
flutter::FlutterWindow::OnUpdateSemanticsEnabled
virtual void OnUpdateSemanticsEnabled(bool enabled)
Definition: flutter_window.cc:247
flutter::FlutterWindow::OnGetObject
virtual LRESULT OnGetObject(UINT const message, WPARAM const wparam, LPARAM const lparam)
Definition: flutter_window.cc:795
flutter::FlutterWindow::GetNativeViewAccessible
virtual gfx::NativeViewAccessible GetNativeViewAccessible()
Definition: flutter_window.cc:301
flutter::FlutterWindow::OnComposeBegin
virtual void OnComposeBegin()
Definition: flutter_window.cc:230
flutter::FlutterWindow::OnBitmapSurfaceCleared
virtual bool OnBitmapSurfaceCleared() override
Definition: flutter_window.cc:276
flutter::FlutterWindow::OnResize
virtual void OnResize(unsigned int width, unsigned int height)
Definition: flutter_window.cc:156
flutter::FlutterWindow::OnImeEndComposition
virtual void OnImeEndComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
Definition: flutter_window.cc:901
flutter::KeyboardManager::WindowDelegate::KeyEventCallback
std::function< void(bool)> KeyEventCallback
Definition: keyboard_manager.h:54
flutter::WindowBindingHandlerDelegate
Definition: window_binding_handler_delegate.h:18
flutter::WindowBindingHandlerDelegate::OnComposeChange
virtual void OnComposeChange(const std::u16string &text, int cursor_pos)=0
flutter::WindowBindingHandlerDelegate::OnHighContrastChanged
virtual void OnHighContrastChanged()=0
flutter::WindowBindingHandlerDelegate::OnText
virtual void OnText(const std::u16string &)=0
flutter::WindowBindingHandlerDelegate::OnPointerLeave
virtual void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)=0
flutter::WindowBindingHandlerDelegate::OnKey
virtual void OnKey(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback)=0
flutter::WindowBindingHandlerDelegate::OnUpdateSemanticsEnabled
virtual void OnUpdateSemanticsEnabled(bool enabled)=0
flutter::WindowBindingHandlerDelegate::OnPointerMove
virtual void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint32_t rotation, uint32_t pressure, int modifiers_state)=0
flutter::WindowBindingHandlerDelegate::OnPointerUp
virtual void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button)=0
flutter::WindowBindingHandlerDelegate::OnWindowStateEvent
virtual void OnWindowStateEvent(HWND hwnd, WindowStateEvent event)=0
flutter::WindowBindingHandlerDelegate::GetAxFragmentRootDelegate
virtual ui::AXFragmentRootDelegateWin * GetAxFragmentRootDelegate()=0
flutter::WindowBindingHandlerDelegate::OnComposeEnd
virtual void OnComposeEnd()=0
flutter::WindowBindingHandlerDelegate::OnWindowRepaint
virtual void OnWindowRepaint()=0
flutter::WindowBindingHandlerDelegate::GetNativeViewAccessible
virtual gfx::NativeViewAccessible GetNativeViewAccessible()=0
flutter::WindowBindingHandlerDelegate::OnWindowSizeChanged
virtual bool OnWindowSizeChanged(size_t width, size_t height)=0
flutter::WindowBindingHandlerDelegate::OnComposeBegin
virtual void OnComposeBegin()=0
flutter::WindowBindingHandlerDelegate::OnFocus
virtual void OnFocus(FlutterViewFocusState focus_state, FlutterViewFocusDirection direction)=0
flutter::WindowBindingHandlerDelegate::OnScroll
virtual void OnScroll(double x, double y, double delta_x, double delta_y, int scroll_offset_multiplier, FlutterPointerDeviceKind device_kind, int32_t device_id)=0
flutter::WindowBindingHandlerDelegate::OnComposeCommit
virtual void OnComposeCommit()=0
flutter::WindowBindingHandlerDelegate::OnPointerDown
virtual void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button, uint32_t rotation, uint32_t pressure)=0
display_manager
const DisplayManagerWin32 * display_manager
Definition: display_manager.cc:18
display_manager.h
dpi_utils.h
flutter_window.h
flutter_windows_engine.h
flutter_windows_view.h
callback
FlutterDesktopBinaryReply callback
Definition: flutter_windows_view_unittests.cc:52
extended
bool extended
Definition: keyboard_key_handler_unittests.cc:118
key
int key
Definition: keyboard_key_handler_unittests.cc:114
character
char32_t character
Definition: keyboard_key_handler_unittests.cc:117
action
int action
Definition: keyboard_key_handler_unittests.cc:116
scancode
int scancode
Definition: keyboard_key_handler_unittests.cc:115
was_down
bool was_down
Definition: keyboard_key_handler_unittests.cc:119
text
std::u16string text
Definition: keyboard_unittests.cc:332
message
Win32Message message
Definition: keyboard_unittests.cc:137
keyboard_utils.h
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::kShift
constexpr int kShift
Definition: keyboard_utils.h:14
flutter::GetDpiForHWND
UINT GetDpiForHWND(HWND hwnd)
Definition: dpi_utils.cc:128
flutter::WindowStateEvent
WindowStateEvent
An event representing a change in window state that may update the.
Definition: windows_lifecycle_manager.h:24
flutter::WindowStateEvent::kHide
@ kHide
flutter::WindowStateEvent::kUnfocus
@ kUnfocus
flutter::WindowStateEvent::kShow
@ kShow
flutter::WindowStateEvent::kFocus
@ kFocus
flutter::kControl
constexpr int kControl
Definition: keyboard_utils.h:15
flutter::PhysicalWindowBounds
Definition: window_binding_handler.h:28
flutter::PointerLocation
Definition: window_binding_handler.h:35