Bug 879562 - Connect up MetroWidget scroll wheel event handling to WinMouseScrollHandler. r=masayuki

This commit is contained in:
Jim Mathies 2013-08-09 05:15:48 -05:00
parent ab854d295c
commit b9029e054f
5 changed files with 29 additions and 122 deletions

View File

@ -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() ||

View File

@ -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<double>(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<UI::Input::IPointerPoint> currentPoint;
WRL::ComPtr<UI::Input::IPointerPointProperties> 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(&timestamp);
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<UI::Input::IPointerPoint> 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<PointerEventHandler>(
this,
&MetroInput::OnPointerWheelChanged).Get(),
&mTokenPointerWheelChanged);
// Register for the events raised by our Gesture Recognizer
mGestureRecognizer->add_Tapped(
WRL::Callback<TappedEventHandler>(

View File

@ -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.

View File

@ -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<int32_t>(aDeltaY);
Log(" Vertical scroll, delta %d", mouseData);
} else if (aNativeMessage == MOUSEEVENTF_HWHEEL) {
mouseData = static_cast<int32_t>(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<int32_t>(aDeltaY) : static_cast<int32_t>(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:
{

View File

@ -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);