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 3 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
16 changes: 16 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,16 @@ 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();
// 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;
}
}

void Win32FlutterWindow::OnChar(char32_t code_point) {
if (process_events_) {
SendChar(code_point);
Expand Down Expand Up @@ -207,6 +217,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 @@ -102,6 +105,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
19 changes: 16 additions & 3 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 @@ -129,14 +139,17 @@ Win32Window::MessageHandler(HWND hwnd,
current_height_ = height;
window->HandleResize(width, height);
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();
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 @@ -106,7 +109,13 @@ class Win32Window {

UINT GetCurrentHeight();

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

Choose a reason for hiding this comment

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

ivars need to be private, not protected, with accessors if necessary. In this case, rather than an accessor you can just put the toggling of the variable in the superclass. That would make a lot more sense anyway, because what it's tracking is whether TrackMouseEvent has fired, and that's superclass logic, not subclass logic.

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


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 Down