Bug 1358017 - Part 5: Implements the "honour root" functionality for the auto-dir scrolling feature in APZ r=kats

With this commit, all the auto-dir scrolling functionalities are completed in
APZ.

MozReview-Commit-ID: L7qa3xOD8t9

--HG--
extra : rebase_source : bad2770219a0e6219f91899ab6c78e68f37195ac
This commit is contained in:
Zhang Junzhi 2018-03-16 21:20:39 +08:00
Родитель fe2d79f73f
Коммит 2bdc6774da
4 изменённых файлов: 64 добавлений и 6 удалений

Просмотреть файл

@ -833,6 +833,7 @@ public:
, mScrollClip()
, mHasScrollgrab(false)
, mIsLayersIdRoot(false)
, mIsAutoDirRootContentRTL(false)
, mUsesContainerScrolling(false)
, mForceDisableApz(false)
, mOverscrollBehavior()
@ -850,6 +851,7 @@ public:
mScrollClip == aOther.mScrollClip &&
mHasScrollgrab == aOther.mHasScrollgrab &&
mIsLayersIdRoot == aOther.mIsLayersIdRoot &&
mIsAutoDirRootContentRTL == aOther.mIsAutoDirRootContentRTL &&
mUsesContainerScrolling == aOther.mUsesContainerScrolling &&
mForceDisableApz == aOther.mForceDisableApz &&
mDisregardedDirection == aOther.mDisregardedDirection &&
@ -944,6 +946,12 @@ public:
bool IsLayersIdRoot() const {
return mIsLayersIdRoot;
}
void SetIsAutoDirRootContentRTL(bool aValue) {
mIsAutoDirRootContentRTL = aValue;
}
bool IsAutoDirRootContentRTL() const {
return mIsAutoDirRootContentRTL;
}
// Implemented out of line because the implementation needs gfxPrefs.h
// and we don't want to include that from FrameMetrics.h.
void SetUsesContainerScrolling(bool aValue);
@ -1012,6 +1020,17 @@ private:
// we don't have a root scroll frame) for its layers id.
bool mIsLayersIdRoot:1;
// The AutoDirRootContent is the <body> element in an HTML document, or the
// root scrollframe if there is no body. This member variable indicates
// whether this element's content in the horizontal direction starts from
// right to left (e.g. it's true either if "writing-mode: vertical-rl", or
// "writing-mode: horizontal-tb; direction: rtl" in CSS).
// When we do auto-dir scrolling (@see mozilla::WheelDeltaAdjustmentStrategy
// or refer to bug 1358017 for details), setting a pref can make the code use
// the writing mode of this root element instead of the target scrollframe,
// and so we need to know if the writing mode is RTL or not.
bool mIsAutoDirRootContentRTL:1;
// True if scrolling using containers, false otherwise. This can be removed
// when containerful scrolling is eliminated.
bool mUsesContainerScrolling:1;

Просмотреть файл

@ -2084,8 +2084,9 @@ bool
AsyncPanZoomController::IsContentOfHonouredTargetRightToLeft(
bool aHonoursRoot) const
{
// TODO The current implementation only honours the scrolling target, the
// functionality of honouring root is going to be added in the next commit.
if (aHonoursRoot) {
return mScrollMetadata.IsAutoDirRootContentRTL();
}
RecursiveMutexAutoLock lock(mRecursiveMutex);
return mFrameMetrics.IsHorizontalContentRightToLeft();
}
@ -4093,6 +4094,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
// has no business using it.
mScrollMetadata.SetScrollClip(Nothing());
mScrollMetadata.SetIsLayersIdRoot(aScrollMetadata.IsLayersIdRoot());
mScrollMetadata.SetIsAutoDirRootContentRTL(
aScrollMetadata.IsAutoDirRootContentRTL());
mScrollMetadata.SetUsesContainerScrolling(aScrollMetadata.UsesContainerScrolling());
mFrameMetrics.SetIsScrollInfoLayer(aLayerMetrics.IsScrollInfoLayer());
mScrollMetadata.SetForceDisableApz(aScrollMetadata.IsApzForceDisabled());

Просмотреть файл

@ -282,6 +282,7 @@ struct ParamTraits<mozilla::layers::ScrollMetadata>
WriteParam(aMsg, aParam.mScrollClip);
WriteParam(aMsg, aParam.mHasScrollgrab);
WriteParam(aMsg, aParam.mIsLayersIdRoot);
WriteParam(aMsg, aParam.mIsAutoDirRootContentRTL);
WriteParam(aMsg, aParam.mUsesContainerScrolling);
WriteParam(aMsg, aParam.mForceDisableApz);
WriteParam(aMsg, aParam.mDisregardedDirection);
@ -310,6 +311,8 @@ struct ParamTraits<mozilla::layers::ScrollMetadata>
ReadParam(aMsg, aIter, &aResult->mScrollClip) &&
ReadBoolForBitfield(aMsg, aIter, aResult, &paramType::SetHasScrollgrab) &&
ReadBoolForBitfield(aMsg, aIter, aResult, &paramType::SetIsLayersIdRoot) &&
ReadBoolForBitfield(aMsg, aIter, aResult,
&paramType::SetIsAutoDirRootContentRTL) &&
ReadBoolForBitfield(aMsg, aIter, aResult, &paramType::SetUsesContainerScrolling) &&
ReadBoolForBitfield(aMsg, aIter, aResult, &paramType::SetForceDisableApz) &&
ReadParam(aMsg, aIter, &aResult->mDisregardedDirection) &&

Просмотреть файл

@ -9341,16 +9341,50 @@ nsLayoutUtils::ComputeScrollMetadata(nsIFrame* aForFrame,
metrics.SetIsRootContent(aIsRootContent);
metadata.SetScrollParentId(aScrollParentId);
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
bool isRootScrollFrame = aScrollFrame == rootScrollFrame;
nsIDocument* document = presShell->GetDocument();
if (scrollId != FrameMetrics::NULL_SCROLL_ID && !presContext->GetParentPresContext()) {
if ((aScrollFrame && (aScrollFrame == presShell->GetRootScrollFrame())) ||
aContent == presShell->GetDocument()->GetDocumentElement()) {
if ((aScrollFrame && isRootScrollFrame)) {
metadata.SetIsLayersIdRoot(true);
} else {
MOZ_ASSERT(document, "A non-root-scroll frame must be in a document");
if (aContent == document->GetDocumentElement()) {
metadata.SetIsLayersIdRoot(true);
}
}
}
// Get whether the root content is RTL(E.g. it's true either if
// "writing-mode: vertical-rl", or if
// "writing-mode: horizontal-tb; direction: rtl;" in CSS).
// For the concept of this and the reason why we need to get this kind of
// information, see the definition of |mIsAutoDirRootContentRTL| in struct
// |ScrollMetadata|.
Element* bodyElement = document ? document->GetBodyElement() : nullptr;
nsIFrame* primaryFrame = bodyElement ? bodyElement->GetPrimaryFrame() :
rootScrollFrame;
if (!primaryFrame) {
primaryFrame = rootScrollFrame;
}
if (primaryFrame) {
WritingMode writingModeOfRootScrollFrame =
primaryFrame->GetWritingMode();
WritingMode::BlockDir blockDirOfRootScrollFrame =
writingModeOfRootScrollFrame.GetBlockDir();
WritingMode::InlineDir inlineDirOfRootScrollFrame =
writingModeOfRootScrollFrame.GetInlineDir();
if (blockDirOfRootScrollFrame == WritingMode::BlockDir::eBlockRL ||
(blockDirOfRootScrollFrame == WritingMode::BlockDir::eBlockTB &&
inlineDirOfRootScrollFrame == WritingMode::InlineDir::eInlineRTL)) {
metadata.SetIsAutoDirRootContentRTL(true);
}
}
// Only the root scrollable frame for a given presShell should pick up
// the presShell's resolution. All the other frames are 1.0.
if (aScrollFrame == presShell->GetRootScrollFrame()) {
if (isRootScrollFrame) {
metrics.SetPresShellResolution(presShell->GetResolution());
} else {
metrics.SetPresShellResolution(1.0f);
@ -9409,7 +9443,6 @@ nsLayoutUtils::ComputeScrollMetadata(nsIFrame* aForFrame,
// document has a widget then the widget's bounds will correspond to what is
// visible. If we don't have a widget the root view's bounds correspond to what
// would be visible because they don't get modified by setCSSViewport.
bool isRootScrollFrame = aScrollFrame == presShell->GetRootScrollFrame();
bool isRootContentDocRootScrollFrame = isRootScrollFrame
&& presContext->IsRootContentDocument();
if (isRootContentDocRootScrollFrame) {