diff options
author | David Robillard <d@drobilla.net> | 2019-07-21 15:38:03 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2019-07-21 15:46:46 +0200 |
commit | 5192224751e8b6d9963312e217782f7a1a70fb39 (patch) | |
tree | 597cf047497e0cc8ab215f89fa699eaa94b9a0fc | |
parent | 0ef7e4312136bc4f4b29ba17a9e6ea74a77418d5 (diff) | |
download | pugl-5192224751e8b6d9963312e217782f7a1a70fb39.tar.gz pugl-5192224751e8b6d9963312e217782f7a1a70fb39.tar.bz2 pugl-5192224751e8b6d9963312e217782f7a1a70fb39.zip |
Implement enter and leave notifications on Windows
-rw-r--r-- | pugl/pugl_win.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/pugl/pugl_win.c b/pugl/pugl_win.c index 3edf08f..fc72498 100644 --- a/pugl/pugl_win.c +++ b/pugl/pugl_win.c @@ -79,6 +79,7 @@ struct PuglInternalsImpl { DWORD refreshRate; double timerFrequency; bool resizing; + bool mouseTracked; }; // Scoped class to manage the fake window used during window creation @@ -609,6 +610,27 @@ handleConfigure(PuglView* view, PuglEvent* event) return rect; } +static void +handleCrossing(PuglView* view, const PuglEventType type, POINT pos) +{ + POINT root_pos = pos; + ClientToScreen(view->impl->hwnd, &root_pos); + + const PuglEventCrossing ev = { + type, + view, + 0, + (uint32_t)GetMessageTime(), + (double)pos.x, + (double)pos.y, + (double)root_pos.x, + (double)root_pos.y, + getModifiers(), + PUGL_CROSSING_NORMAL + }; + puglDispatchEvent(view, (const PuglEvent*)&ev); +} + static LRESULT handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) { @@ -673,8 +695,19 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) case WM_MOUSEMOVE: pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); - ClientToScreen(view->impl->hwnd, &pt); + if (!view->impl->mouseTracked) { + TRACKMOUSEEVENT tme = {0}; + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = view->impl->hwnd; + TrackMouseEvent(&tme); + + handleCrossing(view, PUGL_ENTER_NOTIFY, pt); + view->impl->mouseTracked = true; + } + + ClientToScreen(view->impl->hwnd, &pt); event.motion.type = PUGL_MOTION_NOTIFY; event.motion.time = (uint32_t)GetMessageTime(); event.motion.x = GET_X_LPARAM(lParam); @@ -684,6 +717,12 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) event.motion.state = getModifiers(); event.motion.is_hint = false; break; + case WM_MOUSELEAVE: + GetCursorPos(&pt); + ScreenToClient(view->impl->hwnd, &pt); + handleCrossing(view, PUGL_LEAVE_NOTIFY, pt); + view->impl->mouseTracked = false; + break; case WM_LBUTTONDOWN: initMouseEvent(&event, view, 1, true, lParam); break; |