13 #include "flutter/fml/logging.h"
14 #include "flutter/shell/platform/embedder/embedder.h"
27 constexpr
int base_dpi = 96;
29 static const int kMinTouchDeviceId = 0;
30 static const int kMaxTouchDeviceId = 128;
32 static const int kLinesPerScrollWindowsDefault = 3;
34 static constexpr int32_t kDefaultPointerDeviceId = 0;
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;
49 return kFlutterPointerDeviceKindStylus;
51 return kFlutterPointerDeviceKindMouse;
55 static uint64_t ConvertWinButtonToFlutterButton(UINT button) {
59 return kFlutterPointerButtonMousePrimary;
62 return kFlutterPointerButtonMouseSecondary;
65 return kFlutterPointerButtonMouseMiddle;
67 return kFlutterPointerButtonMouseBack;
69 return kFlutterPointerButtonMouseForward;
71 FML_LOG(WARNING) <<
"Mouse button not recognized: " << button;
81 std::shared_ptr<WindowsProcTable> windows_proc_table,
82 std::unique_ptr<TextInputManager> text_input_manager)
83 : touch_id_generator_(kMinTouchDeviceId, kMaxTouchDeviceId),
85 windows_proc_table_(std::move(windows_proc_table)),
86 text_input_manager_(std::move(text_input_manager)),
87 ax_fragment_root_(nullptr) {
96 UpdateScrollOffsetMultiplier();
98 if (windows_proc_table_ ==
nullptr) {
99 windows_proc_table_ = std::make_unique<WindowsProcTable>();
101 if (text_input_manager_ ==
nullptr) {
102 text_input_manager_ = std::make_unique<TextInputManager>();
104 keyboard_manager_ = std::make_unique<KeyboardManager>(
this);
111 : touch_id_generator_(kMinTouchDeviceId, kMaxTouchDeviceId) {}
118 binding_handler_delegate_ = window;
122 if (restored_ && window) {
125 if (focused_ && window) {
131 return static_cast<float>(
GetCurrentDPI()) /
static_cast<float>(base_dpi);
140 if (hwnd ==
nullptr) {
144 HWND prevFocus = ::SetFocus(hwnd);
145 if (prevFocus ==
nullptr) {
157 if (binding_handler_delegate_ !=
nullptr) {
163 if (binding_handler_delegate_ !=
nullptr) {
170 FlutterPointerDeviceKind device_kind,
174 int modifiers_state) {
175 binding_handler_delegate_->
OnPointerMove(x, y, device_kind, device_id,
176 rotation, pressure, modifiers_state);
181 FlutterPointerDeviceKind device_kind,
186 uint64_t flutter_button = ConvertWinButtonToFlutterButton(button);
187 if (flutter_button != 0) {
189 x, y, device_kind, device_id,
190 static_cast<FlutterPointerMouseButtons
>(flutter_button), rotation,
197 FlutterPointerDeviceKind device_kind,
200 uint64_t flutter_button = ConvertWinButtonToFlutterButton(button);
201 if (flutter_button != 0) {
203 x, y, device_kind, device_id,
204 static_cast<FlutterPointerMouseButtons
>(flutter_button));
210 FlutterPointerDeviceKind device_kind,
212 binding_handler_delegate_->
OnPointerLeave(x, y, device_kind, device_id);
253 FlutterPointerDeviceKind device_kind,
256 GetCursorPos(&point);
259 binding_handler_delegate_->
OnScroll(point.x, point.y, delta_x, delta_y,
267 Point origin(rect.left() * scale, rect.top() * scale);
268 Size size(rect.width() * scale, rect.height() * scale);
278 bool result = ::PatBlt(dc, 0, 0, current_width_, current_height_, BLACKNESS);
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);
302 if (binding_handler_delegate_ ==
nullptr) {
311 GetCursorPos(&point);
313 return {(size_t)point.x, (
size_t)point.y};
317 FlutterEngineDisplayId
const display_id =
318 reinterpret_cast<FlutterEngineDisplayId
>(
320 if (!display_manager_->FindById(display_id)) {
321 FML_LOG(ERROR) <<
"Current monitor not found in display list.";
335 CreateAxFragmentRoot();
340 CreateAxFragmentRoot();
355 if (binding_handler_delegate_) {
356 binding_handler_delegate_->
OnFocus(
357 FlutterViewFocusState::kFocused,
358 FlutterViewFocusDirection::kUndefined);
363 if (binding_handler_delegate_) {
364 binding_handler_delegate_->
OnFocus(
365 FlutterViewFocusState::kUnfocused,
366 FlutterViewFocusDirection::kUndefined);
371 if (hwnd && binding_handler_delegate_) {
376 void FlutterWindow::TrackMouseLeaveEvent(HWND hwnd) {
377 if (!tracking_mouse_leave_) {
379 tme.cbSize =
sizeof(tme);
380 tme.hwndTrack = hwnd;
381 tme.dwFlags = TME_LEAVE;
382 TrackMouseEvent(&tme);
383 tracking_mouse_leave_ =
true;
387 void FlutterWindow::HandleResize(UINT width, UINT height) {
388 current_width_ = width;
389 current_height_ = height;
396 FlutterWindow* FlutterWindow::GetThisFromHandle(HWND
const window) noexcept {
397 return reinterpret_cast<FlutterWindow*
>(
398 GetWindowLongPtr(window, GWLP_USERDATA));
401 void FlutterWindow::UpdateScrollOffsetMultiplier() {
402 UINT lines_per_scroll = kLinesPerScrollWindowsDefault;
405 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines_per_scroll, 0);
409 scroll_offset_multiplier_ =
410 static_cast<float>(lines_per_scroll) * 100.0 / 3.0;
415 unsigned int height) {
419 WNDCLASS window_class = RegisterWindowClass(converted_title);
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);
426 if (result ==
nullptr) {
427 auto error = GetLastError();
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);
437 SetUserObjectInformationA(GetCurrentProcess(),
438 UOI_TIMERPROC_EXCEPTION_SUPPRESSION, FALSE, 1);
443 SetTimer(result, kDirectManipulationTimer, 14,
nullptr);
449 return window_handle_;
456 return ::PeekMessage(lpMsg, window_handle_, wMsgFilterMin, wMsgFilterMax,
461 return ::MapVirtualKey(virtual_key, MAPVK_VK_TO_CHAR);
467 return ::SendMessage(window_handle_, Msg, wParam, lParam);
471 size_t length = strlen(source);
473 std::wstring wideTitle(length, L
'#');
474 mbstowcs_s(&outlen, &wideTitle[0], length + 1, source, length);
478 WNDCLASS FlutterWindow::RegisterWindowClass(std::wstring& title) {
479 window_class_name_ = title;
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);
496 LRESULT CALLBACK FlutterWindow::WndProc(HWND
const window,
499 LPARAM
const lparam) noexcept {
501 auto cs =
reinterpret_cast<CREATESTRUCT*
>(lparam);
502 SetWindowLongPtr(window, GWLP_USERDATA,
503 reinterpret_cast<LONG_PTR
>(cs->lpCreateParams));
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);
512 return DefWindowProc(window,
message, wparam, lparam);
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;
526 case kWmDpiChangedBeforeParent:
528 OnDpiScale(current_dpi_);
531 width = LOWORD(lparam);
532 height = HIWORD(lparam);
534 current_width_ = width;
535 current_height_ = height;
536 HandleResize(width, height);
545 case WM_POINTERUPDATE:
547 case WM_POINTERLEAVE: {
548 POINT pt = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
549 ScreenToClient(window_handle_, &pt);
550 auto const x =
static_cast<double>(pt.x);
551 auto const y =
static_cast<double>(pt.y);
552 auto const pointerId = GET_POINTERID_WPARAM(wparam);
553 POINTER_INFO pointerInfo;
554 if (windows_proc_table_->GetPointerInfo(pointerId, &pointerInfo)) {
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;
564 auto touch_id = touch_id_generator_.GetGeneratedId(pointerId);
565 FlutterPointerDeviceKind device_kind = kFlutterPointerDeviceKindMouse;
566 switch (pointerInfo.pointerType) {
568 device_kind = kFlutterPointerDeviceKindTouch;
571 device_kind = kFlutterPointerDeviceKindStylus;
574 device_kind = kFlutterPointerDeviceKindMouse;
577 device_kind = kFlutterPointerDeviceKindTrackpad;
580 FML_LOG(ERROR) <<
"Unrecognized device key "
581 << pointerInfo.pointerType;
584 if (
message == WM_POINTERDOWN) {
585 OnPointerDown(x, y, device_kind, touch_id, WM_LBUTTONDOWN, rotation,
587 }
else if (
message == WM_POINTERUPDATE) {
588 OnPointerMove(x, y, device_kind, touch_id, rotation, pressure,
590 }
else if (
message == WM_POINTERUP) {
591 OnPointerUp(x, y, device_kind, touch_id, WM_LBUTTONUP);
594 }
else if (
message == WM_POINTERLEAVE) {
595 OnPointerLeave(x, y, device_kind, touch_id);
596 touch_id_generator_.ReleaseNumber(pointerId);
602 device_kind = GetFlutterPointerDeviceKind();
603 if (device_kind == kFlutterPointerDeviceKindMouse) {
604 TrackMouseLeaveEvent(window_handle_);
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);
612 if (wparam & MK_CONTROL) {
615 if (wparam & MK_SHIFT) {
618 OnPointerMove(mouse_x_, mouse_y_, device_kind, kDefaultPointerDeviceId,
623 device_kind = GetFlutterPointerDeviceKind();
624 if (device_kind == kFlutterPointerDeviceKindMouse) {
625 OnPointerLeave(mouse_x_, mouse_y_, device_kind,
626 kDefaultPointerDeviceId);
632 tracking_mouse_leave_ =
false;
635 UINT hit_test_result = LOWORD(lparam);
636 if (hit_test_result == HTCLIENT) {
645 ::CreateCaret(window_handle_,
nullptr, 1, 1);
655 device_kind = GetFlutterPointerDeviceKind();
656 if (device_kind != kFlutterPointerDeviceKindMouse) {
660 if (
message == WM_LBUTTONDOWN) {
666 SetCapture(window_handle_);
669 if (
message == WM_XBUTTONDOWN) {
670 button_pressed = GET_XBUTTON_WPARAM(wparam);
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,
682 device_kind = GetFlutterPointerDeviceKind();
683 if (device_kind != kFlutterPointerDeviceKindMouse) {
692 button_pressed = GET_XBUTTON_WPARAM(wparam);
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);
701 -(
static_cast<short>(HIWORD(wparam)) /
702 static_cast<double>(WHEEL_DELTA)),
703 kFlutterPointerDeviceKindMouse, kDefaultPointerDeviceId);
706 OnScroll((
static_cast<short>(HIWORD(wparam)) /
707 static_cast<double>(WHEEL_DELTA)),
708 0.0, kFlutterPointerDeviceKindMouse, kDefaultPointerDeviceId);
711 LRESULT lresult = OnGetObject(
message, wparam, lparam);
718 if (wparam == kDirectManipulationTimer) {
719 direct_manipulation_owner_->Update();
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);
734 case WM_INPUTLANGCHANGE:
738 case WM_IME_SETCONTEXT:
739 OnImeSetContext(
message, wparam, lparam);
743 result_lparam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
745 case WM_IME_STARTCOMPOSITION:
746 OnImeStartComposition(
message, wparam, lparam);
751 case WM_IME_COMPOSITION:
752 OnImeComposition(
message, wparam, lparam);
753 if (lparam & GCS_RESULTSTR || lparam & GCS_COMPSTR) {
762 case WM_IME_ENDCOMPOSITION:
763 OnImeEndComposition(
message, wparam, lparam);
766 OnImeRequest(
message, wparam, lparam);
770 if (wparam == UNICODE_NOCHAR)
775 case WM_THEMECHANGED:
786 if (keyboard_manager_->HandleMessage(
message, wparam, lparam)) {
792 return Win32DefWindowProc(window_handle_,
message, wparam, result_lparam);
797 LPARAM
const lparam) {
798 LRESULT reference_result =
static_cast<LRESULT
>(0L);
802 DWORD obj_id =
static_cast<DWORD
>(
static_cast<DWORD_PTR
>(lparam));
804 bool is_uia_request =
static_cast<DWORD
>(UiaRootObjectId) == obj_id;
805 bool is_msaa_request =
static_cast<DWORD
>(OBJID_CLIENT) == obj_id;
807 if (is_uia_request || is_msaa_request) {
823 CreateAxFragmentRoot();
824 if (is_uia_request) {
825 #ifdef FLUTTER_ENGINE_USE_UIA
827 Microsoft::WRL::ComPtr<IRawElementProviderSimple> root;
829 ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(
830 IID_PPV_ARGS(&root)))) {
833 reference_result = UiaReturnRawElementProvider(window_handle_, wparam,
836 FML_LOG(ERROR) <<
"Failed to query AX fragment root.";
839 }
else if (is_msaa_request) {
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());
848 return reference_result;
853 LPARAM
const lparam) {
855 text_input_manager_->CreateImeWindow();
861 LPARAM
const lparam) {
862 text_input_manager_->CreateImeWindow();
868 LPARAM
const lparam) {
870 text_input_manager_->UpdateImeWindow();
880 if (lparam & GCS_RESULTSTR) {
883 long pos = text_input_manager_->GetComposingCursorPosition();
884 std::optional<std::u16string>
text = text_input_manager_->GetResultString();
890 if (lparam & GCS_COMPSTR) {
892 long pos = text_input_manager_->GetComposingCursorPosition();
893 std::optional<std::u16string>
text =
894 text_input_manager_->GetComposingString();
903 LPARAM
const lparam) {
904 text_input_manager_->DestroyImeWindow();
910 LPARAM
const lparam) {
917 text_input_manager_->AbortComposing();
921 text_input_manager_->UpdateCaretRect(rect);
929 return current_width_;
933 return current_height_;
937 return scroll_offset_multiplier_;
944 return ::DefWindowProc(hWnd, Msg, wParam, lParam);
947 void FlutterWindow::Destroy() {
948 if (window_handle_) {
949 text_input_manager_->SetWindowHandle(
nullptr);
950 DestroyWindow(window_handle_);
951 window_handle_ =
nullptr;
954 UnregisterClass(window_class_name_.c_str(),
nullptr);
957 void FlutterWindow::CreateAxFragmentRoot() {
958 if (ax_fragment_root_) {
961 ax_fragment_root_ = std::make_unique<ui::AXFragmentRootWin>(
964 std::make_unique<AlertPlatformNodeDelegate>(*ax_fragment_root_);
965 ui::AXPlatformNode* alert_node =
967 alert_node_.reset(
static_cast<ui::AXPlatformNodeWin*
>(alert_node));
968 ax_fragment_root_->SetAlertNode(
alert_node_.get());
virtual void OnCursorRectUpdated(const Rect &rect) override
virtual void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint32_t rotation, uint32_t pressure, int modifiers_state)
virtual void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)
virtual float GetScrollOffsetMultiplier()
virtual bool Focus() override
virtual ui::AXPlatformNodeWin * GetAlert() override
virtual void OnText(const std::u16string &text) override
virtual UINT Win32DispatchMessage(UINT Msg, WPARAM wParam, LPARAM lParam) override
virtual BOOL Win32PeekMessage(LPMSG lpMsg, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) override
virtual void OnThemeChange()
std::unique_ptr< AlertPlatformNodeDelegate > alert_delegate_
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, UINT button, uint32_t rotation, uint32_t pressure)
virtual void OnImeRequest(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual LRESULT Win32DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
virtual void OnImeStartComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
std::wstring NarrowToWide(const char *source)
virtual FlutterEngineDisplayId GetDisplayId() override
virtual ui::AXFragmentRootDelegateWin * GetAxFragmentRootDelegate()
virtual void OnScroll(double delta_x, double delta_y, FlutterPointerDeviceKind device_kind, int32_t device_id)
virtual void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button)
void InitializeChild(const char *title, unsigned int width, unsigned int height)
virtual AlertPlatformNodeDelegate * GetAlertDelegate() override
std::unique_ptr< DirectManipulationOwner > direct_manipulation_owner_
virtual HWND GetWindowHandle() override
virtual void OnComposeCommit()
virtual void UpdateCursorRect(const Rect &rect)
virtual PhysicalWindowBounds GetPhysicalWindowBounds() override
virtual void OnImeSetContext(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual void OnWindowStateEvent(WindowStateEvent event)
virtual void OnKey(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback) override
std::unique_ptr< ui::AXPlatformNodeWin > alert_node_
virtual PointerLocation GetPrimaryPointerLocation() override
virtual void OnComposeEnd()
virtual void SetView(WindowBindingHandlerDelegate *view) override
LRESULT HandleMessage(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept
virtual void OnComposeChange(const std::u16string &text, int cursor_pos)
virtual void OnResetImeComposing() override
virtual uint32_t Win32MapVkToChar(uint32_t virtual_key) override
virtual void OnImeComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual void OnDpiScale(unsigned int dpi)
virtual void AbortImeComposing()
virtual float GetDpiScale() override
virtual void OnUpdateSemanticsEnabled(bool enabled)
virtual LRESULT OnGetObject(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual gfx::NativeViewAccessible GetNativeViewAccessible()
virtual void OnComposeBegin()
virtual bool OnBitmapSurfaceCleared() override
virtual void OnResize(unsigned int width, unsigned int height)
virtual void OnImeEndComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
std::function< void(bool)> KeyEventCallback
virtual void OnComposeChange(const std::u16string &text, int cursor_pos)=0
virtual void OnHighContrastChanged()=0
virtual void OnText(const std::u16string &)=0
virtual void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)=0
virtual void OnKey(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback)=0
virtual void OnUpdateSemanticsEnabled(bool enabled)=0
virtual void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint32_t rotation, uint32_t pressure, int modifiers_state)=0
virtual void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button)=0
virtual void OnWindowStateEvent(HWND hwnd, WindowStateEvent event)=0
virtual ui::AXFragmentRootDelegateWin * GetAxFragmentRootDelegate()=0
virtual void OnComposeEnd()=0
virtual void OnWindowRepaint()=0
virtual gfx::NativeViewAccessible GetNativeViewAccessible()=0
virtual bool OnWindowSizeChanged(size_t width, size_t height)=0
virtual void OnComposeBegin()=0
virtual void OnFocus(FlutterViewFocusState focus_state, FlutterViewFocusDirection direction)=0
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
virtual void OnComposeCommit()=0
virtual void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button, uint32_t rotation, uint32_t pressure)=0
const DisplayManagerWin32 * display_manager
FlutterDesktopBinaryReply callback
UINT GetDpiForHWND(HWND hwnd)
WindowStateEvent
An event representing a change in window state that may update the.