Bug 672175 part.6 Summarize native mouse wheel events by MouseScrollHandler::EventInfo r=jimm

This commit is contained in:
Masayuki Nakano 2012-03-06 12:20:28 +09:00
parent 213ff5ec16
commit 48de337c85
3 changed files with 122 additions and 51 deletions

View File

@ -162,6 +162,58 @@ MouseScrollHandler::DispatchEvent(nsWindow* aWindow, nsGUIEvent& aEvent)
return aWindow->DispatchWindowEvent(&aEvent);
}
/******************************************************************************
*
* EventInfo
*
******************************************************************************/
MouseScrollHandler::EventInfo::EventInfo(UINT aMessage,
WPARAM aWParam, LPARAM aLParam)
{
NS_ABORT_IF_FALSE(aMessage == WM_MOUSEWHEEL || aMessage == WM_MOUSEHWHEEL,
"EventInfo must be initialized with WM_MOUSEWHEEL or WM_MOUSEHWHEEL");
MouseScrollHandler::GetInstance()->mSystemSettings.Init();
mIsVertical = (aMessage == WM_MOUSEWHEEL);
mIsPage = MouseScrollHandler::sInstance->
mSystemSettings.IsPageScroll(mIsVertical);
mDelta = (short)HIWORD(aWParam);
}
bool
MouseScrollHandler::EventInfo::CanDispatchMouseScrollEvent() const
{
if (!GetScrollAmount()) {
// XXX I think that we should dispatch mouse wheel events even if the
// operation will not scroll because the wheel operation really happened
// and web application may want to handle the event for non-scroll action.
return false;
}
return (mDelta != 0);
}
PRInt32
MouseScrollHandler::EventInfo::GetScrollAmount() const
{
if (mIsPage) {
return 1;
}
return MouseScrollHandler::sInstance->
mSystemSettings.GetScrollAmount(mIsVertical);
}
PRInt32
MouseScrollHandler::EventInfo::GetScrollFlags() const
{
PRInt32 result = mIsPage ? nsMouseScrollEvent::kIsFullPage : 0;
result |= mIsVertical ? nsMouseScrollEvent::kIsVertical :
nsMouseScrollEvent::kIsHorizontal;
return result;
}
/******************************************************************************
*
* SystemSettings

View File

@ -44,6 +44,49 @@ private:
* @return TRUE if the event was consumed. Otherwise, FALSE.
*/
static bool DispatchEvent(nsWindow* aWindow, nsGUIEvent& aEvent);
public:
class EventInfo {
public:
/**
* @param aMessage Must be WM_MOUSEWHEEL or WM_MOUSEHWHEEL.
*/
EventInfo(UINT aMessage, WPARAM aWParam, LPARAM aLParam);
bool CanDispatchMouseScrollEvent() const;
PRInt32 GetNativeDelta() const { return mDelta; }
bool IsVertical() const { return mIsVertical; }
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.
*/
PRInt32 GetScrollAmount() const;
/**
* @return One or more values of
* nsMouseScrollEvent::nsMouseScrollFlags.
*/
PRInt32 GetScrollFlags() const;
private:
EventInfo() {}
// TRUE if event is for vertical scroll. Otherwise, FALSE.
bool mIsVertical;
// TRUE if event scrolls per page, otherwise, FALSE.
bool mIsPage;
// The native delta value.
PRInt32 mDelta;
};
public:
class SystemSettings {
public:

View File

@ -6311,54 +6311,41 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
LRESULT *aRetValue)
{
InitMouseWheelScrollData();
MouseScrollHandler::SystemSettings& systemSettings =
MouseScrollHandler::GetInstance()->GetSystemSettings();
systemSettings.Init();
bool isVertical = (aMessage == WM_MOUSEWHEEL);
if (systemSettings.GetScrollAmount(isVertical) == 0) {
// XXX I think that we should dispatch mouse wheel events even if the
// operation will not scroll because the wheel operation really happened
// and web application may want to handle the event for non-scroll action.
MouseScrollHandler::EventInfo eventInfo(aMessage, aWParam, aLParam);
if (!eventInfo.CanDispatchMouseScrollEvent()) {
ResetRemainingWheelDelta();
*aRetValue = isVertical ? TRUE : FALSE; // means we don't process it
*aRetValue = eventInfo.ComputeMessageResult(false);
return;
}
PRInt32 nativeDelta = (short)HIWORD(aWParam);
if (!nativeDelta) {
*aRetValue = isVertical ? TRUE : FALSE; // means we don't process it
ResetRemainingWheelDelta();
return; // We cannot process this message
}
bool isPageScroll = systemSettings.IsPageScroll(isVertical);
// 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.
PRUint32 now = PR_IntervalToMilliseconds(PR_IntervalNow());
if (sLastMouseWheelWnd &&
(sLastMouseWheelWnd != mWnd ||
sLastMouseWheelDeltaIsPositive != (nativeDelta > 0) ||
sLastMouseWheelOrientationIsVertical != isVertical ||
sLastMouseWheelUnitIsPage != isPageScroll ||
sLastMouseWheelDeltaIsPositive != eventInfo.IsPositive() ||
sLastMouseWheelOrientationIsVertical != eventInfo.IsVertical() ||
sLastMouseWheelUnitIsPage != eventInfo.IsPage() ||
now - sLastMouseWheelTime > 1500)) {
ResetRemainingWheelDelta();
}
sLastMouseWheelWnd = mWnd;
sLastMouseWheelDeltaIsPositive = (nativeDelta > 0);
sLastMouseWheelOrientationIsVertical = isVertical;
sLastMouseWheelUnitIsPage = isPageScroll;
sLastMouseWheelDeltaIsPositive = eventInfo.IsPositive();
sLastMouseWheelOrientationIsVertical = eventInfo.IsVertical();
sLastMouseWheelUnitIsPage = eventInfo.IsPage();
sLastMouseWheelTime = now;
*aRetValue = isVertical ? FALSE : TRUE; // means we process this message
// means we process this message
*aRetValue = eventInfo.ComputeMessageResult(true);
nsModifierKeyState modKeyState;
// Our positive delta value means to bottom or right.
// But positive nativeDelta value means to top or right.
// But positive native delta value means to top or right.
// Use orienter for computing our delta value with native delta value.
PRInt32 orienter = isVertical ? -1 : 1;
PRInt32 orienter = eventInfo.IsVertical() ? -1 : 1;
// Assume the Control key is down if the Elantech touchpad has sent the
// mis-ordered WM_KEYDOWN/WM_MOUSEWHEEL messages. (See the comment in
@ -6386,24 +6373,21 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
PRInt32 actualScrollAction = nsQueryContentEvent::SCROLL_ACTION_NONE;
PRInt32 pixelsPerUnit = 0;
// the amount is the number of lines (or pages) per WHEEL_DELTA
PRInt32 computedScrollAmount =
isPageScroll ? 1 : systemSettings.GetScrollAmount(isVertical);
PRInt32 computedScrollAmount = eventInfo.GetScrollAmount();
if (MouseScrollHandler::GetInstance()->
GetUserPrefs().IsPixelScrollingEnabled()) {
nsMouseScrollEvent testEvent(true, NS_MOUSE_SCROLL, this);
InitEvent(testEvent);
testEvent.scrollFlags = isPageScroll ? nsMouseScrollEvent::kIsFullPage : 0;
testEvent.scrollFlags |= isVertical ? nsMouseScrollEvent::kIsVertical :
nsMouseScrollEvent::kIsHorizontal;
testEvent.scrollFlags = eventInfo.GetScrollFlags();
testEvent.isShift = scrollEvent.isShift;
testEvent.isControl = scrollEvent.isControl;
testEvent.isMeta = scrollEvent.isMeta;
testEvent.isAlt = scrollEvent.isAlt;
testEvent.delta = computedScrollAmount;
if ((isVertical && sLastMouseWheelDeltaIsPositive) ||
(!isVertical && !sLastMouseWheelDeltaIsPositive)) {
if ((eventInfo.IsVertical() && sLastMouseWheelDeltaIsPositive) ||
(!eventInfo.IsVertical() && !sLastMouseWheelDeltaIsPositive)) {
testEvent.delta *= -1;
}
nsQueryContentEvent queryEvent(true, NS_QUERY_SCROLL_TARGET_INFO, this);
@ -6415,7 +6399,7 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
if (queryEvent.mSucceeded) {
actualScrollAction = queryEvent.mReply.mComputedScrollAction;
if (actualScrollAction == nsQueryContentEvent::SCROLL_ACTION_PAGE) {
if (isVertical) {
if (eventInfo.IsVertical()) {
pixelsPerUnit = queryEvent.mReply.mPageHeight;
} else {
pixelsPerUnit = queryEvent.mReply.mPageWidth;
@ -6442,30 +6426,21 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
// we should set kHasPixels flag to the line scroll event.
scrollEvent.scrollFlags =
dispatchPixelScrollEvent ? nsMouseScrollEvent::kHasPixels : 0;
scrollEvent.scrollFlags |= eventInfo.GetScrollFlags();
PRInt32 nativeDeltaForScroll = nativeDelta + sRemainingDeltaForScroll;
PRInt32 nativeDeltaForScroll =
eventInfo.GetNativeDelta() + sRemainingDeltaForScroll;
// NOTE: Don't use computedScrollAmount for computing the delta value of
// line/page scroll event. The value will be recomputed in ESM.
if (isPageScroll) {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
if (isVertical) {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsVertical;
} else {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsHorizontal;
}
if (eventInfo.IsPage()) {
scrollEvent.delta = nativeDeltaForScroll * orienter / WHEEL_DELTA;
PRInt32 recomputedNativeDelta = scrollEvent.delta * orienter / WHEEL_DELTA;
sRemainingDeltaForScroll = nativeDeltaForScroll - recomputedNativeDelta;
} else {
double deltaPerUnit;
if (isVertical) {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsVertical;
} else {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsHorizontal;
}
deltaPerUnit =
(double)WHEEL_DELTA / systemSettings.GetScrollAmount(isVertical);
(double)WHEEL_DELTA / eventInfo.GetScrollAmount();
scrollEvent.delta =
RoundDelta((double)nativeDeltaForScroll * orienter / deltaPerUnit);
PRInt32 recomputedNativeDelta =
@ -6490,7 +6465,7 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
nsMouseScrollEvent pixelEvent(true, NS_MOUSE_PIXEL_SCROLL, this);
InitEvent(pixelEvent);
pixelEvent.scrollFlags = nsMouseScrollEvent::kAllowSmoothScroll;
pixelEvent.scrollFlags |= isVertical ?
pixelEvent.scrollFlags |= eventInfo.IsVertical() ?
nsMouseScrollEvent::kIsVertical : nsMouseScrollEvent::kIsHorizontal;
if (actualScrollAction == nsQueryContentEvent::SCROLL_ACTION_PAGE) {
pixelEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
@ -6501,7 +6476,8 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
pixelEvent.isMeta = scrollEvent.isMeta;
pixelEvent.isAlt = scrollEvent.isAlt;
PRInt32 nativeDeltaForPixel = nativeDelta + sRemainingDeltaForPixel;
PRInt32 nativeDeltaForPixel =
eventInfo.GetNativeDelta() + sRemainingDeltaForPixel;
// Pixel scroll event won't be recomputed the scroll amout and direction by
// ESM. Therefore, we need to set the computed amout and direction here.
PRInt32 orienterForPixel = reversePixelScrollDirection ? -orienter : orienter;