зеркало из https://github.com/mozilla/pjs.git
Bug 462809 - Interpretation of scroll events on Windows and OS X, r=vladimir, ui-r=beltzner
This commit is contained in:
Родитель
067320254c
Коммит
65444db3df
|
@ -963,9 +963,16 @@ pref("mousewheel.transaction.ignoremovedelay", 100);
|
||||||
// Macbook touchpad two finger pixel scrolling
|
// Macbook touchpad two finger pixel scrolling
|
||||||
pref("mousewheel.enable_pixel_scrolling", true);
|
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
|
// 0=lines, 1=pages, 2=history , 3=text size
|
||||||
pref("mousewheel.withnokey.action",0);
|
pref("mousewheel.withnokey.action",0);
|
||||||
pref("mousewheel.withnokey.numlines",1);
|
pref("mousewheel.withnokey.numlines",6);
|
||||||
pref("mousewheel.withnokey.sysnumlines",true);
|
pref("mousewheel.withnokey.sysnumlines",true);
|
||||||
pref("mousewheel.withcontrolkey.action",0);
|
pref("mousewheel.withcontrolkey.action",0);
|
||||||
pref("mousewheel.withcontrolkey.numlines",1);
|
pref("mousewheel.withcontrolkey.numlines",1);
|
||||||
|
|
|
@ -120,7 +120,9 @@
|
||||||
#include "nsIDOMNSUIEvent.h"
|
#include "nsIDOMNSUIEvent.h"
|
||||||
#include "nsITheme.h"
|
#include "nsITheme.h"
|
||||||
#include "nsIPrefBranch.h"
|
#include "nsIPrefBranch.h"
|
||||||
|
#include "nsIPrefBranch2.h"
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
|
#include "nsIObserver.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsIScreenManager.h"
|
#include "nsIScreenManager.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
|
@ -190,6 +192,105 @@
|
||||||
|
|
||||||
#include "nsWindowDefs.h"
|
#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);
|
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));
|
mBrush = ::CreateSolidBrush(NSRGB_2_COLOREF(mBackground));
|
||||||
mForeground = ::GetSysColor(COLOR_WINDOWTEXT);
|
mForeground = ::GetSysColor(COLOR_WINDOWTEXT);
|
||||||
|
|
||||||
|
// To be used for scroll acceleration
|
||||||
|
mScrollSeriesCounter = 0;
|
||||||
|
|
||||||
// Global initialization
|
// Global initialization
|
||||||
if (!sInstanceCount) {
|
if (!sInstanceCount) {
|
||||||
#if !defined(WINCE)
|
#if !defined(WINCE)
|
||||||
|
@ -360,6 +467,9 @@ nsWindow::nsWindow() : nsBaseWidget()
|
||||||
// Init IME handler
|
// Init IME handler
|
||||||
nsIMM32Handler::Initialize();
|
nsIMM32Handler::Initialize();
|
||||||
|
|
||||||
|
// Init scroll pref observer for scroll acceleration
|
||||||
|
NS_IF_ADDREF(gScrollPrefObserver = new nsScrollPrefObserver());
|
||||||
|
|
||||||
#ifdef NS_ENABLE_TSF
|
#ifdef NS_ENABLE_TSF
|
||||||
nsTextStore::Initialize();
|
nsTextStore::Initialize();
|
||||||
#endif
|
#endif
|
||||||
|
@ -410,6 +520,9 @@ nsWindow::~nsWindow()
|
||||||
// delete any of the IME structures that we allocated
|
// delete any of the IME structures that we allocated
|
||||||
nsIMM32Handler::Terminate();
|
nsIMM32Handler::Terminate();
|
||||||
#endif // !defined(WINCE)
|
#endif // !defined(WINCE)
|
||||||
|
|
||||||
|
gScrollPrefObserver->RemoveObservers();
|
||||||
|
NS_RELEASE(gScrollPrefObserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(WINCE)
|
#if !defined(WINCE)
|
||||||
|
@ -4823,6 +4936,10 @@ PRBool nsWindow::OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam, PRBool& ge
|
||||||
currentWindow = mWnd;
|
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);
|
nsMouseScrollEvent scrollEvent(PR_TRUE, NS_MOUSE_SCROLL, this);
|
||||||
scrollEvent.delta = 0;
|
scrollEvent.delta = 0;
|
||||||
if (isVertical) {
|
if (isVertical) {
|
||||||
|
@ -4833,7 +4950,10 @@ PRBool nsWindow::OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam, PRBool& ge
|
||||||
} else {
|
} else {
|
||||||
currentVDelta -= (short) HIWORD (wParam);
|
currentVDelta -= (short) HIWORD (wParam);
|
||||||
if (PR_ABS(currentVDelta) >= iDeltaPerLine) {
|
if (PR_ABS(currentVDelta) >= iDeltaPerLine) {
|
||||||
scrollEvent.delta = currentVDelta / iDeltaPerLine;
|
// Compute delta to create acceleration effect
|
||||||
|
scrollEvent.delta = ComputeMouseWheelDelta(currentVDelta,
|
||||||
|
iDeltaPerLine,
|
||||||
|
ulScrollLines);
|
||||||
currentVDelta %= iDeltaPerLine;
|
currentVDelta %= iDeltaPerLine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4870,6 +4990,64 @@ PRBool nsWindow::OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam, PRBool& ge
|
||||||
|
|
||||||
return PR_FALSE; // break;
|
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)
|
#endif // !defined(WINCE_WINDOWS_MOBILE)
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
|
|
|
@ -325,6 +325,11 @@ protected:
|
||||||
PRBool OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam,
|
PRBool OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam,
|
||||||
PRBool& result, PRBool& getWheelInfo,
|
PRBool& result, PRBool& getWheelInfo,
|
||||||
LRESULT *aRetValue);
|
LRESULT *aRetValue);
|
||||||
|
static void OnMouseWheelTimeout(nsITimer* aTimer, void* aClosure);
|
||||||
|
void UpdateMouseWheelSeriesCounter();
|
||||||
|
int ComputeMouseWheelDelta(int currentVDelta,
|
||||||
|
int iDeltaPerLine,
|
||||||
|
ULONG ulScrollLines);
|
||||||
#endif // !defined(WINCE_WINDOWS_MOBILE)
|
#endif // !defined(WINCE_WINDOWS_MOBILE)
|
||||||
#if !defined(WINCE)
|
#if !defined(WINCE)
|
||||||
void OnWindowPosChanging(LPWINDOWPOS& info);
|
void OnWindowPosChanging(LPWINDOWPOS& info);
|
||||||
|
@ -430,6 +435,7 @@ protected:
|
||||||
nsNativeDragTarget* mNativeDragTarget;
|
nsNativeDragTarget* mNativeDragTarget;
|
||||||
HKL mLastKeyboardLayout;
|
HKL mLastKeyboardLayout;
|
||||||
nsPopupType mPopupType;
|
nsPopupType mPopupType;
|
||||||
|
int mScrollSeriesCounter;
|
||||||
|
|
||||||
static PRUint32 sInstanceCount;
|
static PRUint32 sInstanceCount;
|
||||||
static TriStateBool sCanQuit;
|
static TriStateBool sCanQuit;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче