Win32: Send mouse leave event with last position (flutter/engine#32147)

* Win32: Send mouse leave event with last position

* reformat code
This commit is contained in:
moko256 2022-05-19 22:26:54 +09:00 committed by GitHub
parent 531aa3a104
commit ca8a710c6c
10 changed files with 70 additions and 26 deletions

View File

@ -171,9 +171,11 @@ void FlutterWindowWin32::OnPointerUp(double x,
}
}
void FlutterWindowWin32::OnPointerLeave(FlutterPointerDeviceKind device_kind,
void FlutterWindowWin32::OnPointerLeave(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id) {
binding_handler_delegate_->OnPointerLeave(device_kind, device_id);
binding_handler_delegate_->OnPointerLeave(x, y, device_kind, device_id);
}
void FlutterWindowWin32::OnSetCursor() {

View File

@ -57,7 +57,9 @@ class FlutterWindowWin32 : public WindowWin32, public WindowBindingHandler {
UINT button) override;
// |WindowWin32|
void OnPointerLeave(FlutterPointerDeviceKind device_kind,
void OnPointerLeave(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id) override;
// |WindowWin32|

View File

@ -116,7 +116,8 @@ class MockFlutterWindowWin32 : public FlutterWindowWin32 {
void(double, double, FlutterPointerDeviceKind, int32_t, UINT));
MOCK_METHOD5(OnPointerUp,
void(double, double, FlutterPointerDeviceKind, int32_t, UINT));
MOCK_METHOD2(OnPointerLeave, void(FlutterPointerDeviceKind, int32_t));
MOCK_METHOD4(OnPointerLeave,
void(double, double, FlutterPointerDeviceKind, int32_t));
MOCK_METHOD0(OnSetCursor, void());
MOCK_METHOD4(OnScroll,
void(double, double, FlutterPointerDeviceKind, int32_t));
@ -163,7 +164,8 @@ class MockWindowBindingHandlerDelegate : public WindowBindingHandlerDelegate {
FlutterPointerDeviceKind,
int32_t,
FlutterPointerMouseButtons));
MOCK_METHOD2(OnPointerLeave, void(FlutterPointerDeviceKind, int32_t));
MOCK_METHOD4(OnPointerLeave,
void(double, double, FlutterPointerDeviceKind, int32_t));
MOCK_METHOD1(OnText, void(const std::u16string&));
MOCK_METHOD7(OnKey,
void(int, int, int, char32_t, bool, bool, KeyEventCallback));
@ -328,14 +330,17 @@ TEST(FlutterWindowWin32Test, OnPointerStarSendsDeviceType) {
.Times(1);
// Leave
EXPECT_CALL(delegate, OnPointerLeave(kFlutterPointerDeviceKindMouse,
kDefaultPointerDeviceId))
EXPECT_CALL(delegate,
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
kDefaultPointerDeviceId))
.Times(1);
EXPECT_CALL(delegate, OnPointerLeave(kFlutterPointerDeviceKindTouch,
kDefaultPointerDeviceId))
EXPECT_CALL(delegate,
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
kDefaultPointerDeviceId))
.Times(1);
EXPECT_CALL(delegate, OnPointerLeave(kFlutterPointerDeviceKindStylus,
kDefaultPointerDeviceId))
EXPECT_CALL(delegate,
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
kDefaultPointerDeviceId))
.Times(1);
win32window.OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
@ -344,7 +349,7 @@ TEST(FlutterWindowWin32Test, OnPointerStarSendsDeviceType) {
kDefaultPointerDeviceId, WM_LBUTTONDOWN);
win32window.OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
kDefaultPointerDeviceId, WM_LBUTTONDOWN);
win32window.OnPointerLeave(kFlutterPointerDeviceKindMouse,
win32window.OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
kDefaultPointerDeviceId);
// Touch
@ -354,7 +359,7 @@ TEST(FlutterWindowWin32Test, OnPointerStarSendsDeviceType) {
kDefaultPointerDeviceId, WM_LBUTTONDOWN);
win32window.OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
kDefaultPointerDeviceId, WM_LBUTTONDOWN);
win32window.OnPointerLeave(kFlutterPointerDeviceKindTouch,
win32window.OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
kDefaultPointerDeviceId);
// Pen
@ -364,7 +369,7 @@ TEST(FlutterWindowWin32Test, OnPointerStarSendsDeviceType) {
kDefaultPointerDeviceId, WM_LBUTTONDOWN);
win32window.OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
kDefaultPointerDeviceId, WM_LBUTTONDOWN);
win32window.OnPointerLeave(kFlutterPointerDeviceKindStylus,
win32window.OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
kDefaultPointerDeviceId);
}

View File

@ -196,9 +196,11 @@ void FlutterWindowsView::OnPointerUp(
}
}
void FlutterWindowsView::OnPointerLeave(FlutterPointerDeviceKind device_kind,
void FlutterWindowsView::OnPointerLeave(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id) {
SendPointerLeave(GetOrCreatePointerState(device_kind, device_id));
SendPointerLeave(x, y, GetOrCreatePointerState(device_kind, device_id));
}
void FlutterWindowsView::OnText(const std::u16string& text) {
@ -369,8 +371,12 @@ void FlutterWindowsView::SendPointerUp(double x,
}
}
void FlutterWindowsView::SendPointerLeave(PointerState* state) {
void FlutterWindowsView::SendPointerLeave(double x,
double y,
PointerState* state) {
FlutterPointerEvent event = {};
event.x = x;
event.y = y;
event.phase = FlutterPointerPhase::kRemove;
SendPointerEventWithData(event, state);
}

View File

@ -120,7 +120,9 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate,
FlutterPointerMouseButtons button) override;
// |WindowBindingHandlerDelegate|
void OnPointerLeave(FlutterPointerDeviceKind device_kind,
void OnPointerLeave(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id = 0) override;
// |WindowBindingHandlerDelegate|
@ -243,7 +245,7 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate,
// 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(PointerState* state);
void SendPointerLeave(double x, double y, PointerState* state);
// Reports a keyboard character to Flutter engine.
void SendText(const std::u16string&);

View File

@ -43,7 +43,8 @@ class MockWin32Window : public WindowWin32 {
void(double, double, FlutterPointerDeviceKind, int32_t, UINT));
MOCK_METHOD5(OnPointerUp,
void(double, double, FlutterPointerDeviceKind, int32_t, UINT));
MOCK_METHOD2(OnPointerLeave, void(FlutterPointerDeviceKind, int32_t));
MOCK_METHOD4(OnPointerLeave,
void(double, double, FlutterPointerDeviceKind, int32_t));
MOCK_METHOD0(OnSetCursor, void());
MOCK_METHOD1(OnText, void(const std::u16string&));
MOCK_METHOD7(OnKey,

View File

@ -47,7 +47,9 @@ class WindowBindingHandlerDelegate {
// Notifies delegate that backing window mouse pointer has left the window.
// Typically called by currently configured WindowBindingHandler
virtual void OnPointerLeave(FlutterPointerDeviceKind device_kind,
virtual void OnPointerLeave(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id) = 0;
// Notifies delegate that backing window has received text.

View File

@ -332,7 +332,7 @@ WindowWin32::HandleMessage(UINT const message,
} else if (touch.dwFlags & TOUCHEVENTF_UP) {
OnPointerUp(x, y, kFlutterPointerDeviceKindTouch, touch_id,
WM_LBUTTONDOWN);
OnPointerLeave(kFlutterPointerDeviceKindTouch, touch_id);
OnPointerLeave(x, y, kFlutterPointerDeviceKindTouch, touch_id);
touch_id_generator_.ReleaseNumber(touch.dwID);
}
}
@ -347,15 +347,17 @@ WindowWin32::HandleMessage(UINT const message,
xPos = GET_X_LPARAM(lparam);
yPos = GET_Y_LPARAM(lparam);
mouse_x_ = static_cast<double>(xPos);
mouse_y_ = static_cast<double>(yPos);
OnPointerMove(static_cast<double>(xPos), static_cast<double>(yPos),
device_kind, kDefaultPointerDeviceId);
OnPointerMove(mouse_x_, mouse_y_, device_kind, kDefaultPointerDeviceId);
}
break;
case WM_MOUSELEAVE:
device_kind = GetFlutterPointerDeviceKind();
if (device_kind == kFlutterPointerDeviceKindMouse) {
OnPointerLeave(device_kind, kDefaultPointerDeviceId);
OnPointerLeave(mouse_x_, mouse_y_, device_kind,
kDefaultPointerDeviceId);
}
// Once the tracked event is received, the TrackMouseEvent function

View File

@ -118,7 +118,9 @@ class WindowWin32 : public KeyboardManagerWin32::WindowDelegate {
UINT button) = 0;
// Called when the mouse leaves the window.
virtual void OnPointerLeave(FlutterPointerDeviceKind device_kind,
virtual void OnPointerLeave(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id) = 0;
// Called when the cursor should be set for the client area.
@ -243,6 +245,10 @@ class WindowWin32 : public KeyboardManagerWin32::WindowDelegate {
// message.
int keycode_for_char_message_ = 0;
// Keeps track of the last mouse coordinates by a WM_MOUSEMOVE message.
double mouse_x_ = 0;
double mouse_y_ = 0;
// Manages IME state.
std::unique_ptr<TextInputManagerWin32> text_input_manager_;

View File

@ -143,6 +143,22 @@ TEST(MockWin32Window, HorizontalScroll) {
window.InjectWindowMessage(WM_MOUSEHWHEEL, MAKEWPARAM(0, scroll_amount), 0);
}
TEST(MockWin32Window, MouseLeave) {
MockWin32Window window;
const double mouse_x = 10.0;
const double mouse_y = 20.0;
EXPECT_CALL(window, OnPointerMove(mouse_x, mouse_y,
kFlutterPointerDeviceKindMouse, 0))
.Times(1);
EXPECT_CALL(window, OnPointerLeave(mouse_x, mouse_y,
kFlutterPointerDeviceKindMouse, 0))
.Times(1);
window.InjectWindowMessage(WM_MOUSEMOVE, 0, MAKELPARAM(mouse_x, mouse_y));
window.InjectWindowMessage(WM_MOUSELEAVE, 0, 0);
}
TEST(MockWin32Window, KeyDown) {
MockWin32Window window;
EXPECT_CALL(window, OnKey(_, _, _, _, _, _, _)).Times(1);