зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1358017 - Part 6: Implements the auto-dir scrolling feature(without the "honour root" functionality) in non-APZ r=masayuki
This commit implements the auto-dir scrolling functionality in non-APZ, based on part 1 to part 3. However, the functionality of mousewheel.autodir.honourroot is unimplemented in this commit. MozReview-Commit-ID: 2vYABOx4RkK --HG-- extra : rebase_source : 7dc45e6747a101c1a2c3a22bc695b2a0b2494b50
This commit is contained in:
Родитель
2bdc6774da
Коммит
891d6c4b37
|
@ -2332,8 +2332,8 @@ EventStateManager::DispatchLegacyMouseScrollEvents(nsIFrame* aTargetFrame,
|
|||
// Ignore mouse wheel transaction for computing legacy mouse wheel
|
||||
// events' delta value.
|
||||
nsIFrame* scrollFrame =
|
||||
ComputeScrollTarget(aTargetFrame, aEvent,
|
||||
COMPUTE_LEGACY_MOUSE_SCROLL_EVENT_TARGET);
|
||||
ComputeScrollTargetAndMayAdjustWheelEvent(
|
||||
aTargetFrame, aEvent, COMPUTE_LEGACY_MOUSE_SCROLL_EVENT_TARGET);
|
||||
|
||||
nsIScrollableFrame* scrollTarget = do_QueryFrame(scrollFrame);
|
||||
nsPresContext* pc =
|
||||
|
@ -2523,29 +2523,60 @@ EventStateManager::SendPixelScrollEvent(nsIFrame* aTargetFrame,
|
|||
}
|
||||
|
||||
nsIFrame*
|
||||
EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
||||
WidgetWheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions)
|
||||
EventStateManager::ComputeScrollTargetAndMayAdjustWheelEvent(
|
||||
nsIFrame* aTargetFrame,
|
||||
WidgetWheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions)
|
||||
{
|
||||
return ComputeScrollTarget(aTargetFrame, aEvent->mDeltaX, aEvent->mDeltaY,
|
||||
aEvent, aOptions);
|
||||
return ComputeScrollTargetAndMayAdjustWheelEvent(aTargetFrame,
|
||||
aEvent->mDeltaX,
|
||||
aEvent->mDeltaY,
|
||||
aEvent, aOptions);
|
||||
}
|
||||
|
||||
// Overload ComputeScrollTarget method to allow passing "test" dx and dy when looking
|
||||
// for which scrollbarmediators to activate when two finger down on trackpad
|
||||
// and before any actual motion
|
||||
// Overload ComputeScrollTargetAndMayAdjustWheelEvent method to allow passing
|
||||
// "test" dx and dy when looking for which scrollbarmediators to activate when
|
||||
// two finger down on trackpad and before any actual motion
|
||||
nsIFrame*
|
||||
EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
||||
double aDirectionX,
|
||||
double aDirectionY,
|
||||
WidgetWheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions)
|
||||
EventStateManager::ComputeScrollTargetAndMayAdjustWheelEvent(
|
||||
nsIFrame* aTargetFrame,
|
||||
double aDirectionX,
|
||||
double aDirectionY,
|
||||
WidgetWheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions)
|
||||
{
|
||||
if ((aOptions & INCLUDE_PLUGIN_AS_TARGET) &&
|
||||
!WheelPrefs::WheelEventsEnabledOnPlugins()) {
|
||||
aOptions = RemovePluginFromTarget(aOptions);
|
||||
}
|
||||
|
||||
bool isAutoDir = false;
|
||||
bool honoursRoot = false;
|
||||
if (MAY_BE_ADJUSTED_BY_AUTO_DIR & aOptions) {
|
||||
// If the scroll is respected as auto-dir, aDirection* should always be
|
||||
// equivalent to the event's delta vlaues(Currently, there are only one case
|
||||
// where aDirection*s have different values from the widget wheel event's
|
||||
// original delta values and the only case isn't auto-dir, see
|
||||
// ScrollbarsForWheel::TemporarilyActivateAllPossibleScrollTargets).
|
||||
MOZ_ASSERT(aDirectionX == aEvent->mDeltaX &&
|
||||
aDirectionY == aEvent->mDeltaY);
|
||||
|
||||
WheelDeltaAdjustmentStrategy strategy =
|
||||
GetWheelDeltaAdjustmentStrategy(*aEvent);
|
||||
switch (strategy) {
|
||||
case WheelDeltaAdjustmentStrategy::eAutoDir:
|
||||
isAutoDir = true;
|
||||
honoursRoot = false;
|
||||
break;
|
||||
case WheelDeltaAdjustmentStrategy::eAutoDirWithRootHonour:
|
||||
isAutoDir = true;
|
||||
honoursRoot = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (aOptions & PREFER_MOUSE_WHEEL_TRANSACTION) {
|
||||
// If the user recently scrolled with the mousewheel, then they probably
|
||||
// want to scroll the same view as before instead of the view under the
|
||||
|
@ -2570,6 +2601,16 @@ EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
|||
if (scrollableFrame) {
|
||||
nsIFrame* frameToScroll = do_QueryFrame(scrollableFrame);
|
||||
MOZ_ASSERT(frameToScroll);
|
||||
if (isAutoDir) {
|
||||
ESMAutoDirWheelDeltaAdjuster adjuster(*aEvent,
|
||||
*lastScrollFrame,
|
||||
honoursRoot);
|
||||
// Note that calling this function will not always cause the delta to
|
||||
// be adjusted, it only adjusts the delta when it should, because
|
||||
// Adjust() internally calls ShouldBeAdjusted() before making
|
||||
// adjustment.
|
||||
adjuster.Adjust();
|
||||
}
|
||||
return frameToScroll;
|
||||
}
|
||||
}
|
||||
|
@ -2582,10 +2623,21 @@ EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool checkIfScrollableX =
|
||||
aDirectionX && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS);
|
||||
bool checkIfScrollableY =
|
||||
aDirectionY && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS);
|
||||
bool checkIfScrollableX;
|
||||
bool checkIfScrollableY;
|
||||
if (isAutoDir) {
|
||||
// Always check the frame's scrollability in both the two directions for an
|
||||
// auto-dir scroll. That is, for an auto-dir scroll,
|
||||
// PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS and
|
||||
// PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS should be ignored.
|
||||
checkIfScrollableX = true;
|
||||
checkIfScrollableY = true;
|
||||
} else {
|
||||
checkIfScrollableX =
|
||||
aDirectionX && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS);
|
||||
checkIfScrollableY =
|
||||
aDirectionY && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS);
|
||||
}
|
||||
|
||||
nsIFrame* scrollFrame =
|
||||
!(aOptions & START_FROM_PARENT) ? aTargetFrame :
|
||||
|
@ -2648,10 +2700,23 @@ EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
|||
continue;
|
||||
}
|
||||
|
||||
// For default action, we should climb up the tree if cannot scroll it
|
||||
// by the event actually.
|
||||
bool canScroll = WheelHandlingUtils::CanScrollOn(scrollableFrame,
|
||||
aDirectionX, aDirectionY);
|
||||
// Computes whether the currently checked frame is scrollable by this wheel
|
||||
// event.
|
||||
bool canScroll = false;
|
||||
if (isAutoDir) {
|
||||
ESMAutoDirWheelDeltaAdjuster adjuster(*aEvent, *scrollFrame, honoursRoot);
|
||||
if (adjuster.ShouldBeAdjusted()) {
|
||||
adjuster.Adjust();
|
||||
canScroll = true;
|
||||
} else if (WheelHandlingUtils::CanScrollOn(scrollableFrame,
|
||||
aDirectionX, aDirectionY)) {
|
||||
canScroll = true;
|
||||
}
|
||||
} else if (WheelHandlingUtils::CanScrollOn(scrollableFrame,
|
||||
aDirectionX, aDirectionY)) {
|
||||
canScroll = true;
|
||||
}
|
||||
|
||||
// Comboboxes need special care.
|
||||
nsIComboboxControlFrame* comboBox = do_QueryFrame(scrollFrame);
|
||||
if (comboBox) {
|
||||
|
@ -2666,13 +2731,20 @@ EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
|||
if (canScroll) {
|
||||
return frameToScroll;
|
||||
}
|
||||
|
||||
// Where we are at is the block ending in a for loop.
|
||||
// The current frame has been checked to be unscrollable by this wheel
|
||||
// event, continue the loop to check its parent, if any.
|
||||
}
|
||||
|
||||
nsIFrame* newFrame = nsLayoutUtils::GetCrossDocParentFrame(
|
||||
aTargetFrame->PresShell()->GetRootFrame());
|
||||
aOptions =
|
||||
static_cast<ComputeScrollTargetOptions>(aOptions & ~START_FROM_PARENT);
|
||||
return newFrame ? ComputeScrollTarget(newFrame, aEvent, aOptions) : nullptr;
|
||||
if (!newFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
return ComputeScrollTargetAndMayAdjustWheelEvent(newFrame, aEvent, aOptions);
|
||||
}
|
||||
|
||||
nsSize
|
||||
|
@ -2837,14 +2909,16 @@ EventStateManager::DoScrollText(nsIScrollableFrame* aScrollableFrame,
|
|||
if (scrollFrameWeak.IsAlive()) {
|
||||
if (aEvent->mDeltaX &&
|
||||
overflowStyle.mHorizontal == NS_STYLE_OVERFLOW_HIDDEN &&
|
||||
!ComputeScrollTarget(scrollFrame, aEvent,
|
||||
COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS)) {
|
||||
!ComputeScrollTargetAndMayAdjustWheelEvent(
|
||||
scrollFrame, aEvent,
|
||||
COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS_WITH_AUTO_DIR)) {
|
||||
aEvent->mOverflowDeltaX = aEvent->mDeltaX;
|
||||
}
|
||||
if (aEvent->mDeltaY &&
|
||||
overflowStyle.mVertical == NS_STYLE_OVERFLOW_HIDDEN &&
|
||||
!ComputeScrollTarget(scrollFrame, aEvent,
|
||||
COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS)) {
|
||||
!ComputeScrollTargetAndMayAdjustWheelEvent(
|
||||
scrollFrame, aEvent,
|
||||
COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS_WITH_AUTO_DIR)) {
|
||||
aEvent->mOverflowDeltaY = aEvent->mDeltaY;
|
||||
}
|
||||
}
|
||||
|
@ -3368,8 +3442,10 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
ScrollbarsForWheel::MayInactivate();
|
||||
WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent();
|
||||
nsIScrollableFrame* scrollTarget =
|
||||
do_QueryFrame(ComputeScrollTarget(mCurrentTarget, wheelEvent,
|
||||
COMPUTE_DEFAULT_ACTION_TARGET));
|
||||
do_QueryFrame(
|
||||
ComputeScrollTargetAndMayAdjustWheelEvent(
|
||||
mCurrentTarget, wheelEvent,
|
||||
COMPUTE_DEFAULT_ACTION_TARGET_WITH_AUTO_DIR));
|
||||
if (scrollTarget) {
|
||||
scrollTarget->ScrollSnap();
|
||||
}
|
||||
|
@ -3408,12 +3484,21 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
horizontalizer.Horizontalize();
|
||||
}
|
||||
|
||||
// Since ComputeScrollTargetAndMayAdjustWheelEvent() may adjust the delta
|
||||
// if the event is auto-dir. So we use |ESMAutoDirWheelDeltaRestorer|
|
||||
// here.
|
||||
// An instance of |ESMAutoDirWheelDeltaRestorer| is used to monitor
|
||||
// auto-dir adjustment which may happen during its lifetime. If the delta
|
||||
// values is adjusted during its lifetime, the instance will restore the
|
||||
// adjusted delta when it's being destrcuted.
|
||||
ESMAutoDirWheelDeltaRestorer restorer(*wheelEvent);
|
||||
// Check if the frame to scroll before checking the default action
|
||||
// because if the scroll target is a plugin, the default action should be
|
||||
// chosen by the plugin rather than by our prefs.
|
||||
nsIFrame* frameToScroll =
|
||||
ComputeScrollTarget(mCurrentTarget, wheelEvent,
|
||||
COMPUTE_DEFAULT_ACTION_TARGET);
|
||||
ComputeScrollTargetAndMayAdjustWheelEvent(
|
||||
mCurrentTarget, wheelEvent,
|
||||
COMPUTE_DEFAULT_ACTION_TARGET_WITH_AUTO_DIR);
|
||||
nsPluginFrame* pluginFrame = do_QueryFrame(frameToScroll);
|
||||
if (pluginFrame) {
|
||||
MOZ_ASSERT(pluginFrame->WantsToHandleWheelEventAsDefaultAction());
|
||||
|
@ -3505,8 +3590,8 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
// scrolling is possible in the requested direction. It does this
|
||||
// by looking at the scroll overflow values on mCanTriggerSwipe
|
||||
// events after they have been processed.
|
||||
allDeltaOverflown =
|
||||
!ComputeScrollTarget(mCurrentTarget, wheelEvent,
|
||||
allDeltaOverflown = !ComputeScrollTarget(
|
||||
mCurrentTarget, wheelEvent,
|
||||
COMPUTE_DEFAULT_ACTION_TARGET);
|
||||
}
|
||||
} else {
|
||||
|
@ -6160,7 +6245,6 @@ EventStateManager::GetWheelDeltaAdjustmentStrategy(
|
|||
case WheelPrefs::ACTION_HORIZONTALIZED_SCROLL:
|
||||
return WheelDeltaAdjustmentStrategy::eHorizontalize;
|
||||
default:
|
||||
// Prevent compilation errors generated by -Werror=switch
|
||||
break;
|
||||
}
|
||||
return WheelDeltaAdjustmentStrategy::eNone;
|
||||
|
|
|
@ -768,8 +768,8 @@ protected:
|
|||
DeltaDirection aDeltaDirection);
|
||||
|
||||
/**
|
||||
* ComputeScrollTarget() returns the scrollable frame which should be
|
||||
* scrolled.
|
||||
* ComputeScrollTargetAndMayAdjustWheelEvent() returns the scrollable frame
|
||||
* which should be scrolled.
|
||||
*
|
||||
* @param aTargetFrame The event target of the wheel event.
|
||||
* @param aEvent The handling mouse wheel event.
|
||||
|
@ -777,15 +777,18 @@ protected:
|
|||
* Callers should use COMPUTE_*.
|
||||
* @return The scrollable frame which should be scrolled.
|
||||
*/
|
||||
// These flags are used in ComputeScrollTarget(). Callers should use
|
||||
// COMPUTE_*.
|
||||
// These flags are used in ComputeScrollTargetAndMayAdjustWheelEvent().
|
||||
// Callers should use COMPUTE_*.
|
||||
enum
|
||||
{
|
||||
PREFER_MOUSE_WHEEL_TRANSACTION = 0x00000001,
|
||||
PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS = 0x00000002,
|
||||
PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS = 0x00000004,
|
||||
START_FROM_PARENT = 0x00000008,
|
||||
INCLUDE_PLUGIN_AS_TARGET = 0x00000010
|
||||
INCLUDE_PLUGIN_AS_TARGET = 0x00000010,
|
||||
// Indicates the wheel scroll event being computed is an auto-dir scroll, so
|
||||
// its delta may be adjusted after being computed.
|
||||
MAY_BE_ADJUSTED_BY_AUTO_DIR = 0x00000020,
|
||||
};
|
||||
enum ComputeScrollTargetOptions
|
||||
{
|
||||
|
@ -804,12 +807,22 @@ protected:
|
|||
COMPUTE_DEFAULT_ACTION_TARGET =
|
||||
(COMPUTE_DEFAULT_ACTION_TARGET_EXCEPT_PLUGIN |
|
||||
INCLUDE_PLUGIN_AS_TARGET),
|
||||
COMPUTE_DEFAULT_ACTION_TARGET_WITH_AUTO_DIR_EXCEPT_PLUGIN =
|
||||
(COMPUTE_DEFAULT_ACTION_TARGET_EXCEPT_PLUGIN |
|
||||
MAY_BE_ADJUSTED_BY_AUTO_DIR),
|
||||
COMPUTE_DEFAULT_ACTION_TARGET_WITH_AUTO_DIR =
|
||||
(COMPUTE_DEFAULT_ACTION_TARGET |
|
||||
MAY_BE_ADJUSTED_BY_AUTO_DIR),
|
||||
// Look for the nearest scrollable ancestor which can be scrollable with
|
||||
// aEvent.
|
||||
COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS =
|
||||
(PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS | START_FROM_PARENT),
|
||||
COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS =
|
||||
(PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS | START_FROM_PARENT)
|
||||
(PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS | START_FROM_PARENT),
|
||||
COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS_WITH_AUTO_DIR =
|
||||
(COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS | MAY_BE_ADJUSTED_BY_AUTO_DIR),
|
||||
COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS_WITH_AUTO_DIR =
|
||||
(COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS | MAY_BE_ADJUSTED_BY_AUTO_DIR),
|
||||
};
|
||||
static ComputeScrollTargetOptions RemovePluginFromTarget(
|
||||
ComputeScrollTargetOptions aOptions)
|
||||
|
@ -817,20 +830,52 @@ protected:
|
|||
switch (aOptions) {
|
||||
case COMPUTE_DEFAULT_ACTION_TARGET:
|
||||
return COMPUTE_DEFAULT_ACTION_TARGET_EXCEPT_PLUGIN;
|
||||
case COMPUTE_DEFAULT_ACTION_TARGET_WITH_AUTO_DIR:
|
||||
return COMPUTE_DEFAULT_ACTION_TARGET_WITH_AUTO_DIR_EXCEPT_PLUGIN;
|
||||
default:
|
||||
MOZ_ASSERT(!(aOptions & INCLUDE_PLUGIN_AS_TARGET));
|
||||
return aOptions;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the scroll target.
|
||||
// The delta values in the wheel event may be changed if the event is for
|
||||
// auto-dir scrolling. For information on auto-dir,
|
||||
// @see mozilla::WheelDeltaAdjustmentStrategy
|
||||
nsIFrame* ComputeScrollTargetAndMayAdjustWheelEvent(
|
||||
nsIFrame* aTargetFrame,
|
||||
WidgetWheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions);
|
||||
|
||||
nsIFrame* ComputeScrollTargetAndMayAdjustWheelEvent(
|
||||
nsIFrame* aTargetFrame,
|
||||
double aDirectionX,
|
||||
double aDirectionY,
|
||||
WidgetWheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions);
|
||||
|
||||
nsIFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
|
||||
WidgetWheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions);
|
||||
ComputeScrollTargetOptions aOptions)
|
||||
{
|
||||
MOZ_ASSERT(!(aOptions & MAY_BE_ADJUSTED_BY_AUTO_DIR),
|
||||
"aEvent may be modified by auto-dir");
|
||||
return ComputeScrollTargetAndMayAdjustWheelEvent(aTargetFrame, aEvent,
|
||||
aOptions);
|
||||
}
|
||||
|
||||
nsIFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
|
||||
double aDirectionX,
|
||||
double aDirectionY,
|
||||
WidgetWheelEvent* aEvent,
|
||||
ComputeScrollTargetOptions aOptions);
|
||||
ComputeScrollTargetOptions aOptions)
|
||||
{
|
||||
MOZ_ASSERT(!(aOptions & MAY_BE_ADJUSTED_BY_AUTO_DIR),
|
||||
"aEvent may be modified by auto-dir");
|
||||
return ComputeScrollTargetAndMayAdjustWheelEvent(aTargetFrame,
|
||||
aDirectionX, aDirectionY,
|
||||
aEvent, aOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* GetScrollAmount() returns the scroll amount in app uints of one line or
|
||||
|
@ -838,7 +883,8 @@ protected:
|
|||
* height. Otherwise, returns line height for both its width and height.
|
||||
*
|
||||
* @param aScrollableFrame A frame which will be scrolled by the event.
|
||||
* The result of ComputeScrollTarget() is
|
||||
* The result of
|
||||
* ComputeScrollTargetAndMayAdjustWheelEvent() is
|
||||
* expected for this value.
|
||||
* This can be nullptr if there is no scrollable
|
||||
* frame. Then, this method uses root frame's
|
||||
|
|
|
@ -531,7 +531,8 @@ ScrollbarsForWheel::TemporarilyActivateAllPossibleScrollTargets(
|
|||
AutoWeakFrame* scrollTarget = &sActivatedScrollTargets[i];
|
||||
MOZ_ASSERT(!*scrollTarget, "scroll target still temporarily activated!");
|
||||
nsIScrollableFrame* target = do_QueryFrame(
|
||||
aESM->ComputeScrollTarget(aTargetFrame, dir->deltaX, dir->deltaY, aEvent,
|
||||
aESM->ComputeScrollTarget(
|
||||
aTargetFrame, dir->deltaX, dir->deltaY, aEvent,
|
||||
EventStateManager::COMPUTE_DEFAULT_ACTION_TARGET));
|
||||
nsIScrollbarMediator* scrollbarMediator = do_QueryFrame(target);
|
||||
if (scrollbarMediator) {
|
||||
|
@ -706,4 +707,188 @@ AutoDirWheelDeltaAdjuster::Adjust()
|
|||
OnAdjusted();
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* mozilla::ESMAutoDirWheelDeltaAdjuster */
|
||||
/******************************************************************/
|
||||
|
||||
ESMAutoDirWheelDeltaAdjuster::ESMAutoDirWheelDeltaAdjuster(
|
||||
WidgetWheelEvent& aEvent,
|
||||
nsIFrame& aScrollFrame,
|
||||
bool aHonoursRoot)
|
||||
: AutoDirWheelDeltaAdjuster(aEvent.mDeltaX, aEvent.mDeltaY)
|
||||
, mLineOrPageDeltaX(aEvent.mLineOrPageDeltaX)
|
||||
, mLineOrPageDeltaY(aEvent.mLineOrPageDeltaY)
|
||||
, mOverflowDeltaX(aEvent.mOverflowDeltaX)
|
||||
, mOverflowDeltaY(aEvent.mOverflowDeltaY)
|
||||
{
|
||||
mScrollTargetFrame = aScrollFrame.GetScrollTargetFrame();
|
||||
MOZ_ASSERT(mScrollTargetFrame);
|
||||
|
||||
// TODO Currently, the honoured target is always the current scrolling frame.
|
||||
nsIFrame* honouredFrame = &aScrollFrame;
|
||||
|
||||
WritingMode writingMode = honouredFrame->GetWritingMode();
|
||||
WritingMode::BlockDir blockDir = writingMode.GetBlockDir();
|
||||
WritingMode::InlineDir inlineDir = writingMode.GetInlineDir();
|
||||
// Get whether the honoured frame's content in the horizontal direction starts
|
||||
// from right to left(E.g. it's true either if "writing-mode: vertical-rl", or
|
||||
// if "writing-mode: horizontal-tb; direction: rtl;" in CSS).
|
||||
mIsHorizontalContentRightToLeft =
|
||||
(blockDir == WritingMode::BlockDir::eBlockRL ||
|
||||
(blockDir == WritingMode::BlockDir::eBlockTB &&
|
||||
inlineDir == WritingMode::InlineDir::eInlineRTL));
|
||||
}
|
||||
|
||||
void
|
||||
ESMAutoDirWheelDeltaAdjuster::OnAdjusted()
|
||||
{
|
||||
// Adjust() only adjusted basic deltaX and deltaY, which are not enough for
|
||||
// ESM, we should continue to adjust line-or-page and overflow values.
|
||||
if (mDeltaX) {
|
||||
// A vertical scroll was adjusted to be horizontal.
|
||||
MOZ_ASSERT(0 == mDeltaY);
|
||||
|
||||
mLineOrPageDeltaX = mLineOrPageDeltaY;
|
||||
mLineOrPageDeltaY = 0;
|
||||
mOverflowDeltaX = mOverflowDeltaY;
|
||||
mOverflowDeltaY = 0;
|
||||
} else {
|
||||
// A horizontal scroll was adjusted to be vertical.
|
||||
MOZ_ASSERT(0 != mDeltaY);
|
||||
|
||||
mLineOrPageDeltaY = mLineOrPageDeltaX;
|
||||
mLineOrPageDeltaX = 0;
|
||||
mOverflowDeltaY = mOverflowDeltaX;
|
||||
mOverflowDeltaX = 0;
|
||||
}
|
||||
if (mIsHorizontalContentRightToLeft) {
|
||||
// If in RTL writing mode, reverse the side the scroll will go towards.
|
||||
mLineOrPageDeltaX *= -1;
|
||||
mLineOrPageDeltaY *= -1;
|
||||
mOverflowDeltaX *= -1;
|
||||
mOverflowDeltaY *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ESMAutoDirWheelDeltaAdjuster::CanScrollAlongXAxis() const
|
||||
{
|
||||
return mScrollTargetFrame->GetPerceivedScrollingDirections() &
|
||||
nsIScrollableFrame::HORIZONTAL;
|
||||
}
|
||||
|
||||
bool
|
||||
ESMAutoDirWheelDeltaAdjuster::CanScrollAlongYAxis() const
|
||||
{
|
||||
return mScrollTargetFrame->GetPerceivedScrollingDirections() &
|
||||
nsIScrollableFrame::VERTICAL;
|
||||
}
|
||||
|
||||
bool
|
||||
ESMAutoDirWheelDeltaAdjuster::CanScrollUpwards() const
|
||||
{
|
||||
nsPoint scrollPt = mScrollTargetFrame->GetScrollPosition();
|
||||
nsRect scrollRange = mScrollTargetFrame->GetScrollRange();
|
||||
return static_cast<double>(scrollRange.y) < scrollPt.y;
|
||||
}
|
||||
|
||||
bool
|
||||
ESMAutoDirWheelDeltaAdjuster::CanScrollDownwards() const
|
||||
{
|
||||
nsPoint scrollPt = mScrollTargetFrame->GetScrollPosition();
|
||||
nsRect scrollRange = mScrollTargetFrame->GetScrollRange();
|
||||
return static_cast<double>(scrollRange.YMost()) > scrollPt.y;
|
||||
}
|
||||
|
||||
bool
|
||||
ESMAutoDirWheelDeltaAdjuster::CanScrollLeftwards() const
|
||||
{
|
||||
nsPoint scrollPt = mScrollTargetFrame->GetScrollPosition();
|
||||
nsRect scrollRange = mScrollTargetFrame->GetScrollRange();
|
||||
return static_cast<double>(scrollRange.x) < scrollPt.x;
|
||||
}
|
||||
|
||||
bool
|
||||
ESMAutoDirWheelDeltaAdjuster::CanScrollRightwards() const
|
||||
{
|
||||
nsPoint scrollPt = mScrollTargetFrame->GetScrollPosition();
|
||||
nsRect scrollRange = mScrollTargetFrame->GetScrollRange();
|
||||
return static_cast<double>(scrollRange.XMost()) > scrollPt.x;
|
||||
}
|
||||
|
||||
bool
|
||||
ESMAutoDirWheelDeltaAdjuster::IsHorizontalContentRightToLeft() const
|
||||
{
|
||||
return mIsHorizontalContentRightToLeft;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* mozilla::ESMAutoDirWheelDeltaRestorer */
|
||||
/******************************************************************/
|
||||
|
||||
/*explicit*/
|
||||
ESMAutoDirWheelDeltaRestorer::ESMAutoDirWheelDeltaRestorer(
|
||||
WidgetWheelEvent& aEvent)
|
||||
: mEvent(aEvent)
|
||||
, mOldDeltaX(aEvent.mDeltaX)
|
||||
, mOldDeltaY(aEvent.mDeltaY)
|
||||
, mOldLineOrPageDeltaX(aEvent.mLineOrPageDeltaX)
|
||||
, mOldLineOrPageDeltaY(aEvent.mLineOrPageDeltaY)
|
||||
, mOldOverflowDeltaX(aEvent.mOverflowDeltaX)
|
||||
, mOldOverflowDeltaY(aEvent.mOverflowDeltaY)
|
||||
{
|
||||
}
|
||||
|
||||
ESMAutoDirWheelDeltaRestorer::~ESMAutoDirWheelDeltaRestorer()
|
||||
{
|
||||
if (mOldDeltaX == mEvent.mDeltaX || mOldDeltaY == mEvent.mDeltaY) {
|
||||
// The delta of the event wasn't adjusted during the lifetime of this
|
||||
// |ESMAutoDirWheelDeltaRestorer| instance. No need to restore it.
|
||||
return;
|
||||
}
|
||||
|
||||
bool forRTL = false;
|
||||
|
||||
// First, restore the basic deltaX and deltaY.
|
||||
std::swap(mEvent.mDeltaX, mEvent.mDeltaY);
|
||||
if (mOldDeltaX != mEvent.mDeltaX || mOldDeltaY != mEvent.mDeltaY) {
|
||||
// If X and Y still don't equal to their original values after being
|
||||
// swapped, then it must be because they were adjusted for RTL.
|
||||
forRTL = true;
|
||||
mEvent.mDeltaX *= -1;
|
||||
mEvent.mDeltaY *= -1;
|
||||
MOZ_ASSERT(mOldDeltaX == mEvent.mDeltaX && mOldDeltaY == mEvent.mDeltaY);
|
||||
}
|
||||
|
||||
if (mEvent.mDeltaX) {
|
||||
// A horizontal scroll was adjusted to be vertical during the lifetime of
|
||||
// this instance.
|
||||
MOZ_ASSERT(0 == mEvent.mDeltaY);
|
||||
|
||||
// Restore the line-or-page and overflow values to be horizontal.
|
||||
mEvent.mOverflowDeltaX = mEvent.mOverflowDeltaY;
|
||||
mEvent.mLineOrPageDeltaX = mEvent.mLineOrPageDeltaY;
|
||||
if (forRTL) {
|
||||
mEvent.mOverflowDeltaX *= -1;
|
||||
mEvent.mLineOrPageDeltaX *= -1;
|
||||
}
|
||||
mEvent.mOverflowDeltaY = mOldOverflowDeltaY;
|
||||
mEvent.mLineOrPageDeltaY = mOldLineOrPageDeltaY;
|
||||
} else {
|
||||
// A vertical scroll was adjusted to be horizontal during the lifetime of
|
||||
// this instance.
|
||||
MOZ_ASSERT(0 != mEvent.mDeltaY);
|
||||
|
||||
// Restore the line-or-page and overflow values to be vertical.
|
||||
mEvent.mOverflowDeltaY = mEvent.mOverflowDeltaX;
|
||||
mEvent.mLineOrPageDeltaY = mEvent.mLineOrPageDeltaX;
|
||||
if (forRTL) {
|
||||
mEvent.mOverflowDeltaY *= -1;
|
||||
mEvent.mLineOrPageDeltaY *= -1;
|
||||
}
|
||||
mEvent.mOverflowDeltaX = mOldOverflowDeltaX;
|
||||
mEvent.mLineOrPageDeltaX = mOldLineOrPageDeltaX;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -382,6 +382,74 @@ private:
|
|||
bool mShouldBeAdjusted;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the implementation of AutoDirWheelDeltaAdjuster for EventStateManager
|
||||
*
|
||||
* Detailed comments about some member functions are given in the base class
|
||||
* AutoDirWheelDeltaAdjuster.
|
||||
*/
|
||||
class MOZ_STACK_CLASS ESMAutoDirWheelDeltaAdjuster final
|
||||
: public AutoDirWheelDeltaAdjuster
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param aEvent The auto-dir wheel scroll event.
|
||||
* @param aScrollFrame The scroll target for the event.
|
||||
* @param aHonoursRoot If set to true, the honoured frame is the root
|
||||
* frame in the same document where the target is;
|
||||
* If false, the honoured frame is the scroll
|
||||
* target. For the concept of an honoured target,
|
||||
* @see mozilla::WheelDeltaAdjustmentStrategy
|
||||
*/
|
||||
ESMAutoDirWheelDeltaAdjuster(WidgetWheelEvent& aEvent,
|
||||
nsIFrame& aScrollFrame,
|
||||
bool aHonoursRoot);
|
||||
|
||||
private:
|
||||
virtual void OnAdjusted() override;
|
||||
virtual bool CanScrollAlongXAxis() const override;
|
||||
virtual bool CanScrollAlongYAxis() const override;
|
||||
virtual bool CanScrollUpwards() const override;
|
||||
virtual bool CanScrollDownwards() const override;
|
||||
virtual bool CanScrollLeftwards() const override;
|
||||
virtual bool CanScrollRightwards() const override;
|
||||
virtual bool IsHorizontalContentRightToLeft() const override;
|
||||
|
||||
nsIScrollableFrame* mScrollTargetFrame;
|
||||
bool mIsHorizontalContentRightToLeft;
|
||||
|
||||
int32_t& mLineOrPageDeltaX;
|
||||
int32_t& mLineOrPageDeltaY;
|
||||
double& mOverflowDeltaX;
|
||||
double& mOverflowDeltaY;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is used for restoring the delta in an auto-dir wheel.
|
||||
*
|
||||
* An instance of this calss monitors auto-dir adjustment which may happen
|
||||
* during its lifetime. If the delta values is adjusted during its lifetime, the
|
||||
* instance will restore the adjusted delta when it's being destrcuted.
|
||||
*/
|
||||
class MOZ_STACK_CLASS ESMAutoDirWheelDeltaRestorer final
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param aEvent The wheel scroll event to be monitored.
|
||||
*/
|
||||
explicit ESMAutoDirWheelDeltaRestorer(WidgetWheelEvent& aEvent);
|
||||
~ESMAutoDirWheelDeltaRestorer();
|
||||
|
||||
private:
|
||||
WidgetWheelEvent& mEvent;
|
||||
double mOldDeltaX;
|
||||
double mOldDeltaY;
|
||||
int32_t mOldLineOrPageDeltaX;
|
||||
int32_t mOldLineOrPageDeltaY;
|
||||
double mOldOverflowDeltaX;
|
||||
double mOldOverflowDeltaY;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_WheelHandlingHelper_h_
|
||||
|
|
Загрузка…
Ссылка в новой задаче