зеркало из https://github.com/mozilla/pjs.git
Bug 672175 part.7 Manage last wheel scroll message information by MouseScrollHandler::LastEventInfo r=jimm
This commit is contained in:
Родитель
f441247ea3
Коммит
c420e187b8
|
@ -65,6 +65,11 @@ bool MouseScrollHandler::Device::Elantech::sUseSwipeHack = false;
|
|||
bool MouseScrollHandler::Device::Elantech::sUsePinchHack = false;
|
||||
DWORD MouseScrollHandler::Device::Elantech::sZoomUntil = 0;
|
||||
|
||||
// The duration until timeout of events transaction. The value is 1.5 sec,
|
||||
// it's just a magic number, it was suggested by Logitech's engineer, see
|
||||
// bug 605648 comment 90.
|
||||
#define DEFAULT_TIMEOUT_DURATION 1500
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MouseScrollHandler
|
||||
|
@ -168,7 +173,8 @@ MouseScrollHandler::DispatchEvent(nsWindow* aWindow, nsGUIEvent& aEvent)
|
|||
*
|
||||
******************************************************************************/
|
||||
|
||||
MouseScrollHandler::EventInfo::EventInfo(UINT aMessage,
|
||||
MouseScrollHandler::EventInfo::EventInfo(nsWindow* aWindow,
|
||||
UINT aMessage,
|
||||
WPARAM aWParam, LPARAM aLParam)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aMessage == WM_MOUSEWHEEL || aMessage == WM_MOUSEHWHEEL,
|
||||
|
@ -180,6 +186,8 @@ MouseScrollHandler::EventInfo::EventInfo(UINT aMessage,
|
|||
mIsPage = MouseScrollHandler::sInstance->
|
||||
mSystemSettings.IsPageScroll(mIsVertical);
|
||||
mDelta = (short)HIWORD(aWParam);
|
||||
mWnd = aWindow->GetWindowHandle();
|
||||
mTimeStamp = TimeStamp::Now();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -214,6 +222,50 @@ MouseScrollHandler::EventInfo::GetScrollFlags() const
|
|||
return result;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* LastEventInfo
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool
|
||||
MouseScrollHandler::LastEventInfo::CanContinueTransaction(
|
||||
const EventInfo& aNewEvent)
|
||||
{
|
||||
return !mWnd ||
|
||||
(mWnd == aNewEvent.GetWindowHandle() &&
|
||||
IsPositive() == aNewEvent.IsPositive() &&
|
||||
mIsVertical == aNewEvent.IsVertical() &&
|
||||
mIsPage == aNewEvent.IsPage() &&
|
||||
TimeStamp::Now() - mTimeStamp <=
|
||||
TimeDuration::FromMilliseconds(DEFAULT_TIMEOUT_DURATION));
|
||||
}
|
||||
|
||||
void
|
||||
MouseScrollHandler::LastEventInfo::ResetTransaction()
|
||||
{
|
||||
if (!mWnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
|
||||
("MouseScroll::LastEventInfo::ResetTransaction()"));
|
||||
|
||||
mWnd = nsnull;
|
||||
mRemainingDeltaForScroll = 0;
|
||||
mRemainingDeltaForPixel = 0;
|
||||
}
|
||||
|
||||
void
|
||||
MouseScrollHandler::LastEventInfo::RecordEvent(const EventInfo& aEvent)
|
||||
{
|
||||
mWnd = aEvent.GetWindowHandle();
|
||||
mDelta = aEvent.GetNativeDelta();
|
||||
mIsVertical = aEvent.IsVertical();
|
||||
mIsPage = aEvent.IsPage();
|
||||
mTimeStamp = TimeStamp::Now();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* SystemSettings
|
||||
|
@ -278,6 +330,10 @@ MouseScrollHandler::SystemSettings::MarkDirty()
|
|||
("MouseScrollHandler::SystemSettings::MarkDirty(): "
|
||||
"Marking SystemSettings dirty"));
|
||||
mInitialized = false;
|
||||
// When system settings are changed, we should reset current transaction.
|
||||
MOZ_ASSERT(sInstance,
|
||||
"Must not be called at initializing MouseScrollHandler");
|
||||
MouseScrollHandler::sInstance->mLastEventInfo.ResetTransaction();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -332,6 +388,11 @@ MouseScrollHandler::UserPrefs::MarkDirty()
|
|||
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
|
||||
("MouseScrollHandler::UserPrefs::MarkDirty(): Marking UserPrefs dirty"));
|
||||
mInitialized = false;
|
||||
// When user prefs for mousewheel are changed, we should reset current
|
||||
// transaction.
|
||||
MOZ_ASSERT(sInstance,
|
||||
"Must not be called at initializing MouseScrollHandler");
|
||||
MouseScrollHandler::sInstance->mLastEventInfo.ResetTransaction();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nscore.h"
|
||||
#include "nsDebug.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include <windows.h>
|
||||
|
||||
class nsWindow;
|
||||
|
@ -49,13 +50,16 @@ public:
|
|||
class EventInfo {
|
||||
public:
|
||||
/**
|
||||
* @param aWindow An nsWindow which is handling the event.
|
||||
* @param aMessage Must be WM_MOUSEWHEEL or WM_MOUSEHWHEEL.
|
||||
*/
|
||||
EventInfo(UINT aMessage, WPARAM aWParam, LPARAM aLParam);
|
||||
EventInfo(nsWindow* aWindow, UINT aMessage, WPARAM aWParam, LPARAM aLParam);
|
||||
|
||||
bool CanDispatchMouseScrollEvent() const;
|
||||
|
||||
PRInt32 GetNativeDelta() const { return mDelta; }
|
||||
HWND GetWindowHandle() const { return mWnd; }
|
||||
const TimeStamp& GetTimeStamp() const { return mTimeStamp; }
|
||||
bool IsVertical() const { return mIsVertical; }
|
||||
bool IsPositive() const { return (mDelta > 0); }
|
||||
bool IsPage() const { return mIsPage; }
|
||||
|
@ -76,8 +80,11 @@ public:
|
|||
*/
|
||||
PRInt32 GetScrollFlags() const;
|
||||
|
||||
private:
|
||||
EventInfo() {}
|
||||
protected:
|
||||
EventInfo() :
|
||||
mIsVertical(false), mIsPage(false), mDelta(0), mWnd(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
// TRUE if event is for vertical scroll. Otherwise, FALSE.
|
||||
bool mIsVertical;
|
||||
|
@ -85,8 +92,48 @@ public:
|
|||
bool mIsPage;
|
||||
// The native delta value.
|
||||
PRInt32 mDelta;
|
||||
// The window handle which is handling the event.
|
||||
HWND mWnd;
|
||||
// Timestamp of the event.
|
||||
TimeStamp mTimeStamp;
|
||||
};
|
||||
|
||||
class LastEventInfo : public EventInfo {
|
||||
public:
|
||||
LastEventInfo() :
|
||||
EventInfo(), mRemainingDeltaForScroll(0), mRemainingDeltaForPixel(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* CanContinueTransaction() checks whether the new event can continue the
|
||||
* last transaction or not. Note that if there is no transaction, this
|
||||
* returns true.
|
||||
*/
|
||||
bool CanContinueTransaction(const EventInfo& aNewEvent);
|
||||
|
||||
/**
|
||||
* ResetTransaction() resets the transaction, i.e., the instance forgets
|
||||
* the last event information.
|
||||
*/
|
||||
void ResetTransaction();
|
||||
|
||||
/**
|
||||
* RecordEvent() saves the information of new event.
|
||||
*/
|
||||
void RecordEvent(const EventInfo& aEvent);
|
||||
|
||||
// The remaining native delta value (i.e., not handled by previous
|
||||
// message handler).
|
||||
PRInt32 mRemainingDeltaForScroll;
|
||||
PRInt32 mRemainingDeltaForPixel;
|
||||
};
|
||||
|
||||
LastEventInfo& GetLastEventInfo() { return mLastEventInfo; }
|
||||
|
||||
private:
|
||||
LastEventInfo mLastEventInfo;
|
||||
|
||||
public:
|
||||
class SystemSettings {
|
||||
public:
|
||||
|
|
|
@ -286,16 +286,6 @@ PRUint32 nsWindow::sOOPPPluginFocusEvent =
|
|||
|
||||
MSG nsWindow::sRedirectedKeyDown;
|
||||
|
||||
bool nsWindow::sNeedsToInitMouseWheelSettings = true;
|
||||
|
||||
HWND nsWindow::sLastMouseWheelWnd = NULL;
|
||||
PRInt32 nsWindow::sRemainingDeltaForScroll = 0;
|
||||
PRInt32 nsWindow::sRemainingDeltaForPixel = 0;
|
||||
bool nsWindow::sLastMouseWheelDeltaIsPositive = false;
|
||||
bool nsWindow::sLastMouseWheelOrientationIsVertical = false;
|
||||
bool nsWindow::sLastMouseWheelUnitIsPage = false;
|
||||
PRUint32 nsWindow::sLastMouseWheelTime = 0;
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* SECTION: globals variables
|
||||
|
@ -5160,15 +5150,6 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
|
|||
}
|
||||
break;
|
||||
|
||||
case WM_SETTINGCHANGE:
|
||||
switch (wParam) {
|
||||
case SPI_SETWHEELSCROLLLINES:
|
||||
case SPI_SETWHEELSCROLLCHARS:
|
||||
sNeedsToInitMouseWheelSettings = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_INPUTLANGCHANGEREQUEST:
|
||||
*aRetValue = TRUE;
|
||||
result = false;
|
||||
|
@ -6277,25 +6258,6 @@ bool nsWindow::OnGesture(WPARAM wParam, LPARAM lParam)
|
|||
return true; // Handled
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsWindow::InitMouseWheelScrollData()
|
||||
{
|
||||
if (!sNeedsToInitMouseWheelSettings) {
|
||||
return;
|
||||
}
|
||||
sNeedsToInitMouseWheelSettings = false;
|
||||
ResetRemainingWheelDelta();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsWindow::ResetRemainingWheelDelta()
|
||||
{
|
||||
sRemainingDeltaForPixel = 0;
|
||||
sRemainingDeltaForScroll = 0;
|
||||
sLastMouseWheelWnd = NULL;
|
||||
}
|
||||
|
||||
static PRInt32 RoundDelta(double aDelta)
|
||||
{
|
||||
return aDelta >= 0 ? (PRInt32)floor(aDelta) : (PRInt32)ceil(aDelta);
|
||||
|
@ -6310,32 +6272,25 @@ void
|
|||
nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
|
||||
LRESULT *aRetValue)
|
||||
{
|
||||
InitMouseWheelScrollData();
|
||||
|
||||
MouseScrollHandler::EventInfo eventInfo(aMessage, aWParam, aLParam);
|
||||
MouseScrollHandler* handler = MouseScrollHandler::GetInstance();
|
||||
MouseScrollHandler::EventInfo eventInfo(this, aMessage, aWParam, aLParam);
|
||||
if (!eventInfo.CanDispatchMouseScrollEvent()) {
|
||||
ResetRemainingWheelDelta();
|
||||
handler->GetLastEventInfo().ResetTransaction();
|
||||
*aRetValue = eventInfo.ComputeMessageResult(false);
|
||||
return;
|
||||
}
|
||||
|
||||
MouseScrollHandler::LastEventInfo& lastEventInfo =
|
||||
handler->GetLastEventInfo();
|
||||
|
||||
// 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 != eventInfo.IsPositive() ||
|
||||
sLastMouseWheelOrientationIsVertical != eventInfo.IsVertical() ||
|
||||
sLastMouseWheelUnitIsPage != eventInfo.IsPage() ||
|
||||
now - sLastMouseWheelTime > 1500)) {
|
||||
ResetRemainingWheelDelta();
|
||||
if (!lastEventInfo.CanContinueTransaction(eventInfo)) {
|
||||
lastEventInfo.ResetTransaction();
|
||||
}
|
||||
sLastMouseWheelWnd = mWnd;
|
||||
sLastMouseWheelDeltaIsPositive = eventInfo.IsPositive();
|
||||
sLastMouseWheelOrientationIsVertical = eventInfo.IsVertical();
|
||||
sLastMouseWheelUnitIsPage = eventInfo.IsPage();
|
||||
sLastMouseWheelTime = now;
|
||||
|
||||
lastEventInfo.RecordEvent(eventInfo);
|
||||
|
||||
// means we process this message
|
||||
*aRetValue = eventInfo.ComputeMessageResult(true);
|
||||
|
@ -6386,8 +6341,8 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
|
|||
testEvent.isAlt = scrollEvent.isAlt;
|
||||
|
||||
testEvent.delta = computedScrollAmount;
|
||||
if ((eventInfo.IsVertical() && sLastMouseWheelDeltaIsPositive) ||
|
||||
(!eventInfo.IsVertical() && !sLastMouseWheelDeltaIsPositive)) {
|
||||
if ((eventInfo.IsVertical() && eventInfo.IsPositive()) ||
|
||||
(!eventInfo.IsVertical() && !eventInfo.IsPositive())) {
|
||||
testEvent.delta *= -1;
|
||||
}
|
||||
nsQueryContentEvent queryEvent(true, NS_QUERY_SCROLL_TARGET_INFO, this);
|
||||
|
@ -6429,14 +6384,15 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
|
|||
scrollEvent.scrollFlags |= eventInfo.GetScrollFlags();
|
||||
|
||||
PRInt32 nativeDeltaForScroll =
|
||||
eventInfo.GetNativeDelta() + sRemainingDeltaForScroll;
|
||||
eventInfo.GetNativeDelta() + lastEventInfo.mRemainingDeltaForScroll;
|
||||
|
||||
// NOTE: Don't use computedScrollAmount for computing the delta value of
|
||||
// line/page scroll event. The value will be recomputed in ESM.
|
||||
if (eventInfo.IsPage()) {
|
||||
scrollEvent.delta = nativeDeltaForScroll * orienter / WHEEL_DELTA;
|
||||
PRInt32 recomputedNativeDelta = scrollEvent.delta * orienter / WHEEL_DELTA;
|
||||
sRemainingDeltaForScroll = nativeDeltaForScroll - recomputedNativeDelta;
|
||||
lastEventInfo.mRemainingDeltaForScroll =
|
||||
nativeDeltaForScroll - recomputedNativeDelta;
|
||||
} else {
|
||||
double deltaPerUnit;
|
||||
deltaPerUnit =
|
||||
|
@ -6445,20 +6401,21 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
|
|||
RoundDelta((double)nativeDeltaForScroll * orienter / deltaPerUnit);
|
||||
PRInt32 recomputedNativeDelta =
|
||||
(PRInt32)(scrollEvent.delta * orienter * deltaPerUnit);
|
||||
sRemainingDeltaForScroll = nativeDeltaForScroll - recomputedNativeDelta;
|
||||
lastEventInfo.mRemainingDeltaForScroll =
|
||||
nativeDeltaForScroll - recomputedNativeDelta;
|
||||
}
|
||||
|
||||
if (scrollEvent.delta) {
|
||||
DispatchWindowEvent(&scrollEvent);
|
||||
if (mOnDestroyCalled) {
|
||||
ResetRemainingWheelDelta();
|
||||
lastEventInfo.ResetTransaction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If the query event failed, we cannot send pixel events.
|
||||
if (!dispatchPixelScrollEvent) {
|
||||
sRemainingDeltaForPixel = 0;
|
||||
lastEventInfo.mRemainingDeltaForPixel = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6477,7 +6434,7 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
|
|||
pixelEvent.isAlt = scrollEvent.isAlt;
|
||||
|
||||
PRInt32 nativeDeltaForPixel =
|
||||
eventInfo.GetNativeDelta() + sRemainingDeltaForPixel;
|
||||
eventInfo.GetNativeDelta() + lastEventInfo.mRemainingDeltaForPixel;
|
||||
// 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;
|
||||
|
@ -6488,7 +6445,8 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
|
|||
RoundDelta((double)nativeDeltaForPixel * orienterForPixel / deltaPerPixel);
|
||||
PRInt32 recomputedNativeDelta =
|
||||
(PRInt32)(pixelEvent.delta * orienterForPixel * deltaPerPixel);
|
||||
sRemainingDeltaForPixel = nativeDeltaForPixel - recomputedNativeDelta;
|
||||
lastEventInfo.mRemainingDeltaForPixel =
|
||||
nativeDeltaForPixel - recomputedNativeDelta;
|
||||
if (pixelEvent.delta != 0) {
|
||||
DispatchWindowEvent(&pixelEvent);
|
||||
}
|
||||
|
|
|
@ -604,15 +604,6 @@ protected:
|
|||
static bool sNeedsToInitMouseWheelSettings;
|
||||
static void InitMouseWheelScrollData();
|
||||
|
||||
static HWND sLastMouseWheelWnd;
|
||||
static PRInt32 sRemainingDeltaForScroll;
|
||||
static PRInt32 sRemainingDeltaForPixel;
|
||||
static bool sLastMouseWheelDeltaIsPositive;
|
||||
static bool sLastMouseWheelOrientationIsVertical;
|
||||
static bool sLastMouseWheelUnitIsPage;
|
||||
static PRUint32 sLastMouseWheelTime; // in milliseconds
|
||||
static void ResetRemainingWheelDelta();
|
||||
|
||||
// If a window receives WM_KEYDOWN message or WM_SYSKEYDOWM message which is
|
||||
// redirected message, OnKeyDowm() prevents to dispatch NS_KEY_DOWN event
|
||||
// because it has been dispatched before the message was redirected.
|
||||
|
|
Загрузка…
Ссылка в новой задаче