Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track "mouse leave" event #12363

Merged
merged 6 commits into from
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions shell/platform/windows/win32_flutter_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ void Win32FlutterWindow::OnPointerUp(double x, double y) {
}
}

void Win32FlutterWindow::OnPointerLeave() {
if (process_events_) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW (not something to change in this PR), it's likely that process_events_ and the plugin handler hooks that toggle it are entirely cruft inherited from what the GLFW implementation did to interoperate reasonably with GTK dialogs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly. There was a contract that somewhere that required events to be disabled / enabled.

SendPointerLeave();
}
}

void Win32FlutterWindow::OnChar(char32_t code_point) {
if (process_events_) {
SendChar(code_point);
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions shell/platform/windows/win32_flutter_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the asymmetry is non-obvious (or at least was to me coming from a non-Windows background—macOS and GLFW both have enter and exit, apparently unlike Win32), maybe add a comment explicitly saying that there is no SendPointerEnter because it's automatically inferred from any other pointer event being sent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

//
// 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);

Expand Down
22 changes: 20 additions & 2 deletions shell/platform/windows/win32_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -120,7 +131,6 @@ Win32Window::MessageHandler(HWND hwnd,
window->OnClose();
return 0;
break;

case WM_SIZE:
width = LOWORD(lparam);
height = HIWORD(lparam);
Expand All @@ -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<double>(xPos),
static_cast<double>(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);
Expand Down
9 changes: 9 additions & 0 deletions shell/platform/windows/win32_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);

Expand All @@ -133,6 +139,9 @@ class Win32Window {
// aspects of win32 High DPI handling across different OS versions.
std::unique_ptr<Win32DpiHelper> dpi_helper_ =
std::make_unique<Win32DpiHelper>();

// Set to true to be notified when the mouse leaves the window.
bool tracking_mouse_leave_ = false;
};

} // namespace flutter
Expand Down