From b9029e054f0866bd09538a897ca3dc1560deceb4 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Fri, 9 Aug 2013 05:15:48 -0500 Subject: [PATCH] Bug 879562 - Connect up MetroWidget scroll wheel event handling to WinMouseScrollHandler. r=masayuki --- widget/windows/WinMouseScrollHandler.cpp | 5 ++ widget/windows/winrt/MetroInput.cpp | 83 ------------------------ widget/windows/winrt/MetroInput.h | 3 - widget/windows/winrt/MetroWidget.cpp | 58 +++++++---------- widget/windows/winrt/MetroWidget.h | 2 + 5 files changed, 29 insertions(+), 122 deletions(-) diff --git a/widget/windows/WinMouseScrollHandler.cpp b/widget/windows/WinMouseScrollHandler.cpp index 579b17264a4..ee75ffe87f3 100644 --- a/widget/windows/WinMouseScrollHandler.cpp +++ b/widget/windows/WinMouseScrollHandler.cpp @@ -1065,6 +1065,11 @@ MouseScrollHandler::Device::GetWorkaroundPref(const char* aPrefName, void MouseScrollHandler::Device::Init() { + // Not supported in metro mode. + if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro) { + return; + } + sFakeScrollableWindowNeeded = GetWorkaroundPref("ui.trackpoint_hack.enabled", (TrackPoint::IsDriverInstalled() || diff --git a/widget/windows/winrt/MetroInput.cpp b/widget/windows/winrt/MetroInput.cpp index 08a4ae62887..2747897e340 100644 --- a/widget/windows/winrt/MetroInput.cpp +++ b/widget/windows/winrt/MetroInput.cpp @@ -31,8 +31,6 @@ namespace { const double SWIPE_MIN_DISTANCE = 5.0; const double SWIPE_MIN_VELOCITY = 5.0; - const double WHEEL_DELTA_DOUBLE = static_cast(WHEEL_DELTA); - // Convenience typedefs for event handler types typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CInput__CEdgeGesture_Windows__CUI__CInput__CEdgeGestureEventArgs_t EdgeGestureHandler; typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreDispatcher_Windows__CUI__CCore__CAcceleratorKeyEventArgs_t AcceleratorKeyActivatedHandler; @@ -173,7 +171,6 @@ MetroInput::MetroInput(MetroWidget* aWidget, mTokenPointerMoved.value = 0; mTokenPointerEntered.value = 0; mTokenPointerExited.value = 0; - mTokenPointerWheelChanged.value = 0; mTokenEdgeStarted.value = 0; mTokenEdgeCanceled.value = 0; mTokenEdgeCompleted.value = 0; @@ -297,79 +294,6 @@ MetroInput::OnEdgeGestureCompleted(UI::Input::IEdgeGesture* sender, return S_OK; } -// This event is received when the user rotates a mouse wheel. MSDN does not -// seem to indicate that this event can be triggered from other types of input -// (i.e. pen, touch). -HRESULT -MetroInput::OnPointerWheelChanged(UI::Core::ICoreWindow* aSender, - UI::Core::IPointerEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - WRL::ComPtr currentPoint; - WRL::ComPtr props; - Foundation::Point position; - uint64_t timestamp; - float pressure; - boolean horzEvent; - int32_t delta; - - aArgs->get_CurrentPoint(currentPoint.GetAddressOf()); - currentPoint->get_Position(&position); - currentPoint->get_Timestamp(×tamp); - currentPoint->get_Properties(props.GetAddressOf()); - props->get_Pressure(&pressure); - props->get_IsHorizontalMouseWheel(&horzEvent); - props->get_MouseWheelDelta(&delta); - - WheelEvent wheelEvent(true, NS_WHEEL_WHEEL, mWidget.Get()); - mModifierKeyState.Update(); - mModifierKeyState.InitInputEvent(wheelEvent); - wheelEvent.refPoint = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(position)); - wheelEvent.time = timestamp; - wheelEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE; - wheelEvent.pressure = pressure; - wheelEvent.deltaMode = nsIDOMWheelEvent::DOM_DELTA_LINE; - - static int previousVertLeftOverDelta = 0; - static int previousHorLeftOverDelta = 0; - // Since we have chosen DOM_DELTA_LINE as our deltaMode, deltaX or deltaY - // should be the number of lines that we want to scroll. Windows has given - // us delta, which is a more precise value, and the constant WHEEL_DELTA, - // which defines the threshold of wheel movement before an action should - // be taken. - if (horzEvent) { - wheelEvent.deltaX = delta / WHEEL_DELTA_DOUBLE; - if ((delta > 0 && previousHorLeftOverDelta < 0) - || (delta < 0 && previousHorLeftOverDelta > 0)) { - previousHorLeftOverDelta = 0; - } - previousHorLeftOverDelta += delta; - wheelEvent.lineOrPageDeltaX = previousHorLeftOverDelta / WHEEL_DELTA; - previousHorLeftOverDelta %= WHEEL_DELTA; - } else { - int mouseWheelDelta = -1 * delta; - wheelEvent.deltaY = mouseWheelDelta / WHEEL_DELTA_DOUBLE; - if ((mouseWheelDelta > 0 && previousVertLeftOverDelta < 0) - || (mouseWheelDelta < 0 && previousVertLeftOverDelta > 0)) { - previousVertLeftOverDelta = 0; - } - previousVertLeftOverDelta += mouseWheelDelta; - wheelEvent.lineOrPageDeltaY = previousVertLeftOverDelta / WHEEL_DELTA; - previousVertLeftOverDelta %= WHEEL_DELTA; - } - - DispatchEventIgnoreStatus(&wheelEvent); - - WRL::ComPtr point; - aArgs->get_CurrentPoint(point.GetAddressOf()); - mGestureRecognizer->ProcessMouseWheelEvent(point.Get(), - wheelEvent.IsShift(), - wheelEvent.IsControl()); - return S_OK; -} - /** * This helper function is used by our processing of PointerPressed, * PointerReleased, and PointerMoved events. @@ -1149,7 +1073,6 @@ MetroInput::UnregisterInputEvents() { mWindow->remove_PointerMoved(mTokenPointerMoved); mWindow->remove_PointerEntered(mTokenPointerEntered); mWindow->remove_PointerExited(mTokenPointerExited); - mWindow->remove_PointerWheelChanged(mTokenPointerWheelChanged); // Unregistering from the gesture recognizer events probably isn't as // necessary since we're about to destroy the gesture recognizer, but @@ -1241,12 +1164,6 @@ MetroInput::RegisterInputEvents() &MetroInput::OnPointerExited).Get(), &mTokenPointerExited); - mWindow->add_PointerWheelChanged( - WRL::Callback( - this, - &MetroInput::OnPointerWheelChanged).Get(), - &mTokenPointerWheelChanged); - // Register for the events raised by our Gesture Recognizer mGestureRecognizer->add_Tapped( WRL::Callback( diff --git a/widget/windows/winrt/MetroInput.h b/widget/windows/winrt/MetroInput.h index e6d21c9f5db..735dfa5ee98 100644 --- a/widget/windows/winrt/MetroInput.h +++ b/widget/windows/winrt/MetroInput.h @@ -114,8 +114,6 @@ public: // by sending gecko events and forwarding these input events to its // GestureRecognizer to be processed into more complex input events // (tap, rightTap, rotate, etc) - HRESULT OnPointerWheelChanged(ICoreWindow* aSender, - IPointerEventArgs* aArgs); HRESULT OnPointerPressed(ICoreWindow* aSender, IPointerEventArgs* aArgs); HRESULT OnPointerReleased(ICoreWindow* aSender, @@ -243,7 +241,6 @@ private: EventRegistrationToken mTokenPointerMoved; EventRegistrationToken mTokenPointerEntered; EventRegistrationToken mTokenPointerExited; - EventRegistrationToken mTokenPointerWheelChanged; // When we register ourselves to handle edge gestures, we receive a // token. To we unregister ourselves, we must use the token we received. diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp index b8836ec1ba6..3c78acb24df 100644 --- a/widget/windows/winrt/MetroWidget.cpp +++ b/widget/windows/winrt/MetroWidget.cpp @@ -30,6 +30,7 @@ #include "nsExceptionHandler.h" #endif #include "UIABridgePrivate.h" +#include "WinMouseScrollHandler.h" using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; @@ -168,6 +169,7 @@ MetroWidget::MetroWidget() : if (!gInstanceCount) { UserActivity(); nsTextStore::Initialize(); + MouseScrollHandler::Initialize(); KeyboardLayout::GetInstance()->OnLayoutChange(::GetKeyboardLayout(0)); } // !gInstanceCount gInstanceCount++; @@ -241,6 +243,7 @@ MetroWidget::Create(nsIWidget *aParent, // the main widget gets created first gTopLevelAssigned = true; MetroApp::SetBaseWidget(this); + WinUtils::SetNSWindowBasePtr(mWnd, this); if (mWidgetListener) { mWidgetListener->WindowActivated(); @@ -278,6 +281,7 @@ MetroWidget::Destroy() // Release references to children, device context, toolkit, and app shell. nsBaseWidget::Destroy(); nsBaseWidget::OnDestroy(); + WinUtils::SetNSWindowBasePtr(mWnd, nullptr); if (mLayerManager) { mLayerManager->Destroy(); @@ -524,43 +528,18 @@ MetroWidget::SynthesizeNativeMouseEvent(nsIntPoint aPoint, nsresult MetroWidget::SynthesizeNativeMouseScrollEvent(nsIntPoint aPoint, - uint32_t aNativeMessage, - double aDeltaX, - double aDeltaY, - double aDeltaZ, - uint32_t aModifierFlags, - uint32_t aAdditionalFlags) + uint32_t aNativeMessage, + double aDeltaX, + double aDeltaY, + double aDeltaZ, + uint32_t aModifierFlags, + uint32_t aAdditionalFlags) { - Log("ENTERED SynthesizeNativeMouseScrollEvent"); - - int32_t mouseData = 0; - if (aNativeMessage == MOUSEEVENTF_WHEEL) { - mouseData = static_cast(aDeltaY); - Log(" Vertical scroll, delta %d", mouseData); - } else if (aNativeMessage == MOUSEEVENTF_HWHEEL) { - mouseData = static_cast(aDeltaX); - Log(" Horizontal scroll, delta %d", mouseData); - } else { - Log("ERROR Unrecognized scroll event"); - return NS_ERROR_INVALID_ARG; - } - - INPUT inputs[2]; - memset(inputs, 0, 2*sizeof(INPUT)); - inputs[0].type = inputs[1].type = INPUT_MOUSE; - inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; - // Inexplicably, the x and y coordinates that we want to move the mouse to - // are specified as values in the range (0, 65535). (0,0) represents the - // top left of the primary monitor and (65535, 65535) represents the - // bottom right of the primary monitor. - inputs[0].mi.dx = (aPoint.x * 65535) / ::GetSystemMetrics(SM_CXSCREEN); - inputs[0].mi.dy = (aPoint.y * 65535) / ::GetSystemMetrics(SM_CYSCREEN); - inputs[1].mi.dwFlags = aNativeMessage; - inputs[1].mi.mouseData = mouseData; - SendInputs(aModifierFlags, inputs, 2); - - Log("EXITING SynthesizeNativeMouseScrollEvent"); - return NS_OK; + return MouseScrollHandler::SynthesizeNativeMouseScrollEvent( + this, aPoint, aNativeMessage, + (aNativeMessage == WM_MOUSEWHEEL || aNativeMessage == WM_VSCROLL) ? + static_cast(aDeltaY) : static_cast(aDeltaX), + aModifierFlags, aAdditionalFlags); } static void @@ -597,9 +576,16 @@ MetroWidget::WindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLPara // Indicates if we should hand messages to the default windows // procedure for processing. bool processDefault = true; + // The result returned if we do not do default processing. LRESULT processResult = 0; + MSGResult msgResult(&processResult); + MouseScrollHandler::ProcessMessage(this, aMsg, aWParam, aLParam, msgResult); + if (msgResult.mConsumed) { + return processResult; + } + switch (aMsg) { case WM_PAINT: { diff --git a/widget/windows/winrt/MetroWidget.h b/widget/windows/winrt/MetroWidget.h index 7aa27491865..24e6ea17b2a 100644 --- a/widget/windows/winrt/MetroWidget.h +++ b/widget/windows/winrt/MetroWidget.h @@ -71,6 +71,8 @@ public: // nsWindowBase virtual void InitEvent(nsGUIEvent& aEvent, nsIntPoint* aPoint = nullptr) MOZ_OVERRIDE; virtual bool DispatchWindowEvent(nsGUIEvent* aEvent) MOZ_OVERRIDE; + virtual bool IsTopLevelWidget() MOZ_OVERRIDE { return true; } + virtual nsWindowBase* GetParentWindowBase(bool aIncludeOwner) MOZ_OVERRIDE { return nullptr; } // nsBaseWidget virtual CompositorParent* NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight);