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