Flutter Windows Embedder
flutter::FlutterWindow Class Reference

#include <flutter_window.h>

Inheritance diagram for flutter::FlutterWindow:
flutter::KeyboardManager::WindowDelegate flutter::WindowBindingHandler

Public Member Functions

 FlutterWindow (int width, int height, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr, std::unique_ptr< TextInputManager > text_input_manager=nullptr)
 
virtual ~FlutterWindow ()
 
void InitializeChild (const char *title, unsigned int width, unsigned int height)
 
virtual BOOL Win32PeekMessage (LPMSG lpMsg, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) override
 
virtual uint32_t Win32MapVkToChar (uint32_t virtual_key) override
 
virtual UINT Win32DispatchMessage (UINT Msg, WPARAM wParam, LPARAM lParam) override
 
virtual void OnDpiScale (unsigned int dpi)
 
virtual void OnResize (unsigned int width, unsigned int height)
 
virtual void OnPaint ()
 
virtual void OnPointerMove (double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, int modifiers_state)
 
virtual void OnPointerDown (double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button)
 
virtual void OnPointerUp (double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button)
 
virtual void OnPointerLeave (double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)
 
virtual void OnText (const std::u16string &text) override
 
virtual void OnKey (int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback) override
 
virtual void OnComposeBegin ()
 
virtual void OnComposeCommit ()
 
virtual void OnComposeEnd ()
 
virtual void OnComposeChange (const std::u16string &text, int cursor_pos)
 
virtual void OnCursorRectUpdated (const Rect &rect) override
 
virtual void OnResetImeComposing () override
 
virtual void OnUpdateSemanticsEnabled (bool enabled)
 
virtual void OnScroll (double delta_x, double delta_y, FlutterPointerDeviceKind device_kind, int32_t device_id)
 
virtual gfx::NativeViewAccessible GetNativeViewAccessible ()
 
virtual void SetView (WindowBindingHandlerDelegate *view) override
 
virtual HWND GetWindowHandle () override
 
virtual float GetDpiScale () override
 
virtual PhysicalWindowBounds GetPhysicalWindowBounds () override
 
virtual bool OnBitmapSurfaceCleared () override
 
virtual bool OnBitmapSurfaceUpdated (const void *allocation, size_t row_bytes, size_t height) override
 
virtual PointerLocation GetPrimaryPointerLocation () override
 
virtual void OnThemeChange ()
 
virtual AlertPlatformNodeDelegateGetAlertDelegate () override
 
virtual ui::AXPlatformNodeWin * GetAlert () override
 
virtual bool Focus () override
 
virtual ui::AXFragmentRootDelegateWin * GetAxFragmentRootDelegate ()
 
virtual void OnWindowStateEvent (WindowStateEvent event)
 
- Public Member Functions inherited from flutter::KeyboardManager::WindowDelegate
virtual ~WindowDelegate ()=default
 
- Public Member Functions inherited from flutter::WindowBindingHandler
virtual ~WindowBindingHandler ()=default
 

Protected Member Functions

 FlutterWindow ()
 
virtual LRESULT Win32DefWindowProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 
std::wstring NarrowToWide (const char *source)
 
LRESULT HandleMessage (UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept
 
virtual LRESULT OnGetObject (UINT const message, WPARAM const wparam, LPARAM const lparam)
 
virtual void OnImeSetContext (UINT const message, WPARAM const wparam, LPARAM const lparam)
 
virtual void OnImeStartComposition (UINT const message, WPARAM const wparam, LPARAM const lparam)
 
virtual void OnImeComposition (UINT const message, WPARAM const wparam, LPARAM const lparam)
 
virtual void OnImeEndComposition (UINT const message, WPARAM const wparam, LPARAM const lparam)
 
virtual void OnImeRequest (UINT const message, WPARAM const wparam, LPARAM const lparam)
 
virtual void AbortImeComposing ()
 
virtual void UpdateCursorRect (const Rect &rect)
 
UINT GetCurrentDPI ()
 
UINT GetCurrentWidth ()
 
UINT GetCurrentHeight ()
 
virtual float GetScrollOffsetMultiplier ()
 

Protected Attributes

std::unique_ptr< AlertPlatformNodeDelegatealert_delegate_
 
std::unique_ptr< ui::AXPlatformNodeWin > alert_node_
 
std::unique_ptr< DirectManipulationOwnerdirect_manipulation_owner_
 

Friends

class WindowAXFragmentRootDelegate
 

Additional Inherited Members

- Public Types inherited from flutter::KeyboardManager::WindowDelegate
using KeyEventCallback = std::function< void(bool)>
 

Detailed Description

Definition at line 35 of file flutter_window.h.

Constructor & Destructor Documentation

◆ FlutterWindow() [1/2]

flutter::FlutterWindow::FlutterWindow ( int  width,
int  height,
std::shared_ptr< WindowsProcTable windows_proc_table = nullptr,
std::unique_ptr< TextInputManager text_input_manager = nullptr 
)

Definition at line 76 of file flutter_window.cc.

81  : touch_id_generator_(kMinTouchDeviceId, kMaxTouchDeviceId),
82  windows_proc_table_(std::move(windows_proc_table)),
83  text_input_manager_(std::move(text_input_manager)),
84  ax_fragment_root_(nullptr) {
85  // Get the DPI of the primary monitor as the initial DPI. If Per-Monitor V2 is
86  // supported, |current_dpi_| should be updated in the
87  // kWmDpiChangedBeforeParent message.
88  current_dpi_ = GetDpiForHWND(nullptr);
89 
90  // Get initial value for wheel scroll lines
91  // TODO: Listen to changes for this value
92  // https://github.com/flutter/flutter/issues/107248
93  UpdateScrollOffsetMultiplier();
94 
95  if (windows_proc_table_ == nullptr) {
96  windows_proc_table_ = std::make_unique<WindowsProcTable>();
97  }
98  if (text_input_manager_ == nullptr) {
99  text_input_manager_ = std::make_unique<TextInputManager>();
100  }
101  keyboard_manager_ = std::make_unique<KeyboardManager>(this);
102 
103  InitializeChild("FLUTTERVIEW", width, height);
104 }
void InitializeChild(const char *title, unsigned int width, unsigned int height)
UINT GetDpiForHWND(HWND hwnd)
Definition: dpi_utils.cc:130

References flutter::GetDpiForHWND(), and InitializeChild().

◆ ~FlutterWindow()

flutter::FlutterWindow::~FlutterWindow ( )
virtual

Definition at line 110 of file flutter_window.cc.

110  {
111  Destroy();
112 }

◆ FlutterWindow() [2/2]

flutter::FlutterWindow::FlutterWindow ( )
protected

Definition at line 107 of file flutter_window.cc.

108  : touch_id_generator_(kMinTouchDeviceId, kMaxTouchDeviceId) {}

Member Function Documentation

◆ AbortImeComposing()

void flutter::FlutterWindow::AbortImeComposing ( )
protectedvirtual

Definition at line 873 of file flutter_window.cc.

873  {
874  text_input_manager_->AbortComposing();
875 }

Referenced by OnResetImeComposing().

◆ Focus()

bool flutter::FlutterWindow::Focus ( )
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 135 of file flutter_window.cc.

135  {
136  auto hwnd = GetWindowHandle();
137  if (hwnd == nullptr) {
138  return false;
139  }
140 
141  HWND prevFocus = ::SetFocus(hwnd);
142  if (prevFocus == nullptr) {
143  return false;
144  }
145 
146  return true;
147 }
virtual HWND GetWindowHandle() override

References GetWindowHandle().

◆ GetAlert()

ui::AXPlatformNodeWin * flutter::FlutterWindow::GetAlert ( )
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 321 of file flutter_window.cc.

321  {
322  CreateAxFragmentRoot();
323  return alert_node_.get();
324 }
std::unique_ptr< ui::AXPlatformNodeWin > alert_node_

References alert_node_.

◆ GetAlertDelegate()

AlertPlatformNodeDelegate * flutter::FlutterWindow::GetAlertDelegate ( )
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 316 of file flutter_window.cc.

316  {
317  CreateAxFragmentRoot();
318  return alert_delegate_.get();
319 }
std::unique_ptr< AlertPlatformNodeDelegate > alert_delegate_

References alert_delegate_.

◆ GetAxFragmentRootDelegate()

ui::AXFragmentRootDelegateWin * flutter::FlutterWindow::GetAxFragmentRootDelegate ( )
virtual

Definition at line 312 of file flutter_window.cc.

312  {
313  return binding_handler_delegate_->GetAxFragmentRootDelegate();
314 }
virtual ui::AXFragmentRootDelegateWin * GetAxFragmentRootDelegate()=0

References flutter::WindowBindingHandlerDelegate::GetAxFragmentRootDelegate().

◆ GetCurrentDPI()

UINT flutter::FlutterWindow::GetCurrentDPI ( )
protected

Definition at line 881 of file flutter_window.cc.

881  {
882  return current_dpi_;
883 }

Referenced by GetDpiScale().

◆ GetCurrentHeight()

UINT flutter::FlutterWindow::GetCurrentHeight ( )
protected

Definition at line 889 of file flutter_window.cc.

889  {
890  return current_height_;
891 }

Referenced by GetPhysicalWindowBounds().

◆ GetCurrentWidth()

UINT flutter::FlutterWindow::GetCurrentWidth ( )
protected

Definition at line 885 of file flutter_window.cc.

885  {
886  return current_width_;
887 }

Referenced by GetPhysicalWindowBounds().

◆ GetDpiScale()

float flutter::FlutterWindow::GetDpiScale ( )
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 127 of file flutter_window.cc.

127  {
128  return static_cast<float>(GetCurrentDPI()) / static_cast<float>(base_dpi);
129 }

References GetCurrentDPI().

Referenced by OnCursorRectUpdated().

◆ GetNativeViewAccessible()

gfx::NativeViewAccessible flutter::FlutterWindow::GetNativeViewAccessible ( )
virtual

Definition at line 293 of file flutter_window.cc.

293  {
294  if (binding_handler_delegate_ == nullptr) {
295  return nullptr;
296  }
297 
298  return binding_handler_delegate_->GetNativeViewAccessible();
299 }
virtual gfx::NativeViewAccessible GetNativeViewAccessible()=0

References flutter::WindowBindingHandlerDelegate::GetNativeViewAccessible().

Referenced by OnGetObject().

◆ GetPhysicalWindowBounds()

PhysicalWindowBounds flutter::FlutterWindow::GetPhysicalWindowBounds ( )
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 131 of file flutter_window.cc.

131  {
132  return {GetCurrentWidth(), GetCurrentHeight()};
133 }

References GetCurrentHeight(), and GetCurrentWidth().

◆ GetPrimaryPointerLocation()

PointerLocation flutter::FlutterWindow::GetPrimaryPointerLocation ( )
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 301 of file flutter_window.cc.

301  {
302  POINT point;
303  GetCursorPos(&point);
304  ScreenToClient(GetWindowHandle(), &point);
305  return {(size_t)point.x, (size_t)point.y};
306 }

References GetWindowHandle().

◆ GetScrollOffsetMultiplier()

float flutter::FlutterWindow::GetScrollOffsetMultiplier ( )
protectedvirtual

Definition at line 893 of file flutter_window.cc.

893  {
894  return scroll_offset_multiplier_;
895 }

Referenced by OnScroll().

◆ GetWindowHandle()

HWND flutter::FlutterWindow::GetWindowHandle ( )
overridevirtual

◆ HandleMessage()

LRESULT flutter::FlutterWindow::HandleMessage ( UINT const  message,
WPARAM const  wparam,
LPARAM const  lparam 
)
protectednoexcept

Definition at line 499 of file flutter_window.cc.

501  {
502  LPARAM result_lparam = lparam;
503  int xPos = 0, yPos = 0;
504  UINT width = 0, height = 0;
505  UINT button_pressed = 0;
506  FlutterPointerDeviceKind device_kind;
507 
508  switch (message) {
509  case kWmDpiChangedBeforeParent:
510  current_dpi_ = GetDpiForHWND(window_handle_);
511  OnDpiScale(current_dpi_);
512  return 0;
513  case WM_SIZE:
514  width = LOWORD(lparam);
515  height = HIWORD(lparam);
516 
517  current_width_ = width;
518  current_height_ = height;
519  HandleResize(width, height);
520 
521  OnWindowStateEvent(width == 0 && height == 0 ? WindowStateEvent::kHide
523  break;
524  case WM_PAINT:
525  OnPaint();
526  break;
527  case WM_TOUCH: {
528  UINT num_points = LOWORD(wparam);
529  touch_points_.resize(num_points);
530  auto touch_input_handle = reinterpret_cast<HTOUCHINPUT>(lparam);
531  if (GetTouchInputInfo(touch_input_handle, num_points,
532  touch_points_.data(), sizeof(TOUCHINPUT))) {
533  for (const auto& touch : touch_points_) {
534  // Generate a mapped ID for the Windows-provided touch ID
535  auto touch_id = touch_id_generator_.GetGeneratedId(touch.dwID);
536 
537  POINT pt = {TOUCH_COORD_TO_PIXEL(touch.x),
538  TOUCH_COORD_TO_PIXEL(touch.y)};
539  ScreenToClient(window_handle_, &pt);
540  auto x = static_cast<double>(pt.x);
541  auto y = static_cast<double>(pt.y);
542 
543  if (touch.dwFlags & TOUCHEVENTF_DOWN) {
544  OnPointerDown(x, y, kFlutterPointerDeviceKindTouch, touch_id,
545  WM_LBUTTONDOWN);
546  } else if (touch.dwFlags & TOUCHEVENTF_MOVE) {
547  OnPointerMove(x, y, kFlutterPointerDeviceKindTouch, touch_id, 0);
548  } else if (touch.dwFlags & TOUCHEVENTF_UP) {
549  OnPointerUp(x, y, kFlutterPointerDeviceKindTouch, touch_id,
550  WM_LBUTTONDOWN);
551  OnPointerLeave(x, y, kFlutterPointerDeviceKindTouch, touch_id);
552  touch_id_generator_.ReleaseNumber(touch.dwID);
553  }
554  }
555  CloseTouchInputHandle(touch_input_handle);
556  }
557  return 0;
558  }
559  case WM_MOUSEMOVE:
560  device_kind = GetFlutterPointerDeviceKind();
561  if (device_kind == kFlutterPointerDeviceKindMouse) {
562  TrackMouseLeaveEvent(window_handle_);
563 
564  xPos = GET_X_LPARAM(lparam);
565  yPos = GET_Y_LPARAM(lparam);
566  mouse_x_ = static_cast<double>(xPos);
567  mouse_y_ = static_cast<double>(yPos);
568 
569  int mods = 0;
570  if (wparam & MK_CONTROL) {
571  mods |= kControl;
572  }
573  if (wparam & MK_SHIFT) {
574  mods |= kShift;
575  }
576  OnPointerMove(mouse_x_, mouse_y_, device_kind, kDefaultPointerDeviceId,
577  mods);
578  }
579  break;
580  case WM_MOUSELEAVE:
581  device_kind = GetFlutterPointerDeviceKind();
582  if (device_kind == kFlutterPointerDeviceKindMouse) {
583  OnPointerLeave(mouse_x_, mouse_y_, device_kind,
584  kDefaultPointerDeviceId);
585  }
586 
587  // Once the tracked event is received, the TrackMouseEvent function
588  // resets. Set to false to make sure it's called once mouse movement is
589  // detected again.
590  tracking_mouse_leave_ = false;
591  break;
592  case WM_SETCURSOR: {
593  UINT hit_test_result = LOWORD(lparam);
594  if (hit_test_result == HTCLIENT) {
595  // Halt further processing to prevent DefWindowProc from setting the
596  // cursor back to the registered class cursor.
597  return TRUE;
598  }
599  break;
600  }
601  case WM_SETFOCUS:
603  ::CreateCaret(window_handle_, nullptr, 1, 1);
604  break;
605  case WM_KILLFOCUS:
607  ::DestroyCaret();
608  break;
609  case WM_LBUTTONDOWN:
610  case WM_RBUTTONDOWN:
611  case WM_MBUTTONDOWN:
612  case WM_XBUTTONDOWN:
613  device_kind = GetFlutterPointerDeviceKind();
614  if (device_kind != kFlutterPointerDeviceKindMouse) {
615  break;
616  }
617 
618  if (message == WM_LBUTTONDOWN) {
619  // Capture the pointer in case the user drags outside the client area.
620  // In this case, the "mouse leave" event is delayed until the user
621  // releases the button. It's only activated on left click given that
622  // it's more common for apps to handle dragging with only the left
623  // button.
624  SetCapture(window_handle_);
625  }
626  button_pressed = message;
627  if (message == WM_XBUTTONDOWN) {
628  button_pressed = GET_XBUTTON_WPARAM(wparam);
629  }
630  xPos = GET_X_LPARAM(lparam);
631  yPos = GET_Y_LPARAM(lparam);
632  OnPointerDown(static_cast<double>(xPos), static_cast<double>(yPos),
633  device_kind, kDefaultPointerDeviceId, button_pressed);
634  break;
635  case WM_LBUTTONUP:
636  case WM_RBUTTONUP:
637  case WM_MBUTTONUP:
638  case WM_XBUTTONUP:
639  device_kind = GetFlutterPointerDeviceKind();
640  if (device_kind != kFlutterPointerDeviceKindMouse) {
641  break;
642  }
643 
644  if (message == WM_LBUTTONUP) {
645  ReleaseCapture();
646  }
647  button_pressed = message;
648  if (message == WM_XBUTTONUP) {
649  button_pressed = GET_XBUTTON_WPARAM(wparam);
650  }
651  xPos = GET_X_LPARAM(lparam);
652  yPos = GET_Y_LPARAM(lparam);
653  OnPointerUp(static_cast<double>(xPos), static_cast<double>(yPos),
654  device_kind, kDefaultPointerDeviceId, button_pressed);
655  break;
656  case WM_MOUSEWHEEL:
657  OnScroll(0.0,
658  -(static_cast<short>(HIWORD(wparam)) /
659  static_cast<double>(WHEEL_DELTA)),
660  kFlutterPointerDeviceKindMouse, kDefaultPointerDeviceId);
661  break;
662  case WM_MOUSEHWHEEL:
663  OnScroll((static_cast<short>(HIWORD(wparam)) /
664  static_cast<double>(WHEEL_DELTA)),
665  0.0, kFlutterPointerDeviceKindMouse, kDefaultPointerDeviceId);
666  break;
667  case WM_GETOBJECT: {
668  LRESULT lresult = OnGetObject(message, wparam, lparam);
669  if (lresult) {
670  return lresult;
671  }
672  break;
673  }
674  case WM_TIMER:
675  if (wparam == kDirectManipulationTimer) {
676  direct_manipulation_owner_->Update();
677  return 0;
678  }
679  break;
680  case DM_POINTERHITTEST: {
682  UINT contact_id = GET_POINTERID_WPARAM(wparam);
683  POINTER_INPUT_TYPE pointer_type;
684  if (windows_proc_table_->GetPointerType(contact_id, &pointer_type) &&
685  pointer_type == PT_TOUCHPAD) {
686  direct_manipulation_owner_->SetContact(contact_id);
687  }
688  }
689  break;
690  }
691  case WM_INPUTLANGCHANGE:
692  // TODO(cbracken): pass this to TextInputManager to aid with
693  // language-specific issues.
694  break;
695  case WM_IME_SETCONTEXT:
696  OnImeSetContext(message, wparam, lparam);
697  // Strip the ISC_SHOWUICOMPOSITIONWINDOW bit from lparam before passing it
698  // to DefWindowProc() so that the composition window is hidden since
699  // Flutter renders the composing string itself.
700  result_lparam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
701  break;
702  case WM_IME_STARTCOMPOSITION:
703  OnImeStartComposition(message, wparam, lparam);
704  // Suppress further processing by DefWindowProc() so that the default
705  // system IME style isn't used, but rather the one set in the
706  // WM_IME_SETCONTEXT handler.
707  return TRUE;
708  case WM_IME_COMPOSITION:
709  OnImeComposition(message, wparam, lparam);
710  if (lparam & GCS_RESULTSTR || lparam & GCS_COMPSTR) {
711  // Suppress further processing by DefWindowProc() since otherwise it
712  // will emit the result string as WM_CHAR messages on commit. Instead,
713  // committing the composing text to the EditableText string is handled
714  // in TextInputModel::CommitComposing, triggered by
715  // OnImeEndComposition().
716  return TRUE;
717  }
718  break;
719  case WM_IME_ENDCOMPOSITION:
720  OnImeEndComposition(message, wparam, lparam);
721  return TRUE;
722  case WM_IME_REQUEST:
723  OnImeRequest(message, wparam, lparam);
724  break;
725  case WM_UNICHAR: {
726  // Tell third-pary app, we can support Unicode.
727  if (wparam == UNICODE_NOCHAR)
728  return TRUE;
729  // DefWindowProc will send WM_CHAR for this WM_UNICHAR.
730  break;
731  }
732  case WM_THEMECHANGED:
733  OnThemeChange();
734  break;
735  case WM_DEADCHAR:
736  case WM_SYSDEADCHAR:
737  case WM_CHAR:
738  case WM_SYSCHAR:
739  case WM_KEYDOWN:
740  case WM_SYSKEYDOWN:
741  case WM_KEYUP:
742  case WM_SYSKEYUP:
743  if (keyboard_manager_->HandleMessage(message, wparam, lparam)) {
744  return 0;
745  }
746  break;
747  }
748 
749  return Win32DefWindowProc(window_handle_, message, wparam, result_lparam);
750 }
virtual void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)
virtual void OnThemeChange()
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)
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)
std::unique_ptr< DirectManipulationOwner > direct_manipulation_owner_
virtual void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button)
virtual void OnImeSetContext(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual void OnWindowStateEvent(WindowStateEvent event)
virtual void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, int modifiers_state)
virtual void OnImeComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual void OnDpiScale(unsigned int dpi)
virtual LRESULT OnGetObject(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual void OnImeEndComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
uint32_t GetGeneratedId(uint32_t number)
Win32Message message
constexpr int kShift
constexpr int kControl

References flutter::GetDpiForHWND(), flutter::kControl, flutter::kFocus, flutter::kHide, flutter::kShift, flutter::kShow, flutter::kUnfocus, and message.

◆ InitializeChild()

void flutter::FlutterWindow::InitializeChild ( const char *  title,
unsigned int  width,
unsigned int  height 
)

Definition at line 395 of file flutter_window.cc.

397  {
398  Destroy();
399  std::wstring converted_title = NarrowToWide(title);
400 
401  WNDCLASS window_class = RegisterWindowClass(converted_title);
402 
403  auto* result = CreateWindowEx(
404  0, window_class.lpszClassName, converted_title.c_str(),
405  WS_CHILD | WS_VISIBLE, CW_DEFAULT, CW_DEFAULT, width, height,
406  HWND_MESSAGE, nullptr, window_class.hInstance, this);
407 
408  if (result == nullptr) {
409  auto error = GetLastError();
410  LPWSTR message = nullptr;
411  size_t size = FormatMessageW(
412  FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
413  FORMAT_MESSAGE_IGNORE_INSERTS,
414  NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
415  reinterpret_cast<LPWSTR>(&message), 0, NULL);
416  OutputDebugString(message);
417  LocalFree(message);
418  }
419  SetUserObjectInformationA(GetCurrentProcess(),
420  UOI_TIMERPROC_EXCEPTION_SUPPRESSION, FALSE, 1);
421  // SetTimer is not precise, if a 16 ms interval is requested, it will instead
422  // often fire in an interval of 32 ms. Providing a value of 14 will ensure it
423  // runs every 16 ms, which will allow for 60 Hz trackpad gesture events, which
424  // is the maximal frequency supported by SetTimer.
425  SetTimer(result, kDirectManipulationTimer, 14, nullptr);
426  direct_manipulation_owner_ = std::make_unique<DirectManipulationOwner>(this);
427  direct_manipulation_owner_->Init(width, height);
428 }
std::wstring NarrowToWide(const char *source)

References direct_manipulation_owner_, message, and NarrowToWide().

Referenced by FlutterWindow().

◆ NarrowToWide()

std::wstring flutter::FlutterWindow::NarrowToWide ( const char *  source)
protected

Definition at line 452 of file flutter_window.cc.

452  {
453  size_t length = strlen(source);
454  size_t outlen = 0;
455  std::wstring wideTitle(length, L'#');
456  mbstowcs_s(&outlen, &wideTitle[0], length + 1, source, length);
457  return wideTitle;
458 }

Referenced by InitializeChild().

◆ OnBitmapSurfaceCleared()

bool flutter::FlutterWindow::OnBitmapSurfaceCleared ( )
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 268 of file flutter_window.cc.

268  {
269  HDC dc = ::GetDC(GetWindowHandle());
270  bool result = ::PatBlt(dc, 0, 0, current_width_, current_height_, BLACKNESS);
271  ::ReleaseDC(GetWindowHandle(), dc);
272  return result;
273 }

References GetWindowHandle().

◆ OnBitmapSurfaceUpdated()

bool flutter::FlutterWindow::OnBitmapSurfaceUpdated ( const void *  allocation,
size_t  row_bytes,
size_t  height 
)
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 275 of file flutter_window.cc.

277  {
278  HDC dc = ::GetDC(GetWindowHandle());
279  BITMAPINFO bmi = {};
280  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
281  bmi.bmiHeader.biWidth = row_bytes / 4;
282  bmi.bmiHeader.biHeight = -height;
283  bmi.bmiHeader.biPlanes = 1;
284  bmi.bmiHeader.biBitCount = 32;
285  bmi.bmiHeader.biCompression = BI_RGB;
286  bmi.bmiHeader.biSizeImage = 0;
287  int ret = ::SetDIBitsToDevice(dc, 0, 0, row_bytes / 4, height, 0, 0, 0,
288  height, allocation, &bmi, DIB_RGB_COLORS);
289  ::ReleaseDC(GetWindowHandle(), dc);
290  return ret != 0;
291 }

References GetWindowHandle().

Referenced by flutter::testing::TEST_F().

◆ OnComposeBegin()

void flutter::FlutterWindow::OnComposeBegin ( )
virtual

Definition at line 222 of file flutter_window.cc.

222  {
223  binding_handler_delegate_->OnComposeBegin();
224 }

References flutter::WindowBindingHandlerDelegate::OnComposeBegin().

Referenced by OnImeStartComposition().

◆ OnComposeChange()

void flutter::FlutterWindow::OnComposeChange ( const std::u16string &  text,
int  cursor_pos 
)
virtual

Definition at line 234 of file flutter_window.cc.

235  {
236  binding_handler_delegate_->OnComposeChange(text, cursor_pos);
237 }
virtual void OnComposeChange(const std::u16string &text, int cursor_pos)=0
std::u16string text

References flutter::WindowBindingHandlerDelegate::OnComposeChange(), and text.

Referenced by OnImeComposition().

◆ OnComposeCommit()

void flutter::FlutterWindow::OnComposeCommit ( )
virtual

Definition at line 226 of file flutter_window.cc.

226  {
227  binding_handler_delegate_->OnComposeCommit();
228 }

References flutter::WindowBindingHandlerDelegate::OnComposeCommit().

Referenced by OnImeComposition().

◆ OnComposeEnd()

void flutter::FlutterWindow::OnComposeEnd ( )
virtual

Definition at line 230 of file flutter_window.cc.

230  {
231  binding_handler_delegate_->OnComposeEnd();
232 }

References flutter::WindowBindingHandlerDelegate::OnComposeEnd().

Referenced by OnImeEndComposition().

◆ OnCursorRectUpdated()

void flutter::FlutterWindow::OnCursorRectUpdated ( const Rect rect)
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 256 of file flutter_window.cc.

256  {
257  // Convert the rect from Flutter logical coordinates to device coordinates.
258  auto scale = GetDpiScale();
259  Point origin(rect.left() * scale, rect.top() * scale);
260  Size size(rect.width() * scale, rect.height() * scale);
261  UpdateCursorRect(Rect(origin, size));
262 }
virtual void UpdateCursorRect(const Rect &rect)
virtual float GetDpiScale() override

References GetDpiScale(), flutter::Rect::height(), flutter::Rect::left(), flutter::Rect::top(), UpdateCursorRect(), and flutter::Rect::width().

◆ OnDpiScale()

void flutter::FlutterWindow::OnDpiScale ( unsigned int  dpi)
virtual

Definition at line 149 of file flutter_window.cc.

149 {};

◆ OnGetObject()

LRESULT flutter::FlutterWindow::OnGetObject ( UINT const  message,
WPARAM const  wparam,
LPARAM const  lparam 
)
protectedvirtual

Definition at line 752 of file flutter_window.cc.

754  {
755  LRESULT reference_result = static_cast<LRESULT>(0L);
756 
757  // Only the lower 32 bits of lparam are valid when checking the object id
758  // because it sometimes gets sign-extended incorrectly (but not always).
759  DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(lparam));
760 
761  bool is_uia_request = static_cast<DWORD>(UiaRootObjectId) == obj_id;
762  bool is_msaa_request = static_cast<DWORD>(OBJID_CLIENT) == obj_id;
763 
764  if (is_uia_request || is_msaa_request) {
765  // On Windows, we don't get a notification that the screen reader has been
766  // enabled or disabled. There is an API to query for screen reader state,
767  // but that state isn't set by all screen readers, including by Narrator,
768  // the screen reader that ships with Windows:
769  // https://docs.microsoft.com/en-us/windows/win32/winauto/screen-reader-parameter
770  //
771  // Instead, we enable semantics in Flutter if Windows issues queries for
772  // Microsoft Active Accessibility (MSAA) COM objects.
774  }
775 
776  gfx::NativeViewAccessible root_view = GetNativeViewAccessible();
777  // TODO(schectman): UIA is currently disabled by default.
778  // https://github.com/flutter/flutter/issues/114547
779  if (root_view) {
780  CreateAxFragmentRoot();
781  if (is_uia_request) {
782 #ifdef FLUTTER_ENGINE_USE_UIA
783  // Retrieve UIA object for the root view.
784  Microsoft::WRL::ComPtr<IRawElementProviderSimple> root;
785  if (SUCCEEDED(
786  ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(
787  IID_PPV_ARGS(&root)))) {
788  // Return the UIA object via UiaReturnRawElementProvider(). See:
789  // https://docs.microsoft.com/en-us/windows/win32/winauto/wm-getobject
790  reference_result = UiaReturnRawElementProvider(window_handle_, wparam,
791  lparam, root.Get());
792  } else {
793  FML_LOG(ERROR) << "Failed to query AX fragment root.";
794  }
795 #endif // FLUTTER_ENGINE_USE_UIA
796  } else if (is_msaa_request) {
797  // Create the accessibility root if it does not already exist.
798  // Return the IAccessible for the root view.
799  Microsoft::WRL::ComPtr<IAccessible> root;
800  ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(
801  IID_PPV_ARGS(&root));
802  reference_result = LresultFromObject(IID_IAccessible, wparam, root.Get());
803  }
804  }
805  return reference_result;
806 }
virtual void OnUpdateSemanticsEnabled(bool enabled)
virtual gfx::NativeViewAccessible GetNativeViewAccessible()

References GetNativeViewAccessible(), and OnUpdateSemanticsEnabled().

◆ OnImeComposition()

void flutter::FlutterWindow::OnImeComposition ( UINT const  message,
WPARAM const  wparam,
LPARAM const  lparam 
)
protectedvirtual

Definition at line 823 of file flutter_window.cc.

825  {
826  // Update the IME window position.
827  text_input_manager_->UpdateImeWindow();
828 
829  if (lparam == 0) {
830  OnComposeChange(u"", 0);
831  OnComposeCommit();
832  }
833 
834  // Process GCS_RESULTSTR at fisrt, because Google Japanese Input and ATOK send
835  // both GCS_RESULTSTR and GCS_COMPSTR to commit composed text and send new
836  // composing text.
837  if (lparam & GCS_RESULTSTR) {
838  // Commit but don't end composing.
839  // Read the committed composing string.
840  long pos = text_input_manager_->GetComposingCursorPosition();
841  std::optional<std::u16string> text = text_input_manager_->GetResultString();
842  if (text) {
843  OnComposeChange(text.value(), pos);
844  OnComposeCommit();
845  }
846  }
847  if (lparam & GCS_COMPSTR) {
848  // Read the in-progress composing string.
849  long pos = text_input_manager_->GetComposingCursorPosition();
850  std::optional<std::u16string> text =
851  text_input_manager_->GetComposingString();
852  if (text) {
853  OnComposeChange(text.value(), pos);
854  }
855  }
856 }
virtual void OnComposeCommit()
virtual void OnComposeChange(const std::u16string &text, int cursor_pos)

References OnComposeChange(), OnComposeCommit(), and text.

◆ OnImeEndComposition()

void flutter::FlutterWindow::OnImeEndComposition ( UINT const  message,
WPARAM const  wparam,
LPARAM const  lparam 
)
protectedvirtual

Definition at line 858 of file flutter_window.cc.

860  {
861  text_input_manager_->DestroyImeWindow();
862  OnComposeEnd();
863 }
virtual void OnComposeEnd()

References OnComposeEnd().

◆ OnImeRequest()

void flutter::FlutterWindow::OnImeRequest ( UINT const  message,
WPARAM const  wparam,
LPARAM const  lparam 
)
protectedvirtual

Definition at line 865 of file flutter_window.cc.

867  {
868  // TODO(cbracken): Handle IMR_RECONVERTSTRING, IMR_DOCUMENTFEED,
869  // and IMR_QUERYCHARPOSITION messages.
870  // https://github.com/flutter/flutter/issues/74547
871 }

◆ OnImeSetContext()

void flutter::FlutterWindow::OnImeSetContext ( UINT const  message,
WPARAM const  wparam,
LPARAM const  lparam 
)
protectedvirtual

Definition at line 808 of file flutter_window.cc.

810  {
811  if (wparam != 0) {
812  text_input_manager_->CreateImeWindow();
813  }
814 }

◆ OnImeStartComposition()

void flutter::FlutterWindow::OnImeStartComposition ( UINT const  message,
WPARAM const  wparam,
LPARAM const  lparam 
)
protectedvirtual

Definition at line 816 of file flutter_window.cc.

818  {
819  text_input_manager_->CreateImeWindow();
820  OnComposeBegin();
821 }
virtual void OnComposeBegin()

References OnComposeBegin().

◆ OnKey()

void flutter::FlutterWindow::OnKey ( int  key,
int  scancode,
int  action,
char32_t  character,
bool  extended,
bool  was_down,
KeyEventCallback  callback 
)
overridevirtual

Implements flutter::KeyboardManager::WindowDelegate.

Definition at line 211 of file flutter_window.cc.

217  {
218  binding_handler_delegate_->OnKey(key, scancode, action, character, extended,
219  was_down, std::move(callback));
220 }
virtual void OnKey(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback)=0
FlutterDesktopBinaryReply callback

References action, callback, character, extended, key, flutter::WindowBindingHandlerDelegate::OnKey(), scancode, and was_down.

◆ OnPaint()

void flutter::FlutterWindow::OnPaint ( )
virtual

Definition at line 159 of file flutter_window.cc.

159  {
160  if (binding_handler_delegate_ != nullptr) {
161  binding_handler_delegate_->OnWindowRepaint();
162  }
163 }

References flutter::WindowBindingHandlerDelegate::OnWindowRepaint().

◆ OnPointerDown()

void flutter::FlutterWindow::OnPointerDown ( double  x,
double  y,
FlutterPointerDeviceKind  device_kind,
int32_t  device_id,
UINT  button 
)
virtual

Definition at line 174 of file flutter_window.cc.

178  {
179  uint64_t flutter_button = ConvertWinButtonToFlutterButton(button);
180  if (flutter_button != 0) {
181  binding_handler_delegate_->OnPointerDown(
182  x, y, device_kind, device_id,
183  static_cast<FlutterPointerMouseButtons>(flutter_button));
184  }
185 }
virtual void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button)=0

References flutter::WindowBindingHandlerDelegate::OnPointerDown().

Referenced by flutter::testing::TEST_F().

◆ OnPointerLeave()

void flutter::FlutterWindow::OnPointerLeave ( double  x,
double  y,
FlutterPointerDeviceKind  device_kind,
int32_t  device_id 
)
virtual

Definition at line 200 of file flutter_window.cc.

203  {
204  binding_handler_delegate_->OnPointerLeave(x, y, device_kind, device_id);
205 }
virtual void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)=0

References flutter::WindowBindingHandlerDelegate::OnPointerLeave().

Referenced by flutter::testing::TEST_F().

◆ OnPointerMove()

void flutter::FlutterWindow::OnPointerMove ( double  x,
double  y,
FlutterPointerDeviceKind  device_kind,
int32_t  device_id,
int  modifiers_state 
)
virtual

Definition at line 165 of file flutter_window.cc.

169  {
170  binding_handler_delegate_->OnPointerMove(x, y, device_kind, device_id,
171  modifiers_state);
172 }
virtual void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, int modifiers_state)=0

References flutter::WindowBindingHandlerDelegate::OnPointerMove().

Referenced by flutter::testing::TEST_F().

◆ OnPointerUp()

void flutter::FlutterWindow::OnPointerUp ( double  x,
double  y,
FlutterPointerDeviceKind  device_kind,
int32_t  device_id,
UINT  button 
)
virtual

Definition at line 187 of file flutter_window.cc.

191  {
192  uint64_t flutter_button = ConvertWinButtonToFlutterButton(button);
193  if (flutter_button != 0) {
194  binding_handler_delegate_->OnPointerUp(
195  x, y, device_kind, device_id,
196  static_cast<FlutterPointerMouseButtons>(flutter_button));
197  }
198 }
virtual void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button)=0

References flutter::WindowBindingHandlerDelegate::OnPointerUp().

Referenced by flutter::testing::TEST_F().

◆ OnResetImeComposing()

void flutter::FlutterWindow::OnResetImeComposing ( )
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 264 of file flutter_window.cc.

264  {
266 }
virtual void AbortImeComposing()

References AbortImeComposing().

◆ OnResize()

void flutter::FlutterWindow::OnResize ( unsigned int  width,
unsigned int  height 
)
virtual

Definition at line 153 of file flutter_window.cc.

153  {
154  if (binding_handler_delegate_ != nullptr) {
155  binding_handler_delegate_->OnWindowSizeChanged(width, height);
156  }
157 }
virtual bool OnWindowSizeChanged(size_t width, size_t height)=0

References flutter::WindowBindingHandlerDelegate::OnWindowSizeChanged().

◆ OnScroll()

void flutter::FlutterWindow::OnScroll ( double  delta_x,
double  delta_y,
FlutterPointerDeviceKind  device_kind,
int32_t  device_id 
)
virtual

Definition at line 243 of file flutter_window.cc.

246  {
247  POINT point;
248  GetCursorPos(&point);
249 
250  ScreenToClient(GetWindowHandle(), &point);
251  binding_handler_delegate_->OnScroll(point.x, point.y, delta_x, delta_y,
252  GetScrollOffsetMultiplier(), device_kind,
253  device_id);
254 }
virtual float GetScrollOffsetMultiplier()
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

References GetScrollOffsetMultiplier(), GetWindowHandle(), and flutter::WindowBindingHandlerDelegate::OnScroll().

◆ OnText()

void flutter::FlutterWindow::OnText ( const std::u16string &  text)
overridevirtual

Implements flutter::KeyboardManager::WindowDelegate.

Definition at line 207 of file flutter_window.cc.

207  {
208  binding_handler_delegate_->OnText(text);
209 }
virtual void OnText(const std::u16string &)=0

References flutter::WindowBindingHandlerDelegate::OnText(), and text.

◆ OnThemeChange()

void flutter::FlutterWindow::OnThemeChange ( )
virtual

Definition at line 308 of file flutter_window.cc.

308  {
309  binding_handler_delegate_->OnHighContrastChanged();
310 }

References flutter::WindowBindingHandlerDelegate::OnHighContrastChanged().

◆ OnUpdateSemanticsEnabled()

void flutter::FlutterWindow::OnUpdateSemanticsEnabled ( bool  enabled)
virtual

Definition at line 239 of file flutter_window.cc.

239  {
240  binding_handler_delegate_->OnUpdateSemanticsEnabled(enabled);
241 }
virtual void OnUpdateSemanticsEnabled(bool enabled)=0

References flutter::WindowBindingHandlerDelegate::OnUpdateSemanticsEnabled().

Referenced by OnGetObject().

◆ OnWindowStateEvent()

void flutter::FlutterWindow::OnWindowStateEvent ( WindowStateEvent  event)
virtual

Definition at line 326 of file flutter_window.cc.

326  {
327  switch (event) {
329  restored_ = true;
330  break;
332  restored_ = false;
333  focused_ = false;
334  break;
336  focused_ = true;
337  if (binding_handler_delegate_) {
338  binding_handler_delegate_->OnFocus(
339  FlutterViewFocusState::kFocused,
340  FlutterViewFocusDirection::kUndefined);
341  }
342  break;
344  focused_ = false;
345  if (binding_handler_delegate_) {
346  binding_handler_delegate_->OnFocus(
347  FlutterViewFocusState::kUnfocused,
348  FlutterViewFocusDirection::kUndefined);
349  }
350  break;
351  }
352  HWND hwnd = GetWindowHandle();
353  if (hwnd && binding_handler_delegate_) {
354  binding_handler_delegate_->OnWindowStateEvent(hwnd, event);
355  }
356 }
virtual void OnWindowStateEvent(HWND hwnd, WindowStateEvent event)=0
virtual void OnFocus(FlutterViewFocusState focus_state, FlutterViewFocusDirection direction)=0

References GetWindowHandle(), flutter::kFocus, flutter::kHide, flutter::kShow, flutter::kUnfocus, flutter::WindowBindingHandlerDelegate::OnFocus(), and flutter::WindowBindingHandlerDelegate::OnWindowStateEvent().

Referenced by SetView().

◆ SetView()

void flutter::FlutterWindow::SetView ( WindowBindingHandlerDelegate view)
overridevirtual

Implements flutter::WindowBindingHandler.

Definition at line 114 of file flutter_window.cc.

114  {
115  binding_handler_delegate_ = window;
117  direct_manipulation_owner_->SetBindingHandlerDelegate(window);
118  }
119  if (restored_ && window) {
121  }
122  if (focused_ && window) {
124  }
125 }

References direct_manipulation_owner_, flutter::kFocus, flutter::kShow, and OnWindowStateEvent().

Referenced by flutter::testing::TEST_F().

◆ UpdateCursorRect()

void flutter::FlutterWindow::UpdateCursorRect ( const Rect rect)
protectedvirtual

Definition at line 877 of file flutter_window.cc.

877  {
878  text_input_manager_->UpdateCaretRect(rect);
879 }

Referenced by OnCursorRectUpdated().

◆ Win32DefWindowProc()

LRESULT flutter::FlutterWindow::Win32DefWindowProc ( HWND  hWnd,
UINT  Msg,
WPARAM  wParam,
LPARAM  lParam 
)
protectedvirtual

Definition at line 897 of file flutter_window.cc.

900  {
901  return ::DefWindowProc(hWnd, Msg, wParam, lParam);
902 }

◆ Win32DispatchMessage()

UINT flutter::FlutterWindow::Win32DispatchMessage ( UINT  Msg,
WPARAM  wParam,
LPARAM  lParam 
)
overridevirtual

Implements flutter::KeyboardManager::WindowDelegate.

Definition at line 446 of file flutter_window.cc.

448  {
449  return ::SendMessage(window_handle_, Msg, wParam, lParam);
450 }

◆ Win32MapVkToChar()

uint32_t flutter::FlutterWindow::Win32MapVkToChar ( uint32_t  virtual_key)
overridevirtual

Implements flutter::KeyboardManager::WindowDelegate.

Definition at line 442 of file flutter_window.cc.

442  {
443  return ::MapVirtualKey(virtual_key, MAPVK_VK_TO_CHAR);
444 }

◆ Win32PeekMessage()

BOOL flutter::FlutterWindow::Win32PeekMessage ( LPMSG  lpMsg,
UINT  wMsgFilterMin,
UINT  wMsgFilterMax,
UINT  wRemoveMsg 
)
overridevirtual

Implements flutter::KeyboardManager::WindowDelegate.

Definition at line 434 of file flutter_window.cc.

437  {
438  return ::PeekMessage(lpMsg, window_handle_, wMsgFilterMin, wMsgFilterMax,
439  wRemoveMsg);
440 }

Friends And Related Function Documentation

◆ WindowAXFragmentRootDelegate

friend class WindowAXFragmentRootDelegate
friend

Definition at line 376 of file flutter_window.h.

Member Data Documentation

◆ alert_delegate_

std::unique_ptr<AlertPlatformNodeDelegate> flutter::FlutterWindow::alert_delegate_
protected

Definition at line 268 of file flutter_window.h.

Referenced by GetAlertDelegate().

◆ alert_node_

std::unique_ptr<ui::AXPlatformNodeWin> flutter::FlutterWindow::alert_node_
protected

Definition at line 271 of file flutter_window.h.

Referenced by GetAlert().

◆ direct_manipulation_owner_

std::unique_ptr<DirectManipulationOwner> flutter::FlutterWindow::direct_manipulation_owner_
protected

Definition at line 275 of file flutter_window.h.

Referenced by InitializeChild(), and SetView().


The documentation for this class was generated from the following files: