diff --git a/shell/platform/windows/win32_flutter_window.cc b/shell/platform/windows/win32_flutter_window.cc index d4e08e390f22e87621d60aba6973b45a1238cff3..46125c046c6559c952dedc43ebbfb6764acb3acc 100644 --- a/shell/platform/windows/win32_flutter_window.cc +++ b/shell/platform/windows/win32_flutter_window.cc @@ -125,6 +125,12 @@ void Win32FlutterWindow::OnPointerUp(double x, double y) { } } +void Win32FlutterWindow::OnPointerLeave() { + if (process_events_) { + SendPointerLeave(); + } +} + void Win32FlutterWindow::OnChar(char32_t code_point) { if (process_events_) { SendChar(code_point); @@ -214,6 +220,12 @@ void Win32FlutterWindow::SendPointerUp(double x, double y) { SendPointerEventWithData(event); } +void Win32FlutterWindow::SendPointerLeave() { + FlutterPointerEvent event = {}; + event.phase = FlutterPointerPhase::kRemove; + SendPointerEventWithData(event); +} + void Win32FlutterWindow::SendChar(char32_t code_point) { for (const auto& handler : keyboard_hook_handlers_) { handler->CharHook(this, code_point); diff --git a/shell/platform/windows/win32_flutter_window.h b/shell/platform/windows/win32_flutter_window.h index 138fef8f49279579234a463d9fba1a358c818518..72d5dc65f28eb42617c7e93cd7517b4a417af802 100644 --- a/shell/platform/windows/win32_flutter_window.h +++ b/shell/platform/windows/win32_flutter_window.h @@ -53,6 +53,9 @@ class Win32FlutterWindow : public Win32Window { // |Win32Window| void OnPointerUp(double x, double y) override; + // |Win32Window| + void OnPointerLeave() override; + // |Win32Window| void OnChar(char32_t code_point) override; @@ -105,6 +108,13 @@ class Win32FlutterWindow : public Win32Window { // Reports mouse release to Flutter engine. void SendPointerUp(double x, double y); + // Reports mouse left the window client area. + // + // Win32 api doesn't have "mouse enter" event. Therefore, there is no + // SendPointerEnter method. A mouse enter event is tracked then the "move" + // event is called. + void SendPointerLeave(); + // Reports a keyboard character to Flutter engine. void SendChar(char32_t code_point); diff --git a/shell/platform/windows/win32_window.cc b/shell/platform/windows/win32_window.cc index b2e313ef98a122b2cefdb8b8ae8fdeab5ae396ec..c6432c85eb1a18c84ceededa4e5689aaf7716b91 100644 --- a/shell/platform/windows/win32_window.cc +++ b/shell/platform/windows/win32_window.cc @@ -98,6 +98,17 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, return DefWindowProc(window, message, wparam, lparam); } +void Win32Window::TrackMouseLeaveEvent(HWND hwnd) { + if (!tracking_mouse_leave_) { + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(tme); + tme.hwndTrack = hwnd; + tme.dwFlags = TME_LEAVE; + TrackMouseEvent(&tme); + tracking_mouse_leave_ = true; + } +} + LRESULT Win32Window::MessageHandler(HWND hwnd, UINT const message, @@ -120,7 +131,6 @@ Win32Window::MessageHandler(HWND hwnd, window->OnClose(); return 0; break; - case WM_SIZE: width = LOWORD(lparam); height = HIWORD(lparam); @@ -133,12 +143,20 @@ Win32Window::MessageHandler(HWND hwnd, window->OnFontChange(); break; case WM_MOUSEMOVE: + window->TrackMouseLeaveEvent(hwnd); + xPos = GET_X_LPARAM(lparam); yPos = GET_Y_LPARAM(lparam); - window->OnPointerMove(static_cast(xPos), static_cast(yPos)); break; + case WM_MOUSELEAVE:; + window->OnPointerLeave(); + // Once the tracked event is received, the TrackMouseEvent function + // resets. Set to false to make sure it's called once mouse movement is + // detected again. + tracking_mouse_leave_ = false; + break; case WM_LBUTTONDOWN: xPos = GET_X_LPARAM(lparam); yPos = GET_Y_LPARAM(lparam); diff --git a/shell/platform/windows/win32_window.h b/shell/platform/windows/win32_window.h index 0b5f4eedd8a3cdc60d24e1c7074c15f2801db459..dc209ca9e2e3bf2279e8790336e6f05750c36cfd 100644 --- a/shell/platform/windows/win32_window.h +++ b/shell/platform/windows/win32_window.h @@ -88,6 +88,9 @@ class Win32Window { // down to up virtual void OnPointerUp(double x, double y) = 0; + // Called when the mouse leaves the window. + virtual void OnPointerLeave() = 0; + // Called when character input occurs. virtual void OnChar(char32_t code_point) = 0; @@ -110,6 +113,9 @@ class Win32Window { UINT GetCurrentHeight(); private: + // Activates tracking for a "mouse leave" event. + void TrackMouseLeaveEvent(HWND hwnd); + // Stores new width and height and calls |OnResize| to notify inheritors void HandleResize(UINT width, UINT height); @@ -133,6 +139,9 @@ class Win32Window { // aspects of win32 High DPI handling across different OS versions. std::unique_ptr dpi_helper_ = std::make_unique(); + + // Set to true to be notified when the mouse leaves the window. + bool tracking_mouse_leave_ = false; }; } // namespace flutter