mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 719320 part.6 Separate pixel delta value accumulation code r=smaug
This commit is contained in:
parent
b65f092c51
commit
0127890358
@ -134,15 +134,12 @@ static PRUint32 gMouseOrKeyboardEventCounter = 0;
|
||||
static nsITimer* gUserInteractionTimer = nullptr;
|
||||
static nsITimerCallback* gUserInteractionTimerCallback = nullptr;
|
||||
|
||||
// Pixel scroll accumulation for synthetic line scrolls
|
||||
static nscoord gPixelScrollDeltaX = 0;
|
||||
static nscoord gPixelScrollDeltaY = 0;
|
||||
static PRUint32 gPixelScrollDeltaTimeout = 0;
|
||||
|
||||
TimeStamp nsEventStateManager::sHandlingInputStart;
|
||||
|
||||
nsEventStateManager::WheelPrefs*
|
||||
nsEventStateManager::WheelPrefs::sInstance = nullptr;
|
||||
nsEventStateManager::PixelDeltaAccumulator*
|
||||
nsEventStateManager::PixelDeltaAccumulator::sInstance = nullptr;
|
||||
|
||||
static inline bool
|
||||
IsMouseEventReal(nsEvent* aEvent)
|
||||
@ -844,6 +841,7 @@ nsEventStateManager::~nsEventStateManager()
|
||||
nsresult
|
||||
nsEventStateManager::Shutdown()
|
||||
{
|
||||
PixelDeltaAccumulator::Shutdown();
|
||||
Preferences::RemoveObservers(this, kObservedPrefs);
|
||||
m_haveShutdown = true;
|
||||
return NS_OK;
|
||||
@ -1137,6 +1135,8 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
if (content)
|
||||
mCurrentTargetContent = content;
|
||||
|
||||
PixelDeltaAccumulator::GetInstance()->Reset();
|
||||
|
||||
nsMouseScrollEvent* msEvent = static_cast<nsMouseScrollEvent*>(aEvent);
|
||||
WheelPrefs::GetInstance()->ApplyUserPrefsToDelta(msEvent);
|
||||
|
||||
@ -1156,52 +1156,11 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
nsMouseScrollEvent *msEvent = static_cast<nsMouseScrollEvent*>(aEvent);
|
||||
WheelPrefs::GetInstance()->ApplyUserPrefsToDelta(msEvent);
|
||||
|
||||
// Clear old deltas after a period of non action
|
||||
if (OutOfTime(gPixelScrollDeltaTimeout, nsMouseWheelTransaction::GetTimeoutTime())) {
|
||||
gPixelScrollDeltaX = gPixelScrollDeltaY = 0;
|
||||
}
|
||||
gPixelScrollDeltaTimeout = PR_IntervalToMilliseconds(PR_IntervalNow());
|
||||
|
||||
// If needed send a line scroll event for pixel scrolls with kNoLines
|
||||
if (msEvent->scrollFlags & nsMouseScrollEvent::kNoLines) {
|
||||
nsIScrollableFrame* scrollableFrame =
|
||||
ComputeScrollTarget(aTargetFrame, msEvent, false);
|
||||
PRInt32 pixelsPerUnit =
|
||||
nsPresContext::AppUnitsToIntCSSPixels(
|
||||
GetScrollAmount(aPresContext, msEvent, aTargetFrame,
|
||||
scrollableFrame));
|
||||
if (msEvent->scrollFlags & nsMouseScrollEvent::kIsVertical) {
|
||||
gPixelScrollDeltaX += msEvent->delta;
|
||||
if (!gPixelScrollDeltaX || !pixelsPerUnit)
|
||||
break;
|
||||
|
||||
if (NS_ABS(gPixelScrollDeltaX) >= pixelsPerUnit) {
|
||||
PRInt32 numLines = (PRInt32)ceil((float)gPixelScrollDeltaX/(float)pixelsPerUnit);
|
||||
|
||||
gPixelScrollDeltaX -= numLines*pixelsPerUnit;
|
||||
|
||||
nsWeakFrame weakFrame(aTargetFrame);
|
||||
SendLineScrollEvent(aTargetFrame, msEvent, aPresContext,
|
||||
aStatus, numLines);
|
||||
NS_ENSURE_STATE(weakFrame.IsAlive());
|
||||
}
|
||||
} else if (msEvent->scrollFlags & nsMouseScrollEvent::kIsHorizontal) {
|
||||
gPixelScrollDeltaY += msEvent->delta;
|
||||
if (!gPixelScrollDeltaY || !pixelsPerUnit)
|
||||
break;
|
||||
|
||||
if (NS_ABS(gPixelScrollDeltaY) >= pixelsPerUnit) {
|
||||
PRInt32 numLines = (PRInt32)ceil((float)gPixelScrollDeltaY/(float)pixelsPerUnit);
|
||||
|
||||
gPixelScrollDeltaY -= numLines*pixelsPerUnit;
|
||||
|
||||
nsWeakFrame weakFrame(aTargetFrame);
|
||||
SendLineScrollEvent(aTargetFrame, msEvent, aPresContext,
|
||||
aStatus, numLines);
|
||||
NS_ENSURE_STATE(weakFrame.IsAlive());
|
||||
}
|
||||
}
|
||||
}
|
||||
nsWeakFrame weakFrame(aTargetFrame);
|
||||
PixelDeltaAccumulator::GetInstance()->
|
||||
OnMousePixelScrollEvent(aPresContext, aTargetFrame,
|
||||
this, msEvent, aStatus);
|
||||
NS_ENSURE_STATE(weakFrame.IsAlive());
|
||||
|
||||
// When the last line scroll has been canceled, eat the pixel scroll event
|
||||
if ((msEvent->scrollFlags & nsMouseScrollEvent::kIsHorizontal) ?
|
||||
@ -5162,6 +5121,91 @@ nsEventStateManager::ClearGlobalActiveContent(nsEventStateManager* aClearer)
|
||||
sActiveESM = nullptr;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* nsEventStateManager::PixelDeltaAccumulator */
|
||||
/******************************************************************/
|
||||
|
||||
void
|
||||
nsEventStateManager::PixelDeltaAccumulator::OnMousePixelScrollEvent(
|
||||
nsPresContext* aPresContext,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStateManager* aESM,
|
||||
nsMouseScrollEvent* aEvent,
|
||||
nsEventStatus* aStatus)
|
||||
{
|
||||
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)) {
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
nsIScrollableFrame* scrollTarget =
|
||||
aESM->ComputeScrollTarget(aTargetFrame, aEvent, false);
|
||||
PRInt32 pixelsPerLine = nsPresContext::AppUnitsToIntCSSPixels(
|
||||
aESM->GetScrollAmount(aPresContext, aEvent,
|
||||
aTargetFrame, scrollTarget));
|
||||
|
||||
if (!mLastTime.IsNull()) {
|
||||
TimeDuration duration = TimeStamp::Now() - mLastTime;
|
||||
if (duration.ToMilliseconds() > nsMouseWheelTransaction::GetTimeoutTime()) {
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
mLastTime = TimeStamp::Now();
|
||||
|
||||
bool isHorizontal =
|
||||
(aEvent->scrollFlags & nsMouseScrollEvent::kIsHorizontal) != 0;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::PixelDeltaAccumulator::Reset()
|
||||
{
|
||||
mX = mY = 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/* nsEventStateManager::WheelPrefs */
|
||||
|
@ -464,6 +464,55 @@ protected:
|
||||
*/
|
||||
PRInt32 ComputeWheelActionFor(nsMouseScrollEvent* aMouseEvent);
|
||||
|
||||
/**
|
||||
* PixelDeltaAccumulator class manages pixel delta values for dispatching
|
||||
* DOMMouseScroll event.
|
||||
*/
|
||||
class PixelDeltaAccumulator
|
||||
{
|
||||
public:
|
||||
static PixelDeltaAccumulator* GetInstance()
|
||||
{
|
||||
if (!sInstance) {
|
||||
sInstance = new PixelDeltaAccumulator;
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
static void Shutdown()
|
||||
{
|
||||
delete sInstance;
|
||||
sInstance = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* OnMousePixelScrollEvent() stores pixel delta values. And if the
|
||||
* accumulated delta becomes a line height, dispatches DOMMouseScroll event
|
||||
* automatically.
|
||||
*/
|
||||
void OnMousePixelScrollEvent(nsPresContext* aPresContext,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStateManager* aESM,
|
||||
nsMouseScrollEvent* aEvent,
|
||||
nsEventStatus* aStatus);
|
||||
/**
|
||||
* Reset() resets both delta values.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
PixelDeltaAccumulator() :
|
||||
mX(0), mY(0)
|
||||
{
|
||||
}
|
||||
|
||||
PRInt32 mX;
|
||||
PRInt32 mY;
|
||||
TimeStamp mLastTime;
|
||||
|
||||
static PixelDeltaAccumulator* sInstance;
|
||||
};
|
||||
|
||||
// end mousewheel functions
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user