зеркало из https://github.com/mozilla/gecko-dev.git
Bug 462809 - Interpretation of scroll events on Windows and OS X, r=vladimir, ui-r=beltzner
This commit is contained in:
Родитель
cebdbd906e
Коммит
5fdabd8af3
|
@ -963,9 +963,16 @@ pref("mousewheel.transaction.ignoremovedelay", 100);
|
|||
// Macbook touchpad two finger pixel scrolling
|
||||
pref("mousewheel.enable_pixel_scrolling", true);
|
||||
|
||||
// prefs for improved windows scrolling model
|
||||
// number of mousewheel clicks when acceleration starts
|
||||
// acceleration can be turned off if pref is set to -1
|
||||
pref("mousewheel.acceleration.start", 3);
|
||||
// factor to be muliplied for constant acceleration
|
||||
pref("mousewheel.acceleration.factor", 10);
|
||||
|
||||
// 0=lines, 1=pages, 2=history , 3=text size
|
||||
pref("mousewheel.withnokey.action",0);
|
||||
pref("mousewheel.withnokey.numlines",1);
|
||||
pref("mousewheel.withnokey.numlines",6);
|
||||
pref("mousewheel.withnokey.sysnumlines",true);
|
||||
pref("mousewheel.withcontrolkey.action",0);
|
||||
pref("mousewheel.withcontrolkey.numlines",1);
|
||||
|
|
|
@ -120,7 +120,9 @@
|
|||
#include "nsIDOMNSUIEvent.h"
|
||||
#include "nsITheme.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "imgIContainer.h"
|
||||
|
@ -190,6 +192,105 @@
|
|||
|
||||
#include "nsWindowDefs.h"
|
||||
|
||||
// For scroll wheel calculations
|
||||
#include "nsITimer.h"
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* nsScrollPrefObserver Class for scroll acceleration prefs
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
class nsScrollPrefObserver : public nsIObserver
|
||||
{
|
||||
public:
|
||||
nsScrollPrefObserver();
|
||||
int GetScrollAccelerationStart();
|
||||
int GetScrollAccelerationFactor();
|
||||
int GetScrollNumLines();
|
||||
void RemoveObservers();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIPrefBranch2> mPrefBranch;
|
||||
int mScrollAccelerationStart;
|
||||
int mScrollAccelerationFactor;
|
||||
int mScrollNumLines;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsScrollPrefObserver, nsScrollPrefObserver)
|
||||
|
||||
nsScrollPrefObserver::nsScrollPrefObserver()
|
||||
{
|
||||
nsresult rv;
|
||||
mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
|
||||
rv = mPrefBranch->GetIntPref("mousewheel.acceleration.start",
|
||||
&mScrollAccelerationStart);
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Failed to get pref: mousewheel.acceleration.start");
|
||||
rv = mPrefBranch->AddObserver("mousewheel.acceleration.start",
|
||||
this, PR_FALSE);
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Failed to add pref observer: mousewheel.acceleration.start");
|
||||
|
||||
rv = mPrefBranch->GetIntPref("mousewheel.acceleration.factor",
|
||||
&mScrollAccelerationFactor);
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Failed to get pref: mousewheel.acceleration.factor");
|
||||
rv = mPrefBranch->AddObserver("mousewheel.acceleration.factor",
|
||||
this, PR_FALSE);
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Failed to add pref observer: mousewheel.acceleration.factor");
|
||||
|
||||
rv = mPrefBranch->GetIntPref("mousewheel.withnokey.numlines",
|
||||
&mScrollNumLines);
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Failed to get pref: mousewheel.withnokey.numlines");
|
||||
rv = mPrefBranch->AddObserver("mousewheel.withnokey.numlines",
|
||||
this, PR_FALSE);
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Failed to add pref observer: mousewheel.withnokey.numlines");
|
||||
}
|
||||
|
||||
int nsScrollPrefObserver::GetScrollAccelerationStart()
|
||||
{
|
||||
return mScrollAccelerationStart;
|
||||
}
|
||||
|
||||
int nsScrollPrefObserver::GetScrollAccelerationFactor()
|
||||
{
|
||||
return mScrollAccelerationFactor;
|
||||
}
|
||||
|
||||
int nsScrollPrefObserver::GetScrollNumLines()
|
||||
{
|
||||
return mScrollNumLines;
|
||||
}
|
||||
|
||||
void nsScrollPrefObserver::RemoveObservers()
|
||||
{
|
||||
mPrefBranch->RemoveObserver("mousewheel.acceleration.start", this);
|
||||
mPrefBranch->RemoveObserver("mousewheel.acceleration.factor", this);
|
||||
mPrefBranch->RemoveObserver("mousewheel.withnokey.numlines", this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPrefObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
mPrefBranch->GetIntPref("mousewheel.acceleration.start",
|
||||
&mScrollAccelerationStart);
|
||||
mPrefBranch->GetIntPref("mousewheel.acceleration.factor",
|
||||
&mScrollAccelerationFactor);
|
||||
mPrefBranch->GetIntPref("mousewheel.withnokey.numlines",
|
||||
&mScrollNumLines);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
**************************************************************
|
||||
**
|
||||
|
@ -291,6 +392,9 @@ static PRBool gWindowsVisible = PR_FALSE;
|
|||
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
|
||||
// Global scroll pref observer for scroll acceleration prefs
|
||||
static nsScrollPrefObserver* gScrollPrefObserver = nsnull;
|
||||
|
||||
/**************************************************************
|
||||
**************************************************************
|
||||
**
|
||||
|
@ -351,6 +455,9 @@ nsWindow::nsWindow() : nsBaseWidget()
|
|||
mBrush = ::CreateSolidBrush(NSRGB_2_COLOREF(mBackground));
|
||||
mForeground = ::GetSysColor(COLOR_WINDOWTEXT);
|
||||
|
||||
// To be used for scroll acceleration
|
||||
mScrollSeriesCounter = 0;
|
||||
|
||||
// Global initialization
|
||||
if (!sInstanceCount) {
|
||||
#if !defined(WINCE)
|
||||
|
@ -360,6 +467,9 @@ nsWindow::nsWindow() : nsBaseWidget()
|
|||
// Init IME handler
|
||||
nsIMM32Handler::Initialize();
|
||||
|
||||
// Init scroll pref observer for scroll acceleration
|
||||
NS_IF_ADDREF(gScrollPrefObserver = new nsScrollPrefObserver());
|
||||
|
||||
#ifdef NS_ENABLE_TSF
|
||||
nsTextStore::Initialize();
|
||||
#endif
|
||||
|
@ -410,6 +520,9 @@ nsWindow::~nsWindow()
|
|||
// delete any of the IME structures that we allocated
|
||||
nsIMM32Handler::Terminate();
|
||||
#endif // !defined(WINCE)
|
||||
|
||||
gScrollPrefObserver->RemoveObservers();
|
||||
NS_RELEASE(gScrollPrefObserver);
|
||||
}
|
||||
|
||||
#if !defined(WINCE)
|
||||
|
@ -4823,6 +4936,10 @@ PRBool nsWindow::OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam, PRBool& ge
|
|||
currentWindow = mWnd;
|
||||
}
|
||||
|
||||
// Keep track of whether or not the scroll notification is part of a series
|
||||
// in order to calculate appropriate acceleration effect
|
||||
UpdateMouseWheelSeriesCounter();
|
||||
|
||||
nsMouseScrollEvent scrollEvent(PR_TRUE, NS_MOUSE_SCROLL, this);
|
||||
scrollEvent.delta = 0;
|
||||
if (isVertical) {
|
||||
|
@ -4833,7 +4950,10 @@ PRBool nsWindow::OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam, PRBool& ge
|
|||
} else {
|
||||
currentVDelta -= (short) HIWORD (wParam);
|
||||
if (PR_ABS(currentVDelta) >= iDeltaPerLine) {
|
||||
scrollEvent.delta = currentVDelta / iDeltaPerLine;
|
||||
// Compute delta to create acceleration effect
|
||||
scrollEvent.delta = ComputeMouseWheelDelta(currentVDelta,
|
||||
iDeltaPerLine,
|
||||
ulScrollLines);
|
||||
currentVDelta %= iDeltaPerLine;
|
||||
}
|
||||
}
|
||||
|
@ -4870,6 +4990,64 @@ PRBool nsWindow::OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam, PRBool& ge
|
|||
|
||||
return PR_FALSE; // break;
|
||||
}
|
||||
|
||||
// Reset scrollSeriesCounter when timer finishes (scroll series has ended)
|
||||
void nsWindow::OnMouseWheelTimeout(nsITimer* aTimer, void* aClosure)
|
||||
{
|
||||
nsWindow* window = (nsWindow*) aClosure;
|
||||
window->mScrollSeriesCounter = 0;
|
||||
}
|
||||
|
||||
// Increment scrollSeriesCount and reset timer to keep count going
|
||||
void nsWindow::UpdateMouseWheelSeriesCounter()
|
||||
{
|
||||
mScrollSeriesCounter++;
|
||||
|
||||
int scrollSeriesTimeout = 80;
|
||||
static nsITimer* scrollTimer;
|
||||
if (!scrollTimer) {
|
||||
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (!timer)
|
||||
return;
|
||||
timer.swap(scrollTimer);
|
||||
}
|
||||
|
||||
scrollTimer->Cancel();
|
||||
nsresult rv =
|
||||
scrollTimer->InitWithFuncCallback(OnMouseWheelTimeout, this,
|
||||
scrollSeriesTimeout,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "nsITimer::InitWithFuncCallback failed");
|
||||
}
|
||||
|
||||
// If the scroll notification is part of a series of notifications we should
|
||||
// increase scollEvent.delta to create an acceleration effect
|
||||
int nsWindow::ComputeMouseWheelDelta(int currentVDelta,
|
||||
int iDeltaPerLine,
|
||||
ULONG ulScrollLines)
|
||||
{
|
||||
// scrollAccelerationStart: click number at which acceleration starts
|
||||
int scrollAccelerationStart = gScrollPrefObserver->GetScrollAccelerationStart();
|
||||
// scrollNumlines: number of lines per scroll before acceleration
|
||||
int scrollNumLines = gScrollPrefObserver->GetScrollNumLines();
|
||||
// scrollAccelerationFactor: factor muliplied for constant acceleration
|
||||
int scrollAccelerationFactor = gScrollPrefObserver->GetScrollAccelerationFactor();
|
||||
|
||||
// compute delta that obeys numlines pref
|
||||
int ulScrollLinesInt = static_cast<int>(ulScrollLines);
|
||||
// currentVDelta is a multiple of (iDeltaPerLine * ulScrollLinesInt)
|
||||
int delta = scrollNumLines * currentVDelta / (iDeltaPerLine * ulScrollLinesInt);
|
||||
|
||||
// mScrollSeriesCounter: the index of the scroll notification in a series
|
||||
if (mScrollSeriesCounter < scrollAccelerationStart ||
|
||||
scrollAccelerationStart < 0 ||
|
||||
scrollAccelerationFactor < 0)
|
||||
return delta;
|
||||
else
|
||||
return int(0.5 + delta * mScrollSeriesCounter *
|
||||
(double) scrollAccelerationFactor / 10);
|
||||
}
|
||||
|
||||
#endif // !defined(WINCE_WINDOWS_MOBILE)
|
||||
|
||||
static PRBool
|
||||
|
|
|
@ -325,6 +325,11 @@ protected:
|
|||
PRBool OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam,
|
||||
PRBool& result, PRBool& getWheelInfo,
|
||||
LRESULT *aRetValue);
|
||||
static void OnMouseWheelTimeout(nsITimer* aTimer, void* aClosure);
|
||||
void UpdateMouseWheelSeriesCounter();
|
||||
int ComputeMouseWheelDelta(int currentVDelta,
|
||||
int iDeltaPerLine,
|
||||
ULONG ulScrollLines);
|
||||
#endif // !defined(WINCE_WINDOWS_MOBILE)
|
||||
#if !defined(WINCE)
|
||||
void OnWindowPosChanging(LPWINDOWPOS& info);
|
||||
|
@ -430,6 +435,7 @@ protected:
|
|||
nsNativeDragTarget* mNativeDragTarget;
|
||||
HKL mLastKeyboardLayout;
|
||||
nsPopupType mPopupType;
|
||||
int mScrollSeriesCounter;
|
||||
|
||||
static PRUint32 sInstanceCount;
|
||||
static TriStateBool sCanQuit;
|
||||
|
|
Загрузка…
Ссылка в новой задаче