mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 868648: Make window overlay scrollbars appear/disappear when 2 fingers down/up trackpad. Credits to Markus for his help getting this right. r=mstange,masayuki,smichaud
This commit is contained in:
parent
8e7e13c21d
commit
9ded7a778d
@ -269,6 +269,56 @@ struct DeltaValues
|
||||
double deltaY;
|
||||
};
|
||||
|
||||
/******************************************************************/
|
||||
/* nsScrollbarsForWheel */
|
||||
/******************************************************************/
|
||||
|
||||
class nsScrollbarsForWheel {
|
||||
public:
|
||||
static void PrepareToScrollText(nsEventStateManager* aESM,
|
||||
nsIFrame* aTargetFrame,
|
||||
WheelEvent* aEvent);
|
||||
static void SetActiveScrollTarget(nsIScrollableFrame* aScrollTarget);
|
||||
// Hide all scrollbars (both mActiveOwner's and mActivatedScrollTargets')
|
||||
static void MayInactivate();
|
||||
static void Inactivate();
|
||||
static bool IsActive();
|
||||
static void OwnWheelTransaction(bool aOwn);
|
||||
|
||||
protected:
|
||||
static const size_t kNumberOfTargets = 4;
|
||||
static const DeltaValues directions[kNumberOfTargets];
|
||||
static nsWeakFrame sActiveOwner;
|
||||
static nsWeakFrame sActivatedScrollTargets[kNumberOfTargets];
|
||||
static bool sHadWheelStart;
|
||||
static bool sOwnWheelTransaction;
|
||||
|
||||
|
||||
/**
|
||||
* These two methods are called upon NS_WHEEL_START/NS_WHEEL_STOP events
|
||||
* to show/hide the right scrollbars.
|
||||
*/
|
||||
static void TemporarilyActivateAllPossibleScrollTargets(
|
||||
nsEventStateManager* aESM,
|
||||
nsIFrame* aTargetFrame,
|
||||
WheelEvent* aEvent);
|
||||
static void DeactivateAllTemporarilyActivatedScrollTargets();
|
||||
};
|
||||
|
||||
const DeltaValues nsScrollbarsForWheel::directions[kNumberOfTargets] = {
|
||||
DeltaValues(-1, 0), DeltaValues(+1, 0), DeltaValues(0, -1), DeltaValues(0, +1)
|
||||
};
|
||||
nsWeakFrame nsScrollbarsForWheel::sActiveOwner = nullptr;
|
||||
nsWeakFrame nsScrollbarsForWheel::sActivatedScrollTargets[kNumberOfTargets] = {
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
bool nsScrollbarsForWheel::sHadWheelStart = false;
|
||||
bool nsScrollbarsForWheel::sOwnWheelTransaction = false;
|
||||
|
||||
/******************************************************************/
|
||||
/* nsMouseWheelTransaction */
|
||||
/******************************************************************/
|
||||
|
||||
class nsMouseWheelTransaction {
|
||||
public:
|
||||
static nsIFrame* GetTargetFrame() { return sTargetFrame; }
|
||||
@ -277,11 +327,13 @@ public:
|
||||
// Be careful, UpdateTransaction may fire a DOM event, therefore, the target
|
||||
// frame might be destroyed in the event handler.
|
||||
static bool UpdateTransaction(WheelEvent* aEvent);
|
||||
static void MayEndTransaction();
|
||||
static void EndTransaction();
|
||||
static void OnEvent(WidgetEvent* aEvent);
|
||||
static void Shutdown();
|
||||
static uint32_t GetTimeoutTime();
|
||||
|
||||
static void OwnScrollbars(bool aOwn);
|
||||
|
||||
static DeltaValues AccelerateWheelDelta(WheelEvent* aEvent,
|
||||
bool aAllowScrollSpeedOverride);
|
||||
@ -299,12 +351,14 @@ protected:
|
||||
static int32_t GetAccelerationFactor();
|
||||
static DeltaValues OverrideSystemScrollSpeed(WheelEvent* aEvent);
|
||||
static double ComputeAcceleratedWheelDelta(double aDelta, int32_t aFactor);
|
||||
static bool OutOfTime(uint32_t aBaseTime, uint32_t aThreshold);
|
||||
|
||||
static nsWeakFrame sTargetFrame;
|
||||
static uint32_t sTime; // in milliseconds
|
||||
static uint32_t sMouseMoved; // in milliseconds
|
||||
static nsITimer* sTimer;
|
||||
static int32_t sScrollSeriesCounter;
|
||||
static bool sOwnScrollbars;
|
||||
};
|
||||
|
||||
nsWeakFrame nsMouseWheelTransaction::sTargetFrame(nullptr);
|
||||
@ -312,13 +366,7 @@ uint32_t nsMouseWheelTransaction::sTime = 0;
|
||||
uint32_t nsMouseWheelTransaction::sMouseMoved = 0;
|
||||
nsITimer* nsMouseWheelTransaction::sTimer = nullptr;
|
||||
int32_t nsMouseWheelTransaction::sScrollSeriesCounter = 0;
|
||||
|
||||
static bool
|
||||
OutOfTime(uint32_t aBaseTime, uint32_t aThreshold)
|
||||
{
|
||||
uint32_t now = PR_IntervalToMilliseconds(PR_IntervalNow());
|
||||
return (now - aBaseTime > aThreshold);
|
||||
}
|
||||
bool nsMouseWheelTransaction::sOwnScrollbars = false;
|
||||
|
||||
static bool
|
||||
CanScrollInRange(nscoord aMin, nscoord aValue, nscoord aMax, double aDirection)
|
||||
@ -328,20 +376,33 @@ CanScrollInRange(nscoord aMin, nscoord aValue, nscoord aMax, double aDirection)
|
||||
}
|
||||
|
||||
static bool
|
||||
CanScrollOn(nsIScrollableFrame* aScrollFrame, double aDeltaX, double aDeltaY)
|
||||
CanScrollOn(nsIScrollableFrame* aScrollFrame, double aDirectionX, double aDirectionY)
|
||||
{
|
||||
MOZ_ASSERT(aScrollFrame);
|
||||
NS_ASSERTION(aDeltaX || aDeltaY,
|
||||
NS_ASSERTION(aDirectionX || aDirectionY,
|
||||
"One of the delta values must be non-zero at least");
|
||||
|
||||
nsPoint scrollPt = aScrollFrame->GetScrollPosition();
|
||||
nsRect scrollRange = aScrollFrame->GetScrollRange();
|
||||
uint32_t directions = aScrollFrame->GetPerceivedScrollingDirections();
|
||||
|
||||
return (aDeltaX && (directions & nsIScrollableFrame::HORIZONTAL) &&
|
||||
CanScrollInRange(scrollRange.x, scrollPt.x, scrollRange.XMost(), aDeltaX)) ||
|
||||
(aDeltaY && (directions & nsIScrollableFrame::VERTICAL) &&
|
||||
CanScrollInRange(scrollRange.y, scrollPt.y, scrollRange.YMost(), aDeltaY));
|
||||
return (aDirectionX && (directions & nsIScrollableFrame::HORIZONTAL) &&
|
||||
CanScrollInRange(scrollRange.x, scrollPt.x, scrollRange.XMost(), aDirectionX)) ||
|
||||
(aDirectionY && (directions & nsIScrollableFrame::VERTICAL) &&
|
||||
CanScrollInRange(scrollRange.y, scrollPt.y, scrollRange.YMost(), aDirectionY));
|
||||
}
|
||||
|
||||
bool
|
||||
nsMouseWheelTransaction::OutOfTime(uint32_t aBaseTime, uint32_t aThreshold)
|
||||
{
|
||||
uint32_t now = PR_IntervalToMilliseconds(PR_IntervalNow());
|
||||
return (now - aBaseTime > aThreshold);
|
||||
}
|
||||
|
||||
void
|
||||
nsMouseWheelTransaction::OwnScrollbars(bool aOwn)
|
||||
{
|
||||
sOwnScrollbars = aOwn;
|
||||
}
|
||||
|
||||
void
|
||||
@ -349,6 +410,9 @@ nsMouseWheelTransaction::BeginTransaction(nsIFrame* aTargetFrame,
|
||||
WheelEvent* aEvent)
|
||||
{
|
||||
NS_ASSERTION(!sTargetFrame, "previous transaction is not finished!");
|
||||
MOZ_ASSERT(aEvent->message == NS_WHEEL_WHEEL,
|
||||
"Transaction must be started with a wheel event");
|
||||
nsScrollbarsForWheel::OwnWheelTransaction(false);
|
||||
sTargetFrame = aTargetFrame;
|
||||
sScrollSeriesCounter = 0;
|
||||
if (!UpdateTransaction(aEvent)) {
|
||||
@ -385,6 +449,16 @@ nsMouseWheelTransaction::UpdateTransaction(WheelEvent* aEvent)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsMouseWheelTransaction::MayEndTransaction()
|
||||
{
|
||||
if (!sOwnScrollbars && nsScrollbarsForWheel::IsActive()) {
|
||||
nsScrollbarsForWheel::OwnWheelTransaction(true);
|
||||
} else {
|
||||
EndTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsMouseWheelTransaction::EndTransaction()
|
||||
{
|
||||
@ -392,6 +466,11 @@ nsMouseWheelTransaction::EndTransaction()
|
||||
sTimer->Cancel();
|
||||
sTargetFrame = nullptr;
|
||||
sScrollSeriesCounter = 0;
|
||||
if (sOwnScrollbars) {
|
||||
sOwnScrollbars = false;
|
||||
nsScrollbarsForWheel::OwnWheelTransaction(false);
|
||||
nsScrollbarsForWheel::Inactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -415,7 +494,7 @@ nsMouseWheelTransaction::OnEvent(WidgetEvent* aEvent)
|
||||
OutOfTime(sMouseMoved, GetIgnoreMoveDelayTime())) {
|
||||
// Terminate the current mousewheel transaction if the mouse moved more
|
||||
// than ignoremovedelay milliseconds ago
|
||||
EndTransaction();
|
||||
MayEndTransaction();
|
||||
}
|
||||
return;
|
||||
case NS_MOUSE_MOVE:
|
||||
@ -426,7 +505,7 @@ nsMouseWheelTransaction::OnEvent(WidgetEvent* aEvent)
|
||||
nsIntPoint pt = GetScreenPoint(static_cast<WidgetGUIEvent*>(aEvent));
|
||||
nsIntRect r = sTargetFrame->GetScreenRectExternal();
|
||||
if (!r.Contains(pt)) {
|
||||
EndTransaction();
|
||||
MayEndTransaction();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -475,9 +554,10 @@ nsMouseWheelTransaction::OnFailToScrollTarget()
|
||||
}
|
||||
// The target frame might be destroyed in the event handler, at that time,
|
||||
// we need to finish the current transaction
|
||||
if (!sTargetFrame)
|
||||
if (!sTargetFrame) {
|
||||
EndTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsMouseWheelTransaction::OnTimeout(nsITimer* aTimer, void* aClosure)
|
||||
@ -491,7 +571,7 @@ nsMouseWheelTransaction::OnTimeout(nsITimer* aTimer, void* aClosure)
|
||||
nsIFrame* frame = sTargetFrame;
|
||||
// We need to finish current transaction before DOM event firing. Because
|
||||
// the next DOM event might create strange situation for us.
|
||||
EndTransaction();
|
||||
MayEndTransaction();
|
||||
|
||||
if (Preferences::GetBool("test.mousescroll", false)) {
|
||||
// This event is used for automated tests, see bug 442774.
|
||||
@ -625,6 +705,127 @@ nsMouseWheelTransaction::OverrideSystemScrollSpeed(WheelEvent* aEvent)
|
||||
return NS_FAILED(rv) ? DeltaValues(aEvent) : overriddenDeltaValues;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* nsScrollbarsForWheel */
|
||||
/******************************************************************/
|
||||
|
||||
void
|
||||
nsScrollbarsForWheel::PrepareToScrollText(
|
||||
nsEventStateManager* aESM,
|
||||
nsIFrame* aTargetFrame,
|
||||
WheelEvent* aEvent)
|
||||
{
|
||||
if (aEvent->message == NS_WHEEL_START) {
|
||||
nsMouseWheelTransaction::OwnScrollbars(false);
|
||||
if (!IsActive()) {
|
||||
TemporarilyActivateAllPossibleScrollTargets(aESM, aTargetFrame, aEvent);
|
||||
sHadWheelStart = true;
|
||||
}
|
||||
} else {
|
||||
DeactivateAllTemporarilyActivatedScrollTargets();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarsForWheel::SetActiveScrollTarget(nsIScrollableFrame* aScrollTarget)
|
||||
{
|
||||
if (!sHadWheelStart) {
|
||||
return;
|
||||
}
|
||||
nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(aScrollTarget);
|
||||
if (!scrollbarOwner) {
|
||||
return;
|
||||
}
|
||||
sHadWheelStart = false;
|
||||
sActiveOwner = do_QueryFrame(aScrollTarget);
|
||||
scrollbarOwner->ScrollbarActivityStarted();
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarsForWheel::MayInactivate()
|
||||
{
|
||||
if (!sOwnWheelTransaction && nsMouseWheelTransaction::GetTargetFrame()) {
|
||||
nsMouseWheelTransaction::OwnScrollbars(true);
|
||||
} else {
|
||||
Inactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarsForWheel::Inactivate()
|
||||
{
|
||||
nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sActiveOwner);
|
||||
if (scrollbarOwner) {
|
||||
scrollbarOwner->ScrollbarActivityStopped();
|
||||
}
|
||||
sActiveOwner = nullptr;
|
||||
DeactivateAllTemporarilyActivatedScrollTargets();
|
||||
if (sOwnWheelTransaction) {
|
||||
sOwnWheelTransaction = false;
|
||||
nsMouseWheelTransaction::OwnScrollbars(false);
|
||||
nsMouseWheelTransaction::EndTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsScrollbarsForWheel::IsActive()
|
||||
{
|
||||
if (sActiveOwner) {
|
||||
return true;
|
||||
}
|
||||
for (size_t i = 0; i < kNumberOfTargets; ++i) {
|
||||
if (sActivatedScrollTargets[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarsForWheel::OwnWheelTransaction(bool aOwn)
|
||||
{
|
||||
sOwnWheelTransaction = aOwn;
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarsForWheel::TemporarilyActivateAllPossibleScrollTargets(
|
||||
nsEventStateManager* aESM,
|
||||
nsIFrame* aTargetFrame,
|
||||
WheelEvent* aEvent)
|
||||
{
|
||||
for (size_t i = 0; i < kNumberOfTargets; i++) {
|
||||
const DeltaValues *dir = &directions[i];
|
||||
nsWeakFrame* scrollTarget = &sActivatedScrollTargets[i];
|
||||
MOZ_ASSERT(!*scrollTarget, "scroll target still temporarily activated!");
|
||||
nsIScrollableFrame* target =
|
||||
aESM->ComputeScrollTarget(aTargetFrame, dir->deltaX, dir->deltaY, aEvent,
|
||||
nsEventStateManager::COMPUTE_DEFAULT_ACTION_TARGET);
|
||||
if (target) {
|
||||
nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(target);
|
||||
if (scrollbarOwner) {
|
||||
nsIFrame* targetFrame = do_QueryFrame(target);
|
||||
*scrollTarget = targetFrame;
|
||||
scrollbarOwner->ScrollbarActivityStarted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarsForWheel::DeactivateAllTemporarilyActivatedScrollTargets()
|
||||
{
|
||||
for (size_t i = 0; i < kNumberOfTargets; i++) {
|
||||
nsWeakFrame* scrollTarget = &sActivatedScrollTargets[i];
|
||||
if (*scrollTarget) {
|
||||
nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(*scrollTarget);
|
||||
if (scrollbarOwner) {
|
||||
scrollbarOwner->ScrollbarActivityStopped();
|
||||
}
|
||||
*scrollTarget = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* nsEventStateManager */
|
||||
/******************************************************************/
|
||||
@ -977,13 +1178,20 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
break;
|
||||
case NS_WHEEL_WHEEL:
|
||||
case NS_WHEEL_START:
|
||||
case NS_WHEEL_STOP:
|
||||
{
|
||||
NS_ASSERTION(aEvent->mFlags.mIsTrusted,
|
||||
"Untrusted wheel event shouldn't be here");
|
||||
|
||||
nsIContent* content = GetFocusedContent();
|
||||
if (content)
|
||||
if (content) {
|
||||
mCurrentTargetContent = content;
|
||||
}
|
||||
|
||||
if (aEvent->message != NS_WHEEL_WHEEL) {
|
||||
break;
|
||||
}
|
||||
|
||||
WheelEvent* wheelEvent = static_cast<WheelEvent*>(aEvent);
|
||||
WheelPrefs::GetInstance()->ApplyUserPrefsToDelta(wheelEvent);
|
||||
@ -2545,6 +2753,20 @@ nsIScrollableFrame*
|
||||
nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
||||
WheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions)
|
||||
{
|
||||
return ComputeScrollTarget(aTargetFrame, aEvent->deltaX, aEvent->deltaY,
|
||||
aEvent, aOptions);
|
||||
}
|
||||
|
||||
// Overload ComputeScrollTarget method to allow passing "test" dx and dy when looking
|
||||
// for which scrollbarowners to activate when two finger down on trackpad
|
||||
// and before any actual motion
|
||||
nsIScrollableFrame*
|
||||
nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
||||
double aDirectionX,
|
||||
double aDirectionY,
|
||||
WheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions)
|
||||
{
|
||||
if (aOptions & PREFER_MOUSE_WHEEL_TRANSACTION) {
|
||||
// If the user recently scrolled with the mousewheel, then they probably
|
||||
@ -2569,14 +2791,14 @@ nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
||||
// If the event doesn't cause scroll actually, we cannot find scroll target
|
||||
// because we check if the event can cause scroll actually on each found
|
||||
// scrollable frame.
|
||||
if (!aEvent->deltaX && !aEvent->deltaY) {
|
||||
if (!aDirectionX && !aDirectionY) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool checkIfScrollableX =
|
||||
aEvent->deltaX && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS);
|
||||
aDirectionX && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS);
|
||||
bool checkIfScrollableY =
|
||||
aEvent->deltaY && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS);
|
||||
aDirectionY && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS);
|
||||
|
||||
nsIScrollableFrame* frameToScroll = nullptr;
|
||||
nsIFrame* scrollFrame =
|
||||
@ -2604,8 +2826,7 @@ nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
||||
|
||||
// For default action, we should climb up the tree if cannot scroll it
|
||||
// by the event actually.
|
||||
bool canScroll = CanScrollOn(frameToScroll,
|
||||
aEvent->deltaX, aEvent->deltaY);
|
||||
bool canScroll = CanScrollOn(frameToScroll, aDirectionX, aDirectionY);
|
||||
// Comboboxes need special care.
|
||||
nsIComboboxControlFrame* comboBox = do_QueryFrame(scrollFrame);
|
||||
if (comboBox) {
|
||||
@ -3170,25 +3391,41 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NS_WHEEL_STOP:
|
||||
{
|
||||
MOZ_ASSERT(aEvent->mFlags.mIsTrusted);
|
||||
nsScrollbarsForWheel::MayInactivate();
|
||||
}
|
||||
break;
|
||||
case NS_WHEEL_WHEEL:
|
||||
case NS_WHEEL_START:
|
||||
{
|
||||
MOZ_ASSERT(aEvent->mFlags.mIsTrusted);
|
||||
|
||||
if (*aStatus == nsEventStatus_eConsumeNoDefault) {
|
||||
nsScrollbarsForWheel::Inactivate();
|
||||
break;
|
||||
}
|
||||
|
||||
WheelEvent* wheelEvent = static_cast<WheelEvent*>(aEvent);
|
||||
switch (WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent)) {
|
||||
case WheelPrefs::ACTION_SCROLL: {
|
||||
if (!wheelEvent->deltaX && !wheelEvent->deltaY) {
|
||||
break;
|
||||
}
|
||||
// For scrolling of default action, we should honor the mouse wheel
|
||||
// transaction.
|
||||
|
||||
nsScrollbarsForWheel::PrepareToScrollText(this, aTargetFrame, wheelEvent);
|
||||
|
||||
if (aEvent->message != NS_WHEEL_WHEEL ||
|
||||
(!wheelEvent->deltaX && !wheelEvent->deltaY)) {
|
||||
break;
|
||||
}
|
||||
|
||||
nsIScrollableFrame* scrollTarget =
|
||||
ComputeScrollTarget(aTargetFrame, wheelEvent,
|
||||
COMPUTE_DEFAULT_ACTION_TARGET);
|
||||
|
||||
nsScrollbarsForWheel::SetActiveScrollTarget(scrollTarget);
|
||||
|
||||
if (!scrollTarget) {
|
||||
wheelEvent->mViewPortIsOverscrolled = true;
|
||||
}
|
||||
@ -3200,6 +3437,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
DoScrollText(scrollTarget, wheelEvent);
|
||||
} else {
|
||||
nsMouseWheelTransaction::EndTransaction();
|
||||
nsScrollbarsForWheel::Inactivate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ class nsEventStateManager : public nsSupportsWeakReference,
|
||||
public nsIObserver
|
||||
{
|
||||
friend class nsMouseWheelTransaction;
|
||||
friend class nsScrollbarsForWheel;
|
||||
public:
|
||||
|
||||
typedef mozilla::TimeStamp TimeStamp;
|
||||
@ -557,6 +558,12 @@ protected:
|
||||
mozilla::WheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions);
|
||||
|
||||
nsIScrollableFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
|
||||
double aDirectionX,
|
||||
double aDirectionY,
|
||||
mozilla::WheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions);
|
||||
|
||||
/**
|
||||
* GetScrollAmount() returns the scroll amount in app uints of one line or
|
||||
* one page. If the wheel event scrolls a page, returns the page width and
|
||||
|
@ -77,6 +77,22 @@ nsHTMLScrollFrame::nsHTMLScrollFrame(nsIPresShell* aShell, nsStyleContext* aCont
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLScrollFrame::ScrollbarActivityStarted() const
|
||||
{
|
||||
if (mInner.mScrollbarActivity) {
|
||||
mInner.mScrollbarActivity->ActivityStarted();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLScrollFrame::ScrollbarActivityStopped() const
|
||||
{
|
||||
if (mInner.mScrollbarActivity) {
|
||||
mInner.mScrollbarActivity->ActivityStopped();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLScrollFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
||||
{
|
||||
@ -902,6 +918,22 @@ nsXULScrollFrame::nsXULScrollFrame(nsIPresShell* aShell, nsStyleContext* aContex
|
||||
mInner.mClipAllDescendants = aClipAllDescendants;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULScrollFrame::ScrollbarActivityStarted() const
|
||||
{
|
||||
if (mInner.mScrollbarActivity) {
|
||||
mInner.mScrollbarActivity->ActivityStarted();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsXULScrollFrame::ScrollbarActivityStopped() const
|
||||
{
|
||||
if (mInner.mScrollbarActivity) {
|
||||
mInner.mScrollbarActivity->ActivityStopped();
|
||||
}
|
||||
}
|
||||
|
||||
nsMargin
|
||||
nsGfxScrollFrameInner::GetDesiredScrollbarSizes(nsBoxLayoutState* aState)
|
||||
{
|
||||
|
@ -520,6 +520,9 @@ public:
|
||||
return mInner.GetScrollbarBox(aVertical);
|
||||
}
|
||||
|
||||
virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE;
|
||||
virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE;
|
||||
|
||||
// nsIScrollableFrame
|
||||
virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE {
|
||||
return mInner.GetScrolledFrame();
|
||||
@ -810,6 +813,9 @@ public:
|
||||
return mInner.GetScrollbarBox(aVertical);
|
||||
}
|
||||
|
||||
virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE;
|
||||
virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE;
|
||||
|
||||
// nsIScrollableFrame
|
||||
virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE {
|
||||
return mInner.GetScrolledFrame();
|
||||
|
@ -23,6 +23,13 @@ public:
|
||||
* if there is no such box.
|
||||
*/
|
||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) = 0;
|
||||
|
||||
/**
|
||||
* Show or hide scrollbars on 2 fingers touch.
|
||||
* Subclasses should call their ScrollbarActivity's corresponding methods.
|
||||
*/
|
||||
virtual void ScrollbarActivityStarted() const = 0;
|
||||
virtual void ScrollbarActivityStopped() const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -4495,6 +4495,22 @@ nsTreeBodyFrame::PostScrollEvent()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTreeBodyFrame::ScrollbarActivityStarted() const
|
||||
{
|
||||
if (mScrollbarActivity) {
|
||||
mScrollbarActivity->ActivityStarted();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTreeBodyFrame::ScrollbarActivityStopped() const
|
||||
{
|
||||
if (mScrollbarActivity) {
|
||||
mScrollbarActivity->ActivityStopped();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTreeBodyFrame::DetachImageListeners()
|
||||
{
|
||||
|
@ -465,6 +465,9 @@ protected:
|
||||
void PostScrollEvent();
|
||||
void FireScrollEvent();
|
||||
|
||||
virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE;
|
||||
virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Clear the pointer to this frame for all nsTreeImageListeners that were
|
||||
* created by this frame.
|
||||
|
@ -429,6 +429,8 @@ enum nsEventStructType
|
||||
|
||||
#define NS_WHEEL_EVENT_START 5400
|
||||
#define NS_WHEEL_WHEEL (NS_WHEEL_EVENT_START)
|
||||
#define NS_WHEEL_START (NS_WHEEL_EVENT_START + 1)
|
||||
#define NS_WHEEL_STOP (NS_WHEEL_EVENT_START + 2)
|
||||
|
||||
//System time is changed
|
||||
#define NS_MOZ_TIME_CHANGE_EVENT 5500
|
||||
|
@ -205,6 +205,12 @@ typedef NSInteger NSEventGestureAxis;
|
||||
#endif // #ifdef __LP64__
|
||||
#endif // #if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_8) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
|
||||
enum {
|
||||
NSEventPhaseMayBegin = 0x1 << 5
|
||||
};
|
||||
#endif // #if !defined(MAC_OS_X_VERSION_10_8) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
|
||||
|
||||
// Undocumented scrollPhase flag that lets us discern between real scrolls and
|
||||
// automatically firing momentum scroll events.
|
||||
@interface NSEvent (ScrollPhase)
|
||||
@ -252,6 +258,11 @@ typedef NSInteger NSEventGestureAxis;
|
||||
BOOL mPendingFullDisplay;
|
||||
BOOL mPendingDisplay;
|
||||
|
||||
// WheelStart/Stop events should always come in pairs. This BOOL records the
|
||||
// last received event so that, when we receive one of the events, we make sure
|
||||
// to send its pair event first, in case we didn't yet for any reason.
|
||||
BOOL mExpectingWheelStop;
|
||||
|
||||
// Holds our drag service across multiple drag calls. The reference to the
|
||||
// service is obtained when the mouse enters the view and is released when
|
||||
// the mouse exits or there is a drop. This prevents us from having to
|
||||
@ -355,6 +366,8 @@ typedef NSInteger NSEventGestureAxis;
|
||||
- (void)rotateWithEvent:(NSEvent *)anEvent;
|
||||
- (void)endGestureWithEvent:(NSEvent *)anEvent;
|
||||
|
||||
- (void)scrollWheel:(NSEvent *)anEvent;
|
||||
|
||||
// Helper function for Lion smart magnify events
|
||||
+ (BOOL)isLionSmartMagnifyEvent:(NSEvent*)anEvent;
|
||||
|
||||
|
@ -140,6 +140,8 @@ uint32_t nsChildView::sLastInputEventCount = 0;
|
||||
- (void)forceRefreshOpenGL;
|
||||
|
||||
// set up a gecko mouse event based on a cocoa mouse event
|
||||
- (void) convertCocoaMouseWheelEvent:(NSEvent*)aMouseEvent
|
||||
toGeckoEvent:(WidgetWheelEvent*)outWheelEvent;
|
||||
- (void) convertCocoaMouseEvent:(NSEvent*)aMouseEvent
|
||||
toGeckoEvent:(WidgetInputEvent*)outGeckoEvent;
|
||||
|
||||
@ -2777,6 +2779,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
#endif
|
||||
mPendingDisplay = NO;
|
||||
mBlockedLastMouseDown = NO;
|
||||
mExpectingWheelStop = NO;
|
||||
|
||||
mLastMouseDownEvent = nil;
|
||||
mClickThroughMouseDownEvent = nil;
|
||||
@ -4752,6 +4755,22 @@ static int32_t RoundUp(double aDouble)
|
||||
static_cast<int32_t>(ceil(aDouble));
|
||||
}
|
||||
|
||||
- (void)sendWheelStartOrStop:(uint32_t)msg forEvent:(NSEvent *)theEvent
|
||||
{
|
||||
WidgetWheelEvent wheelEvent(true, msg, mGeckoChild);
|
||||
[self convertCocoaMouseWheelEvent:theEvent toGeckoEvent:&wheelEvent];
|
||||
mExpectingWheelStop = (msg == NS_WHEEL_START);
|
||||
mGeckoChild->DispatchWindowEvent(wheelEvent);
|
||||
}
|
||||
|
||||
- (void)sendWheelCondition:(BOOL)condition first:(uint32_t)first second:(uint32_t)second forEvent:(NSEvent *)theEvent
|
||||
{
|
||||
if (mExpectingWheelStop == condition) {
|
||||
[self sendWheelStartOrStop:first forEvent:theEvent];
|
||||
}
|
||||
[self sendWheelStartOrStop:second forEvent:theEvent];
|
||||
}
|
||||
|
||||
- (void)scrollWheel:(NSEvent*)theEvent
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
@ -4768,25 +4787,23 @@ static int32_t RoundUp(double aDouble)
|
||||
return;
|
||||
}
|
||||
|
||||
WheelEvent wheelEvent(true, NS_WHEEL_WHEEL, mGeckoChild);
|
||||
[self convertCocoaMouseEvent:theEvent toGeckoEvent:&wheelEvent];
|
||||
wheelEvent.deltaMode =
|
||||
Preferences::GetBool("mousewheel.enable_pixel_scrolling", true) ?
|
||||
nsIDOMWheelEvent::DOM_DELTA_PIXEL : nsIDOMWheelEvent::DOM_DELTA_LINE;
|
||||
if (nsCocoaFeatures::OnLionOrLater()) {
|
||||
NSEventPhase phase = [theEvent phase];
|
||||
// Fire NS_WHEEL_START/STOP events when 2 fingers touch/release the touchpad.
|
||||
if (phase & NSEventPhaseMayBegin) {
|
||||
[self sendWheelCondition:YES first:NS_WHEEL_STOP second:NS_WHEEL_START forEvent:theEvent];
|
||||
return;
|
||||
}
|
||||
|
||||
// Calling deviceDeltaX or deviceDeltaY on theEvent will trigger a Cocoa
|
||||
// assertion and an Objective-C NSInternalInconsistencyException if the
|
||||
// underlying "Carbon" event doesn't contain pixel scrolling information.
|
||||
// For these events, carbonEventKind is kEventMouseWheelMoved instead of
|
||||
// kEventMouseScroll.
|
||||
if (wheelEvent.deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL) {
|
||||
EventRef theCarbonEvent = [theEvent _eventRef];
|
||||
UInt32 carbonEventKind = theCarbonEvent ? ::GetEventKind(theCarbonEvent) : 0;
|
||||
if (carbonEventKind != kEventMouseScroll) {
|
||||
wheelEvent.deltaMode = nsIDOMWheelEvent::DOM_DELTA_LINE;
|
||||
if (phase & (NSEventPhaseEnded | NSEventPhaseCancelled)) {
|
||||
[self sendWheelCondition:NO first:NS_WHEEL_START second:NS_WHEEL_STOP forEvent:theEvent];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, mGeckoChild);
|
||||
[self convertCocoaMouseWheelEvent:theEvent toGeckoEvent:&wheelEvent];
|
||||
|
||||
wheelEvent.lineOrPageDeltaX = RoundUp(-[theEvent deltaX]);
|
||||
wheelEvent.lineOrPageDeltaY = RoundUp(-[theEvent deltaY]);
|
||||
|
||||
@ -4817,8 +4834,6 @@ static int32_t RoundUp(double aDouble)
|
||||
return;
|
||||
}
|
||||
|
||||
wheelEvent.isMomentum = nsCocoaUtils::IsMomentumScrollEvent(theEvent);
|
||||
|
||||
NPCocoaEvent cocoaEvent;
|
||||
ChildViewMouseTracker::AttachPluginEvent(wheelEvent, self, theEvent,
|
||||
NPCocoaEventScrollWheel,
|
||||
@ -4907,6 +4922,29 @@ static int32_t RoundUp(double aDouble)
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void) convertCocoaMouseWheelEvent:(NSEvent*)aMouseEvent
|
||||
toGeckoEvent:(WidgetWheelEvent*)outWheelEvent
|
||||
{
|
||||
[self convertCocoaMouseEvent:aMouseEvent toGeckoEvent:outWheelEvent];
|
||||
outWheelEvent->deltaMode =
|
||||
Preferences::GetBool("mousewheel.enable_pixel_scrolling", true) ?
|
||||
nsIDOMWheelEvent::DOM_DELTA_PIXEL : nsIDOMWheelEvent::DOM_DELTA_LINE;
|
||||
|
||||
// Calling deviceDeltaX or deviceDeltaY on theEvent will trigger a Cocoa
|
||||
// assertion and an Objective-C NSInternalInconsistencyException if the
|
||||
// underlying "Carbon" event doesn't contain pixel scrolling information.
|
||||
// For these events, carbonEventKind is kEventMouseWheelMoved instead of
|
||||
// kEventMouseScroll.
|
||||
if (outWheelEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL) {
|
||||
EventRef theCarbonEvent = [aMouseEvent _eventRef];
|
||||
UInt32 carbonEventKind = theCarbonEvent ? ::GetEventKind(theCarbonEvent) : 0;
|
||||
if (carbonEventKind != kEventMouseScroll) {
|
||||
outWheelEvent->deltaMode = nsIDOMWheelEvent::DOM_DELTA_LINE;
|
||||
}
|
||||
}
|
||||
outWheelEvent->isMomentum = nsCocoaUtils::IsMomentumScrollEvent(aMouseEvent);
|
||||
}
|
||||
|
||||
- (void) convertCocoaMouseEvent:(NSEvent*)aMouseEvent
|
||||
toGeckoEvent:(WidgetInputEvent*)outGeckoEvent
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user