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