diff --git a/widget/windows/WinMouseScrollHandler.cpp b/widget/windows/WinMouseScrollHandler.cpp index 6faa446b14f..f87065f3d15 100644 --- a/widget/windows/WinMouseScrollHandler.cpp +++ b/widget/windows/WinMouseScrollHandler.cpp @@ -139,6 +139,13 @@ MouseScrollHandler::ProcessMessage(nsWindow* aWindow, UINT msg, } return false; + case MOZ_WM_MOUSEVWHEEL: + case MOZ_WM_MOUSEHWHEEL: + GetInstance()->HandleMouseWheelMessage(aWindow, msg, wParam, lParam); + // Doesn't need to call next wndproc for internal wheel message. + aEatMessage = true; + return true; + case WM_KEYDOWN: case WM_KEYUP: PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, @@ -266,6 +273,98 @@ MouseScrollHandler::GetScrollTargetInfo( return result; } +void +MouseScrollHandler::HandleMouseWheelMessage(nsWindow* aWindow, + UINT aMessage, + WPARAM aWParam, + LPARAM aLParam) +{ + NS_ABORT_IF_FALSE( + (aMessage == MOZ_WM_MOUSEVWHEEL || aMessage == MOZ_WM_MOUSEHWHEEL), + "HandleMouseWheelMessage must be called with " + "MOZ_WM_MOUSEVWHEEL or MOZ_WM_MOUSEHWHEEL"); + + PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, + ("MouseScroll::HandleMouseWheelMessage: aWindow=%p, " + "aMessage=MOZ_WM_MOUSE%sWHEEL, aWParam=0x%08X, aLParam=0x%08X", + aWindow, aMessage == MOZ_WM_MOUSEVWHEEL ? "V" : "H", + aWParam, aLParam)); + + EventInfo eventInfo(aWindow, WinUtils::GetNativeMessage(aMessage), + aWParam, aLParam); + if (!eventInfo.CanDispatchMouseScrollEvent()) { + PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, + ("MouseScroll::HandleMouseWheelMessage: Cannot dispatch the events")); + mLastEventInfo.ResetTransaction(); + return; + } + + // Discard the remaining delta if current wheel message and last one are + // received by different window or to scroll different direction or + // different unit scroll. Furthermore, if the last event was too old. + if (!mLastEventInfo.CanContinueTransaction(eventInfo)) { + mLastEventInfo.ResetTransaction(); + } + + mLastEventInfo.RecordEvent(eventInfo); + + nsModifierKeyState modKeyState = GetModifierKeyState(); + + // Before dispatching line scroll event, we should get the current scroll + // event target information for pixel scroll. + ScrollTargetInfo scrollTargetInfo = + GetScrollTargetInfo(aWindow, eventInfo, modKeyState); + + // Grab the widget, it might be destroyed by a DOM event handler. + nsRefPtr kungFuDethGrip(aWindow); + + nsMouseScrollEvent scrollEvent(true, NS_MOUSE_SCROLL, aWindow); + if (mLastEventInfo.InitMouseScrollEvent(aWindow, scrollEvent, + scrollTargetInfo, modKeyState)) { + PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, + ("MouseScroll::HandleMouseWheelMessage: dispatching " + "NS_MOUSE_SCROLL event")); + DispatchEvent(aWindow, scrollEvent); + if (aWindow->Destroyed()) { + PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, + ("MouseScroll::HandleMouseWheelMessage: The window was destroyed " + "by NS_MOUSE_SCROLL event")); + mLastEventInfo.ResetTransaction(); + return; + } + } +#ifdef PR_LOGGING + else { + PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, + ("MouseScroll::HandleMouseWheelMessage: NS_MOUSE_SCROLL event is not " + "dispatched")); + } +#endif + + nsMouseScrollEvent pixelEvent(true, NS_MOUSE_PIXEL_SCROLL, aWindow); + if (mLastEventInfo.InitMousePixelScrollEvent(aWindow, pixelEvent, + scrollTargetInfo, modKeyState)) { + PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, + ("MouseScroll::HandleMouseWheelMessage: dispatching " + "NS_MOUSE_PIXEL_SCROLL event")); + DispatchEvent(aWindow, pixelEvent); + if (aWindow->Destroyed()) { + PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, + ("MouseScroll::HandleMouseWheelMessage: The window was destroyed " + "by NS_MOUSE_PIXEL_SCROLL event")); + mLastEventInfo.ResetTransaction(); + return; + } + } +#ifdef PR_LOGGING + else { + PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, + ("MouseScroll::HandleMouseWheelMessage: NS_MOUSE_PIXEL_SCROLL event is " + "not dispatched")); + } +#endif +} + /****************************************************************************** * * EventInfo diff --git a/widget/windows/WinMouseScrollHandler.h b/widget/windows/WinMouseScrollHandler.h index af895af1d4f..362bfec41d3 100644 --- a/widget/windows/WinMouseScrollHandler.h +++ b/widget/windows/WinMouseScrollHandler.h @@ -35,13 +35,6 @@ public: LRESULT *aRetValue, bool &aEatMessage); - /** - * GetModifierKeyState() returns current modifier key state. - * Note that some devices need some hack for the modifier key state. - * This method does it automatically. - */ - static nsModifierKeyState GetModifierKeyState(); - private: MouseScrollHandler(); ~MouseScrollHandler(); @@ -55,7 +48,27 @@ private: */ static bool DispatchEvent(nsWindow* aWindow, nsGUIEvent& aEvent); -public: + /** + * GetModifierKeyState() returns current modifier key state. + * Note that some devices need some hack for the modifier key state. + * This method does it automatically. + */ + static nsModifierKeyState GetModifierKeyState(); + + /** + * HandleMouseWheelMessage() processes MOZ_WM_MOUSEVWHEEL and + * MOZ_WM_MOUSEHWHEEL which are posted when one of our windows received + * WM_MOUSEWHEEL or WM_MOUSEHWHEEL for avoiding deadlock with OOPP. + * + * @param aWindow A window which receives the wheel message. + * @param aMessage MOZ_WM_MOUSEWHEEL or MOZ_WM_MOUSEHWHEEL. + * @param aWParam The wParam value of the original message. + * @param aLParam The lParam value of the original message. + */ + void HandleMouseWheelMessage(nsWindow* aWindow, + UINT aMessage, + WPARAM aWParam, + LPARAM aLParam); class EventInfo; /** @@ -102,11 +115,6 @@ public: bool IsPositive() const { return (mDelta > 0); } bool IsPage() const { return mIsPage; } - LRESULT ComputeMessageResult(bool aWeProcessed) const - { - return IsVertical() ? !aWeProcessed : aWeProcessed; - } - /** * @return Number of lines or pages scrolled per WHEEL_DELTA. */ @@ -208,12 +216,8 @@ public: PRInt32 mRemainingDeltaForPixel; }; - LastEventInfo& GetLastEventInfo() { return mLastEventInfo; } - -private: LastEventInfo mLastEventInfo; -public: class SystemSettings { public: SystemSettings() : mInitialized(false) {} @@ -240,12 +244,6 @@ public: PRInt32 mScrollChars; }; - SystemSettings& GetSystemSettings() - { - return mSystemSettings; - } - -private: SystemSettings mSystemSettings; public: diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 2ade34875fa..67736366fd2 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -5221,21 +5221,6 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam, // our window again, it causes making infinite message loop. return true; - case MOZ_WM_MOUSEVWHEEL: - case MOZ_WM_MOUSEHWHEEL: - { - UINT nativeMessage = WinUtils::GetNativeMessage(msg); - // If OnMouseWheel returns true, the event was forwarded directly to another - // mozilla window message handler (ProcessMessage). In this case the return - // value of the forwarded event is in 'result' which we should return immediately. - // If OnMouseWheel returns false, OnMouseWheel processed the event internally. - // 'result' and 'aRetValue' will be set based on what we did with the event, so - // we should fall through. - OnMouseWheelInternal(nativeMessage, wParam, lParam, aRetValue); - // Doesn't need to call next wndproc for internal message. - return true; - } - case WM_DWMCOMPOSITIONCHANGED: // First, update the compositor state to latest one. All other methods // should use same state as here for consistency painting. @@ -6258,67 +6243,6 @@ bool nsWindow::OnGesture(WPARAM wParam, LPARAM lParam) return true; // Handled } -/** - * OnMouseWheelInternal - mouse wheel event processing. - * aMessage may be WM_MOUSEWHEEL or WM_MOUSEHWHEEL but this is called when - * ProcessMessage() handles MOZ_WM_MOUSEVWHEEL or MOZ_WM_MOUSEHWHEEL. - */ -void -nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam, - LRESULT *aRetValue) -{ - MouseScrollHandler* handler = MouseScrollHandler::GetInstance(); - MouseScrollHandler::EventInfo eventInfo(this, aMessage, aWParam, aLParam); - if (!eventInfo.CanDispatchMouseScrollEvent()) { - handler->GetLastEventInfo().ResetTransaction(); - *aRetValue = eventInfo.ComputeMessageResult(false); - return; - } - - MouseScrollHandler::LastEventInfo& lastEventInfo = - handler->GetLastEventInfo(); - - // Discard the remaining delta if current wheel message and last one are - // received by different window or to scroll different direction or - // different unit scroll. Furthermore, if the last event was too old. - if (!lastEventInfo.CanContinueTransaction(eventInfo)) { - lastEventInfo.ResetTransaction(); - } - - lastEventInfo.RecordEvent(eventInfo); - - // means we process this message - *aRetValue = eventInfo.ComputeMessageResult(true); - - nsModifierKeyState modKeyState = MouseScrollHandler::GetModifierKeyState(); - - // Before dispatching line scroll event, we should get the current scroll - // event target information for pixel scroll. - MouseScrollHandler::ScrollTargetInfo scrollTargetInfo = - handler->GetScrollTargetInfo(this, eventInfo, modKeyState); - - nsMouseScrollEvent scrollEvent(true, NS_MOUSE_SCROLL, this); - if (lastEventInfo.InitMouseScrollEvent(this, scrollEvent, - scrollTargetInfo, modKeyState)) { - DispatchWindowEvent(&scrollEvent); - if (mOnDestroyCalled) { - lastEventInfo.ResetTransaction(); - return; - } - } - - nsMouseScrollEvent pixelEvent(true, NS_MOUSE_PIXEL_SCROLL, this); - if (lastEventInfo.InitMousePixelScrollEvent(this, pixelEvent, - scrollTargetInfo, modKeyState)) { - DispatchWindowEvent(&pixelEvent); - if (mOnDestroyCalled) { - lastEventInfo.ResetTransaction(); - return; - } - } - return; -} - static bool StringCaseInsensitiveEquals(const PRUnichar* aChars1, const PRUint32 aNumChars1, const PRUnichar* aChars2, const PRUint32 aNumChars2) diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index bc07b0e1aa5..6d918a24629 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -407,9 +407,6 @@ protected: void OnWindowPosChanged(WINDOWPOS *wp, bool& aResult); void OnMouseWheel(UINT aMsg, WPARAM aWParam, LPARAM aLParam, LRESULT *aRetValue); - void OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, - LPARAM aLParam, - LRESULT *aRetValue); void OnWindowPosChanging(LPWINDOWPOS& info); void OnSysColorChanged();