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
Родитель bdee4f1853
Коммит f441247ea3
3 изменённых файлов: 122 добавлений и 51 удалений

Просмотреть файл

@ -162,6 +162,58 @@ MouseScrollHandler::DispatchEvent(nsWindow* aWindow, nsGUIEvent& aEvent)
return aWindow->DispatchWindowEvent(&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 * SystemSettings

Просмотреть файл

@ -44,6 +44,49 @@ private:
* @return TRUE if the event was consumed. Otherwise, FALSE. * @return TRUE if the event was consumed. Otherwise, FALSE.
*/ */
static bool DispatchEvent(nsWindow* aWindow, nsGUIEvent& aEvent); 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: public:
class SystemSettings { class SystemSettings {
public: public:

Просмотреть файл

@ -6311,54 +6311,41 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
LRESULT *aRetValue) LRESULT *aRetValue)
{ {
InitMouseWheelScrollData(); InitMouseWheelScrollData();
MouseScrollHandler::SystemSettings& systemSettings =
MouseScrollHandler::GetInstance()->GetSystemSettings();
systemSettings.Init();
bool isVertical = (aMessage == WM_MOUSEWHEEL); MouseScrollHandler::EventInfo eventInfo(aMessage, aWParam, aLParam);
if (systemSettings.GetScrollAmount(isVertical) == 0) { if (!eventInfo.CanDispatchMouseScrollEvent()) {
// 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.
ResetRemainingWheelDelta(); ResetRemainingWheelDelta();
*aRetValue = isVertical ? TRUE : FALSE; // means we don't process it *aRetValue = eventInfo.ComputeMessageResult(false);
return; 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 // Discard the remaining delta if current wheel message and last one are
// received by different window or to scroll different direction or // received by different window or to scroll different direction or
// different unit scroll. Furthermore, if the last event was too old. // different unit scroll. Furthermore, if the last event was too old.
PRUint32 now = PR_IntervalToMilliseconds(PR_IntervalNow()); PRUint32 now = PR_IntervalToMilliseconds(PR_IntervalNow());
if (sLastMouseWheelWnd && if (sLastMouseWheelWnd &&
(sLastMouseWheelWnd != mWnd || (sLastMouseWheelWnd != mWnd ||
sLastMouseWheelDeltaIsPositive != (nativeDelta > 0) || sLastMouseWheelDeltaIsPositive != eventInfo.IsPositive() ||
sLastMouseWheelOrientationIsVertical != isVertical || sLastMouseWheelOrientationIsVertical != eventInfo.IsVertical() ||
sLastMouseWheelUnitIsPage != isPageScroll || sLastMouseWheelUnitIsPage != eventInfo.IsPage() ||
now - sLastMouseWheelTime > 1500)) { now - sLastMouseWheelTime > 1500)) {
ResetRemainingWheelDelta(); ResetRemainingWheelDelta();
} }
sLastMouseWheelWnd = mWnd; sLastMouseWheelWnd = mWnd;
sLastMouseWheelDeltaIsPositive = (nativeDelta > 0); sLastMouseWheelDeltaIsPositive = eventInfo.IsPositive();
sLastMouseWheelOrientationIsVertical = isVertical; sLastMouseWheelOrientationIsVertical = eventInfo.IsVertical();
sLastMouseWheelUnitIsPage = isPageScroll; sLastMouseWheelUnitIsPage = eventInfo.IsPage();
sLastMouseWheelTime = now; sLastMouseWheelTime = now;
*aRetValue = isVertical ? FALSE : TRUE; // means we process this message // means we process this message
*aRetValue = eventInfo.ComputeMessageResult(true);
nsModifierKeyState modKeyState; nsModifierKeyState modKeyState;
// Our positive delta value means to bottom or right. // 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. // 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 // Assume the Control key is down if the Elantech touchpad has sent the
// mis-ordered WM_KEYDOWN/WM_MOUSEWHEEL messages. (See the comment in // 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 actualScrollAction = nsQueryContentEvent::SCROLL_ACTION_NONE;
PRInt32 pixelsPerUnit = 0; PRInt32 pixelsPerUnit = 0;
// the amount is the number of lines (or pages) per WHEEL_DELTA // the amount is the number of lines (or pages) per WHEEL_DELTA
PRInt32 computedScrollAmount = PRInt32 computedScrollAmount = eventInfo.GetScrollAmount();
isPageScroll ? 1 : systemSettings.GetScrollAmount(isVertical);
if (MouseScrollHandler::GetInstance()-> if (MouseScrollHandler::GetInstance()->
GetUserPrefs().IsPixelScrollingEnabled()) { GetUserPrefs().IsPixelScrollingEnabled()) {
nsMouseScrollEvent testEvent(true, NS_MOUSE_SCROLL, this); nsMouseScrollEvent testEvent(true, NS_MOUSE_SCROLL, this);
InitEvent(testEvent); InitEvent(testEvent);
testEvent.scrollFlags = isPageScroll ? nsMouseScrollEvent::kIsFullPage : 0; testEvent.scrollFlags = eventInfo.GetScrollFlags();
testEvent.scrollFlags |= isVertical ? nsMouseScrollEvent::kIsVertical :
nsMouseScrollEvent::kIsHorizontal;
testEvent.isShift = scrollEvent.isShift; testEvent.isShift = scrollEvent.isShift;
testEvent.isControl = scrollEvent.isControl; testEvent.isControl = scrollEvent.isControl;
testEvent.isMeta = scrollEvent.isMeta; testEvent.isMeta = scrollEvent.isMeta;
testEvent.isAlt = scrollEvent.isAlt; testEvent.isAlt = scrollEvent.isAlt;
testEvent.delta = computedScrollAmount; testEvent.delta = computedScrollAmount;
if ((isVertical && sLastMouseWheelDeltaIsPositive) || if ((eventInfo.IsVertical() && sLastMouseWheelDeltaIsPositive) ||
(!isVertical && !sLastMouseWheelDeltaIsPositive)) { (!eventInfo.IsVertical() && !sLastMouseWheelDeltaIsPositive)) {
testEvent.delta *= -1; testEvent.delta *= -1;
} }
nsQueryContentEvent queryEvent(true, NS_QUERY_SCROLL_TARGET_INFO, this); nsQueryContentEvent queryEvent(true, NS_QUERY_SCROLL_TARGET_INFO, this);
@ -6415,7 +6399,7 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
if (queryEvent.mSucceeded) { if (queryEvent.mSucceeded) {
actualScrollAction = queryEvent.mReply.mComputedScrollAction; actualScrollAction = queryEvent.mReply.mComputedScrollAction;
if (actualScrollAction == nsQueryContentEvent::SCROLL_ACTION_PAGE) { if (actualScrollAction == nsQueryContentEvent::SCROLL_ACTION_PAGE) {
if (isVertical) { if (eventInfo.IsVertical()) {
pixelsPerUnit = queryEvent.mReply.mPageHeight; pixelsPerUnit = queryEvent.mReply.mPageHeight;
} else { } else {
pixelsPerUnit = queryEvent.mReply.mPageWidth; 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. // we should set kHasPixels flag to the line scroll event.
scrollEvent.scrollFlags = scrollEvent.scrollFlags =
dispatchPixelScrollEvent ? nsMouseScrollEvent::kHasPixels : 0; 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 // NOTE: Don't use computedScrollAmount for computing the delta value of
// line/page scroll event. The value will be recomputed in ESM. // line/page scroll event. The value will be recomputed in ESM.
if (isPageScroll) { if (eventInfo.IsPage()) {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
if (isVertical) {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsVertical;
} else {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsHorizontal;
}
scrollEvent.delta = nativeDeltaForScroll * orienter / WHEEL_DELTA; scrollEvent.delta = nativeDeltaForScroll * orienter / WHEEL_DELTA;
PRInt32 recomputedNativeDelta = scrollEvent.delta * orienter / WHEEL_DELTA; PRInt32 recomputedNativeDelta = scrollEvent.delta * orienter / WHEEL_DELTA;
sRemainingDeltaForScroll = nativeDeltaForScroll - recomputedNativeDelta; sRemainingDeltaForScroll = nativeDeltaForScroll - recomputedNativeDelta;
} else { } else {
double deltaPerUnit; double deltaPerUnit;
if (isVertical) {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsVertical;
} else {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsHorizontal;
}
deltaPerUnit = deltaPerUnit =
(double)WHEEL_DELTA / systemSettings.GetScrollAmount(isVertical); (double)WHEEL_DELTA / eventInfo.GetScrollAmount();
scrollEvent.delta = scrollEvent.delta =
RoundDelta((double)nativeDeltaForScroll * orienter / deltaPerUnit); RoundDelta((double)nativeDeltaForScroll * orienter / deltaPerUnit);
PRInt32 recomputedNativeDelta = PRInt32 recomputedNativeDelta =
@ -6490,7 +6465,7 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
nsMouseScrollEvent pixelEvent(true, NS_MOUSE_PIXEL_SCROLL, this); nsMouseScrollEvent pixelEvent(true, NS_MOUSE_PIXEL_SCROLL, this);
InitEvent(pixelEvent); InitEvent(pixelEvent);
pixelEvent.scrollFlags = nsMouseScrollEvent::kAllowSmoothScroll; pixelEvent.scrollFlags = nsMouseScrollEvent::kAllowSmoothScroll;
pixelEvent.scrollFlags |= isVertical ? pixelEvent.scrollFlags |= eventInfo.IsVertical() ?
nsMouseScrollEvent::kIsVertical : nsMouseScrollEvent::kIsHorizontal; nsMouseScrollEvent::kIsVertical : nsMouseScrollEvent::kIsHorizontal;
if (actualScrollAction == nsQueryContentEvent::SCROLL_ACTION_PAGE) { if (actualScrollAction == nsQueryContentEvent::SCROLL_ACTION_PAGE) {
pixelEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage; pixelEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
@ -6501,7 +6476,8 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
pixelEvent.isMeta = scrollEvent.isMeta; pixelEvent.isMeta = scrollEvent.isMeta;
pixelEvent.isAlt = scrollEvent.isAlt; 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 // 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. // ESM. Therefore, we need to set the computed amout and direction here.
PRInt32 orienterForPixel = reversePixelScrollDirection ? -orienter : orienter; PRInt32 orienterForPixel = reversePixelScrollDirection ? -orienter : orienter;