зеркало из https://github.com/mozilla/gecko-dev.git
Bug 719320 part.8-6 Init lineOrPageDeltaX and lineOrPageDeltaY from accumulated delta values if the wheel event is caused by pixel scroll only device or the delta values have been modified with prefs r=smaug
This commit is contained in:
Родитель
24a276180b
Коммит
e98c45fc9f
|
@ -751,6 +751,7 @@ nsDOMEvent::DuplicatePrivateData()
|
|||
wheelEvent->modifiers = oldWheelEvent->modifiers;
|
||||
wheelEvent->inputSource = oldWheelEvent->inputSource;
|
||||
wheelEvent->customizedByUserPrefs = oldWheelEvent->customizedByUserPrefs;
|
||||
wheelEvent->isPixelOnlyDevice = oldWheelEvent->isPixelOnlyDevice;
|
||||
wheelEvent->lineOrPageDeltaX = oldWheelEvent->lineOrPageDeltaX;
|
||||
wheelEvent->lineOrPageDeltaY = oldWheelEvent->lineOrPageDeltaY;
|
||||
wheelEvent->overflowDeltaX = oldWheelEvent->overflowDeltaX;
|
||||
|
|
|
@ -138,8 +138,8 @@ TimeStamp nsEventStateManager::sHandlingInputStart;
|
|||
|
||||
nsEventStateManager::WheelPrefs*
|
||||
nsEventStateManager::WheelPrefs::sInstance = nullptr;
|
||||
nsEventStateManager::PixelDeltaAccumulator*
|
||||
nsEventStateManager::PixelDeltaAccumulator::sInstance = nullptr;
|
||||
nsEventStateManager::DeltaAccumulator*
|
||||
nsEventStateManager::DeltaAccumulator::sInstance = nullptr;
|
||||
|
||||
static inline PRInt32
|
||||
RoundDown(double aDouble)
|
||||
|
@ -810,6 +810,7 @@ nsEventStateManager::~nsEventStateManager()
|
|||
NS_RELEASE(gUserInteractionTimer);
|
||||
}
|
||||
WheelPrefs::Shutdown();
|
||||
DeltaAccumulator::Shutdown();
|
||||
}
|
||||
|
||||
if (sDragOverContent && sDragOverContent->OwnerDoc() == mDocument) {
|
||||
|
@ -835,7 +836,6 @@ nsEventStateManager::~nsEventStateManager()
|
|||
nsresult
|
||||
nsEventStateManager::Shutdown()
|
||||
{
|
||||
PixelDeltaAccumulator::Shutdown();
|
||||
Preferences::RemoveObservers(this, kObservedPrefs);
|
||||
m_haveShutdown = true;
|
||||
return NS_OK;
|
||||
|
@ -1132,6 +1132,13 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
|
||||
widget::WheelEvent* wheelEvent = static_cast<widget::WheelEvent*>(aEvent);
|
||||
WheelPrefs::GetInstance()->ApplyUserPrefsToDelta(wheelEvent);
|
||||
|
||||
// Init lineOrPageDelta values for line scroll events for some devices
|
||||
// on some platforms which might dispatch wheel events which don't have
|
||||
// lineOrPageDelta values. And also, if delta values are customized by
|
||||
// prefs, this recomputes them.
|
||||
DeltaAccumulator::GetInstance()->
|
||||
InitLineOrPageDelta(aTargetFrame, this, wheelEvent);
|
||||
}
|
||||
break;
|
||||
case NS_QUERY_SELECTED_TEXT:
|
||||
|
@ -5140,91 +5147,95 @@ nsEventStateManager::ClearGlobalActiveContent(nsEventStateManager* aClearer)
|
|||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* nsEventStateManager::PixelDeltaAccumulator */
|
||||
/* nsEventStateManager::DeltaAccumulator */
|
||||
/******************************************************************/
|
||||
|
||||
void
|
||||
nsEventStateManager::PixelDeltaAccumulator::OnMousePixelScrollEvent(
|
||||
nsPresContext* aPresContext,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStateManager* aESM,
|
||||
nsMouseScrollEvent* aEvent,
|
||||
nsEventStatus* aStatus)
|
||||
nsEventStateManager::DeltaAccumulator::InitLineOrPageDelta(
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStateManager* aESM,
|
||||
widget::WheelEvent* aEvent)
|
||||
{
|
||||
MOZ_ASSERT(aPresContext);
|
||||
MOZ_ASSERT(aESM);
|
||||
MOZ_ASSERT(aEvent);
|
||||
MOZ_ASSERT(aEvent->message == NS_MOUSE_PIXEL_SCROLL);
|
||||
MOZ_ASSERT(NS_IS_TRUSTED_EVENT(aEvent));
|
||||
MOZ_ASSERT(aStatus);
|
||||
|
||||
if (!(aEvent->scrollFlags & nsMouseScrollEvent::kNoLines)) {
|
||||
if (!(aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL &&
|
||||
aEvent->isPixelOnlyDevice) &&
|
||||
!WheelPrefs::GetInstance()->NeedToComputeLineOrPageDelta(aEvent)) {
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
nsIScrollableFrame* scrollTarget =
|
||||
aESM->ComputeScrollTarget(aTargetFrame, aEvent, false);
|
||||
nsSize scrollAmount =
|
||||
aESM->GetScrollAmount(aPresContext, aEvent, aTargetFrame, scrollTarget);
|
||||
bool isHorizontal =
|
||||
(aEvent->scrollFlags & nsMouseScrollEvent::kIsHorizontal) != 0;
|
||||
PRInt32 pixelsPerLine =
|
||||
nsPresContext::AppUnitsToIntCSSPixels(isHorizontal ? scrollAmount.width :
|
||||
scrollAmount.height);
|
||||
|
||||
// Reset if the previous wheel event is too old.
|
||||
if (!mLastTime.IsNull()) {
|
||||
TimeDuration duration = TimeStamp::Now() - mLastTime;
|
||||
if (duration.ToMilliseconds() > nsMouseWheelTransaction::GetTimeoutTime()) {
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
// If we have accumulated delta, we may need to reset it.
|
||||
if (mHandlingDeltaMode != PR_UINT32_MAX) {
|
||||
// If wheel event type is changed, reset the values.
|
||||
if (mHandlingDeltaMode != aEvent->deltaMode ||
|
||||
mHandlingPixelOnlyDevice != aEvent->isPixelOnlyDevice) {
|
||||
Reset();
|
||||
} else {
|
||||
// If the delta direction is changed, we should reset only the
|
||||
// accumulated values.
|
||||
if (mX && aEvent->deltaX && ((aEvent->deltaX > 0.0) != (mX > 0.0))) {
|
||||
mX = 0.0;
|
||||
}
|
||||
if (mY && aEvent->deltaY && ((aEvent->deltaY > 0.0) != (mY > 0.0))) {
|
||||
mY = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mHandlingDeltaMode = aEvent->deltaMode;
|
||||
mHandlingPixelOnlyDevice = aEvent->isPixelOnlyDevice;
|
||||
|
||||
mX += aEvent->deltaX;
|
||||
mY += aEvent->deltaY;
|
||||
|
||||
if (mHandlingDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL) {
|
||||
// Records pixel delta values and init lineOrPageDeltaX and
|
||||
// lineOrPageDeltaY for wheel events which are caused by pixel only
|
||||
// devices. Ignore mouse wheel transaction for computing this. The
|
||||
// lineOrPageDelta values will be used by dispatching legacy
|
||||
// NS_MOUSE_SCROLL_EVENT (DOMMouseScroll) but not be used for scrolling
|
||||
// of default action. The transaction should be used only for the default
|
||||
// action.
|
||||
nsIScrollableFrame* scrollTarget =
|
||||
aESM->ComputeScrollTarget(aTargetFrame, aEvent, false);
|
||||
nsIFrame* frame = do_QueryFrame(scrollTarget);
|
||||
nsPresContext* pc =
|
||||
frame ? frame->PresContext() : aTargetFrame->PresContext();
|
||||
nsSize scrollAmount = aESM->GetScrollAmount(pc, aEvent, scrollTarget);
|
||||
nsIntSize scrollAmountInCSSPixels(
|
||||
nsPresContext::AppUnitsToIntCSSPixels(scrollAmount.width),
|
||||
nsPresContext::AppUnitsToIntCSSPixels(scrollAmount.height));
|
||||
|
||||
aEvent->lineOrPageDeltaX = RoundDown(mX) / scrollAmountInCSSPixels.width;
|
||||
aEvent->lineOrPageDeltaY = RoundDown(mY) / scrollAmountInCSSPixels.height;
|
||||
|
||||
mX -= aEvent->lineOrPageDeltaX * scrollAmountInCSSPixels.width;
|
||||
mY -= aEvent->lineOrPageDeltaY * scrollAmountInCSSPixels.height;
|
||||
} else {
|
||||
aEvent->lineOrPageDeltaX = RoundDown(mX);
|
||||
aEvent->lineOrPageDeltaY = RoundDown(mY);
|
||||
mX -= aEvent->lineOrPageDeltaX;
|
||||
mY -= aEvent->lineOrPageDeltaY;
|
||||
}
|
||||
|
||||
mLastTime = TimeStamp::Now();
|
||||
|
||||
// If the delta direction is changed, we should reset the accumulated values.
|
||||
if (mX && isHorizontal && aEvent->delta &&
|
||||
((aEvent->delta > 0) != (mX > 0))) {
|
||||
mX = 0;
|
||||
}
|
||||
if (mY && !isHorizontal && aEvent->delta &&
|
||||
((aEvent->delta > 0) != (mY > 0))) {
|
||||
mY = 0;
|
||||
}
|
||||
|
||||
PRInt32 numLines;
|
||||
if (isHorizontal) {
|
||||
// Adds delta value, first.
|
||||
mX += aEvent->delta;
|
||||
// Compute lines in integer scrolled by the accumulated delta value.
|
||||
numLines =
|
||||
static_cast<PRInt32>(NS_round(static_cast<double>(mX) / pixelsPerLine));
|
||||
// Consume the lines from the accumulated delta value.
|
||||
mX -= numLines * pixelsPerLine;
|
||||
} else {
|
||||
// Adds delta value, first.
|
||||
mY += aEvent->delta;
|
||||
// Compute lines in integer scrolled by the accumulated delta value.
|
||||
numLines =
|
||||
static_cast<PRInt32>(NS_round(static_cast<double>(mY) / pixelsPerLine));
|
||||
// Consume the lines from the accumulated delta value.
|
||||
mY -= numLines * pixelsPerLine;
|
||||
}
|
||||
|
||||
if (!numLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
aESM->SendLineScrollEvent(aTargetFrame, aEvent, aPresContext,
|
||||
aStatus, numLines);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::PixelDeltaAccumulator::Reset()
|
||||
nsEventStateManager::DeltaAccumulator::Reset()
|
||||
{
|
||||
mX = mY = 0;
|
||||
mX = mY = 0.0;
|
||||
mHandlingDeltaMode = PR_UINT32_MAX;
|
||||
mHandlingPixelOnlyDevice = false;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
@ -5256,6 +5267,7 @@ nsEventStateManager::WheelPrefs::OnPrefChanged(const char* aPrefName,
|
|||
{
|
||||
// forget all prefs, it's not problem for performance.
|
||||
sInstance->Reset();
|
||||
DeltaAccumulator::GetInstance()->Reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5410,3 +5422,14 @@ nsEventStateManager::WheelPrefs::GetActionFor(nsMouseScrollEvent* aEvent)
|
|||
Init(index);
|
||||
return mActions[index];
|
||||
}
|
||||
|
||||
bool
|
||||
nsEventStateManager::WheelPrefs::NeedToComputeLineOrPageDelta(
|
||||
widget::WheelEvent* aEvent)
|
||||
{
|
||||
Index index = GetIndexFor(aEvent);
|
||||
Init(index);
|
||||
|
||||
return (mMultiplierX[index] != 1.0 && mMultiplierX[index] != -1.0) ||
|
||||
(mMultiplierY[index] != 1.0 && mMultiplierY[index] != -1.0);
|
||||
}
|
||||
|
|
|
@ -351,6 +351,12 @@ protected:
|
|||
};
|
||||
Action GetActionFor(nsMouseScrollEvent* aEvent);
|
||||
|
||||
/**
|
||||
* NeedToComputeLineOrPageDelta() returns if the aEvent needs to be
|
||||
* computed the lineOrPageDelta values.
|
||||
*/
|
||||
bool NeedToComputeLineOrPageDelta(mozilla::widget::WheelEvent* aEvent);
|
||||
|
||||
private:
|
||||
WheelPrefs();
|
||||
~WheelPrefs();
|
||||
|
@ -499,16 +505,18 @@ protected:
|
|||
PRInt32 ComputeWheelActionFor(nsMouseScrollEvent* aMouseEvent);
|
||||
|
||||
/**
|
||||
* PixelDeltaAccumulator class manages pixel delta values for dispatching
|
||||
* DOMMouseScroll event.
|
||||
* DeltaAccumulator class manages delta values for dispatching DOMMouseScroll
|
||||
* event. If wheel events are caused by pixel scroll only devices or
|
||||
* the delta values are customized by prefs, this class stores the delta
|
||||
* values and set lineOrPageDelta values.
|
||||
*/
|
||||
class PixelDeltaAccumulator
|
||||
class DeltaAccumulator
|
||||
{
|
||||
public:
|
||||
static PixelDeltaAccumulator* GetInstance()
|
||||
static DeltaAccumulator* GetInstance()
|
||||
{
|
||||
if (!sInstance) {
|
||||
sInstance = new PixelDeltaAccumulator;
|
||||
sInstance = new DeltaAccumulator;
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
@ -520,31 +528,34 @@ protected:
|
|||
}
|
||||
|
||||
/**
|
||||
* OnMousePixelScrollEvent() stores pixel delta values. And if the
|
||||
* accumulated delta becomes a line height, dispatches DOMMouseScroll event
|
||||
* automatically.
|
||||
* InitLineOrPageDelta() stores pixel delta values of WheelEvents which are
|
||||
* caused if it's needed. And if the accumulated delta becomes a
|
||||
* line height, sets lineOrPageDeltaX and lineOrPageDeltaY automatically.
|
||||
*/
|
||||
void OnMousePixelScrollEvent(nsPresContext* aPresContext,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStateManager* aESM,
|
||||
nsMouseScrollEvent* aEvent,
|
||||
nsEventStatus* aStatus);
|
||||
void InitLineOrPageDelta(nsIFrame* aTargetFrame,
|
||||
nsEventStateManager* aESM,
|
||||
mozilla::widget::WheelEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Reset() resets both delta values.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
PixelDeltaAccumulator() :
|
||||
mX(0), mY(0)
|
||||
DeltaAccumulator() :
|
||||
mX(0.0), mY(0.0), mHandlingDeltaMode(PR_UINT32_MAX),
|
||||
mHandlingPixelOnlyDevice(false)
|
||||
{
|
||||
}
|
||||
|
||||
PRInt32 mX;
|
||||
PRInt32 mY;
|
||||
double mX;
|
||||
double mY;
|
||||
TimeStamp mLastTime;
|
||||
|
||||
static PixelDeltaAccumulator* sInstance;
|
||||
PRUint32 mHandlingDeltaMode;
|
||||
bool mHandlingPixelOnlyDevice;
|
||||
|
||||
static DeltaAccumulator* sInstance;
|
||||
};
|
||||
|
||||
// end mousewheel functions
|
||||
|
|
|
@ -1408,7 +1408,7 @@ public:
|
|||
nsMouseEvent_base(aIsTrusted, aMessage, aWidget, NS_WHEEL_EVENT),
|
||||
deltaX(0.0), deltaY(0.0), deltaZ(0.0),
|
||||
deltaMode(nsIDOMWheelEvent::DOM_DELTA_PIXEL),
|
||||
customizedByUserPrefs(false),
|
||||
customizedByUserPrefs(false), isPixelOnlyDevice(false),
|
||||
lineOrPageDeltaX(0), lineOrPageDeltaY(0),
|
||||
overflowDeltaX(0.0), overflowDeltaY(0.0)
|
||||
{
|
||||
|
@ -1425,6 +1425,12 @@ public:
|
|||
// Otherwise, i.e., they are computed from native events, false.
|
||||
bool customizedByUserPrefs;
|
||||
|
||||
// If device event handlers don't know when they should set lineOrPageDeltaX
|
||||
// and lineOrPageDeltaY, this is true. Otherwise, false.
|
||||
// If isPixelOnlyDevice is true, ESM will generate NS_MOUSE_SCROLL events
|
||||
// when accumulated pixel delta values reach a line height.
|
||||
bool isPixelOnlyDevice;
|
||||
|
||||
// If widget sets lineOrPageDelta, nsEventStateManager will dispatch
|
||||
// NS_MOUSE_SCROLL event for compatibility. Note that the delta value means
|
||||
// pages if the deltaMode is DOM_DELTA_PAGE, otherwise, lines.
|
||||
|
|
|
@ -130,6 +130,7 @@ struct ParamTraits<mozilla::widget::WheelEvent>
|
|||
WriteParam(aMsg, aParam.deltaZ);
|
||||
WriteParam(aMsg, aParam.deltaMode);
|
||||
WriteParam(aMsg, aParam.customizedByUserPrefs);
|
||||
WriteParam(aMsg, aParam.isPixelOnlyDevice);
|
||||
WriteParam(aMsg, aParam.lineOrPageDeltaX);
|
||||
WriteParam(aMsg, aParam.lineOrPageDeltaY);
|
||||
WriteParam(aMsg, aParam.overflowDeltaX);
|
||||
|
@ -144,6 +145,7 @@ struct ParamTraits<mozilla::widget::WheelEvent>
|
|||
ReadParam(aMsg, aIter, &aResult->deltaZ) &&
|
||||
ReadParam(aMsg, aIter, &aResult->deltaMode) &&
|
||||
ReadParam(aMsg, aIter, &aResult->customizedByUserPrefs) &&
|
||||
ReadParam(aMsg, aIter, &aResult->isPixelOnlyDevice) &&
|
||||
ReadParam(aMsg, aIter, &aResult->lineOrPageDeltaX) &&
|
||||
ReadParam(aMsg, aIter, &aResult->lineOrPageDeltaY) &&
|
||||
ReadParam(aMsg, aIter, &aResult->overflowDeltaX) &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче