Skip to content

Commit

Permalink
Bug 1534389 - Send normal mouse events when cursor is over a draggabl…
Browse files Browse the repository at this point in the history
…e region on Windows. r=jmathies

Differential Revision: https://phabricator.services.mozilla.com/D23231
  • Loading branch information
mikeconley committed Mar 18, 2019
1 parent 014f45f commit 52ea7e8
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 16 deletions.
46 changes: 31 additions & 15 deletions widget/windows/nsWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ nsWindow::nsWindow(bool aIsChildWindow)
mHideChrome = false;
mFullscreenMode = false;
mMousePresent = false;
mMouseInDraggableArea = false;
mDestroyCalled = false;
mIsEarlyBlankWindow = false;
mHasTaskbarIconBeenCreated = false;
Expand All @@ -613,7 +614,7 @@ nsWindow::nsWindow(bool aIsChildWindow)
mCachedHitTestPoint.x = 0;
mCachedHitTestPoint.y = 0;
mCachedHitTestTime = TimeStamp::Now();
mCachedHitTestResult = 0;
mCachedHitTestResult = false;
#ifdef MOZ_XUL
mTransparencyMode = eTransparencyOpaque;
memset(&mGlassMargins, 0, sizeof mGlassMargins);
Expand Down Expand Up @@ -5300,6 +5301,8 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
break;

case WM_MOUSEMOVE: {
mMouseInDraggableArea =
WithinDraggableRegion(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
if (!mMousePresent && !sIsInMouseCapture) {
// First MOUSEMOVE over the client area. Ask for MOUSELEAVE
TRACKMOUSEEVENT mTrack;
Expand Down Expand Up @@ -5332,12 +5335,19 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
}
} break;

case WM_NCMOUSEMOVE:
// If we receive a mouse move event on non-client chrome, make sure and
// send an eMouseExitFromWidget event as well.
if (mMousePresent && !sIsInMouseCapture)
case WM_NCMOUSEMOVE: {
LPARAM lParamClient = lParamToClient(lParam);
if (WithinDraggableRegion(GET_X_LPARAM(lParamClient),
GET_Y_LPARAM(lParamClient))) {
// If we noticed the mouse moving in our draggable region, forward the
// message as a normal WM_MOUSEMOVE.
SendMessage(mWnd, WM_MOUSEMOVE, wParam, lParamClient);
} else if (mMousePresent && !sIsInMouseCapture) {
// If we receive a mouse move event on non-client chrome, make sure and
// send an eMouseExitFromWidget event as well.
SendMessage(mWnd, WM_MOUSELEAVE, 0, 0);
break;
}
} break;

case WM_LBUTTONDOWN: {
result = DispatchMouseEvent(
Expand All @@ -5357,6 +5367,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,

case WM_MOUSELEAVE: {
if (!mMousePresent) break;
if (mMouseInDraggableArea) break;
mMousePresent = false;

// Check if the mouse is over the fullscreen transition window, if so
Expand Down Expand Up @@ -6106,24 +6117,29 @@ int32_t nsWindow::ClientMarginHitTestPoint(int32_t mx, int32_t my) {
if (!sIsInMouseCapture && allowContentOverride) {
POINT pt = {mx, my};
::ScreenToClient(mWnd, &pt);
if (pt.x == mCachedHitTestPoint.x && pt.y == mCachedHitTestPoint.y &&
TimeStamp::Now() - mCachedHitTestTime <
TimeDuration::FromMilliseconds(HITTEST_CACHE_LIFETIME_MS)) {
return mCachedHitTestResult;
}
if (mDraggableRegion.Contains(pt.x, pt.y)) {
if (WithinDraggableRegion(pt.x, pt.y)) {
testResult = HTCAPTION;
} else {
testResult = HTCLIENT;
}
mCachedHitTestPoint = pt;
mCachedHitTestTime = TimeStamp::Now();
mCachedHitTestResult = testResult;
}

return testResult;
}

bool nsWindow::WithinDraggableRegion(int32_t clientX, int32_t clientY) {
if (clientX == mCachedHitTestPoint.x && clientY == mCachedHitTestPoint.y &&
TimeStamp::Now() - mCachedHitTestTime <
TimeDuration::FromMilliseconds(HITTEST_CACHE_LIFETIME_MS)) {
return mCachedHitTestResult;
}
mCachedHitTestPoint = {clientX, clientY};
mCachedHitTestTime = TimeStamp::Now();

mCachedHitTestResult = mDraggableRegion.Contains(clientX, clientY);
return mCachedHitTestResult;
}

TimeStamp nsWindow::GetMessageTimeStamp(LONG aEventTime) const {
CurrentWindowsTimeGetter getCurrentTime(mWnd);
return TimeConverter().GetTimeStampFromSystemTime(aEventTime, getCurrentTime);
Expand Down
5 changes: 4 additions & 1 deletion widget/windows/nsWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ class nsWindow final : public nsWindowBase {
return mTransparencyMode;
}
void UpdateGlass();
bool WithinDraggableRegion(int32_t clientX, int32_t clientY);

protected:
#endif // MOZ_XUL
Expand Down Expand Up @@ -548,6 +549,7 @@ class nsWindow final : public nsWindowBase {
bool mIsRTL;
bool mFullscreenMode;
bool mMousePresent;
bool mMouseInDraggableArea;
bool mDestroyCalled;
bool mOpeningAnimationSuppressed;
bool mAlwaysOnTop;
Expand Down Expand Up @@ -659,6 +661,8 @@ class nsWindow final : public nsWindowBase {
// Whether we we're created as a child window (aka ChildWindow) or not.
bool mIsChildWindow : 1;

bool mCachedHitTestResult;

// The point in time at which the last paint completed. We use this to avoid
// painting too rapidly in response to frequent input events.
TimeStamp mLastPaintEndTime;
Expand All @@ -669,7 +673,6 @@ class nsWindow final : public nsWindowBase {
// Caching for hit test results
POINT mCachedHitTestPoint;
TimeStamp mCachedHitTestTime;
int32_t mCachedHitTestResult;

RefPtr<mozilla::widget::WinCompositorWidget> mBasicLayersSurface;

Expand Down

0 comments on commit 52ea7e8

Please sign in to comment.