Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 035c9db

Browse files
Track "mouse leave" event (#12363)
1 parent 5b8d7df commit 035c9db

File tree

4 files changed

+51
-2
lines changed

4 files changed

+51
-2
lines changed

shell/platform/windows/win32_flutter_window.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ void Win32FlutterWindow::OnPointerUp(double x, double y) {
125125
}
126126
}
127127

128+
void Win32FlutterWindow::OnPointerLeave() {
129+
if (process_events_) {
130+
SendPointerLeave();
131+
}
132+
}
133+
128134
void Win32FlutterWindow::OnChar(char32_t code_point) {
129135
if (process_events_) {
130136
SendChar(code_point);
@@ -214,6 +220,12 @@ void Win32FlutterWindow::SendPointerUp(double x, double y) {
214220
SendPointerEventWithData(event);
215221
}
216222

223+
void Win32FlutterWindow::SendPointerLeave() {
224+
FlutterPointerEvent event = {};
225+
event.phase = FlutterPointerPhase::kRemove;
226+
SendPointerEventWithData(event);
227+
}
228+
217229
void Win32FlutterWindow::SendChar(char32_t code_point) {
218230
for (const auto& handler : keyboard_hook_handlers_) {
219231
handler->CharHook(this, code_point);

shell/platform/windows/win32_flutter_window.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ class Win32FlutterWindow : public Win32Window {
5353
// |Win32Window|
5454
void OnPointerUp(double x, double y) override;
5555

56+
// |Win32Window|
57+
void OnPointerLeave() override;
58+
5659
// |Win32Window|
5760
void OnChar(char32_t code_point) override;
5861

@@ -105,6 +108,13 @@ class Win32FlutterWindow : public Win32Window {
105108
// Reports mouse release to Flutter engine.
106109
void SendPointerUp(double x, double y);
107110

111+
// Reports mouse left the window client area.
112+
//
113+
// Win32 api doesn't have "mouse enter" event. Therefore, there is no
114+
// SendPointerEnter method. A mouse enter event is tracked then the "move"
115+
// event is called.
116+
void SendPointerLeave();
117+
108118
// Reports a keyboard character to Flutter engine.
109119
void SendChar(char32_t code_point);
110120

shell/platform/windows/win32_window.cc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window,
9898
return DefWindowProc(window, message, wparam, lparam);
9999
}
100100

101+
void Win32Window::TrackMouseLeaveEvent(HWND hwnd) {
102+
if (!tracking_mouse_leave_) {
103+
TRACKMOUSEEVENT tme;
104+
tme.cbSize = sizeof(tme);
105+
tme.hwndTrack = hwnd;
106+
tme.dwFlags = TME_LEAVE;
107+
TrackMouseEvent(&tme);
108+
tracking_mouse_leave_ = true;
109+
}
110+
}
111+
101112
LRESULT
102113
Win32Window::MessageHandler(HWND hwnd,
103114
UINT const message,
@@ -120,7 +131,6 @@ Win32Window::MessageHandler(HWND hwnd,
120131
window->OnClose();
121132
return 0;
122133
break;
123-
124134
case WM_SIZE:
125135
width = LOWORD(lparam);
126136
height = HIWORD(lparam);
@@ -133,12 +143,20 @@ Win32Window::MessageHandler(HWND hwnd,
133143
window->OnFontChange();
134144
break;
135145
case WM_MOUSEMOVE:
146+
window->TrackMouseLeaveEvent(hwnd);
147+
136148
xPos = GET_X_LPARAM(lparam);
137149
yPos = GET_Y_LPARAM(lparam);
138-
139150
window->OnPointerMove(static_cast<double>(xPos),
140151
static_cast<double>(yPos));
141152
break;
153+
case WM_MOUSELEAVE:;
154+
window->OnPointerLeave();
155+
// Once the tracked event is received, the TrackMouseEvent function
156+
// resets. Set to false to make sure it's called once mouse movement is
157+
// detected again.
158+
tracking_mouse_leave_ = false;
159+
break;
142160
case WM_LBUTTONDOWN:
143161
xPos = GET_X_LPARAM(lparam);
144162
yPos = GET_Y_LPARAM(lparam);

shell/platform/windows/win32_window.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ class Win32Window {
8888
// down to up
8989
virtual void OnPointerUp(double x, double y) = 0;
9090

91+
// Called when the mouse leaves the window.
92+
virtual void OnPointerLeave() = 0;
93+
9194
// Called when character input occurs.
9295
virtual void OnChar(char32_t code_point) = 0;
9396

@@ -110,6 +113,9 @@ class Win32Window {
110113
UINT GetCurrentHeight();
111114

112115
private:
116+
// Activates tracking for a "mouse leave" event.
117+
void TrackMouseLeaveEvent(HWND hwnd);
118+
113119
// Stores new width and height and calls |OnResize| to notify inheritors
114120
void HandleResize(UINT width, UINT height);
115121

@@ -133,6 +139,9 @@ class Win32Window {
133139
// aspects of win32 High DPI handling across different OS versions.
134140
std::unique_ptr<Win32DpiHelper> dpi_helper_ =
135141
std::make_unique<Win32DpiHelper>();
142+
143+
// Set to true to be notified when the mouse leaves the window.
144+
bool tracking_mouse_leave_ = false;
136145
};
137146

138147
} // namespace flutter

0 commit comments

Comments
 (0)