Bug 1418387 - Propagate scrollbar direction for scrollbar containers to APZ. r?botond
Most of this patch is just mechanical changes, but note that this patch
now makes the mFlags in scrollbar-container nsDisplayOwnLayer instances
have one of the direction bits set. As a result, this requires changing
the implementation of nsDisplayOwnLayer::IsScrollThumbLayer().
MozReview-Commit-ID: 2BLdbpz5Sa8
--- a/gfx/layers/LayerAttributes.h
+++ b/gfx/layers/LayerAttributes.h
@@ -74,17 +74,16 @@ public:
SimpleLayerAttributes()
: mTransformIsPerspective(false),
mPostXScale(1.0f),
mPostYScale(1.0f),
mContentFlags(0),
mOpacity(1.0f),
mIsFixedPosition(false),
mScrollbarTargetContainerId(FrameMetrics::NULL_SCROLL_ID),
- mIsScrollbarContainer(false),
mMixBlendMode(gfx::CompositionOp::OP_OVER),
mForceIsolatedGroup(false)
{
}
//
// Setters.
// All set methods return true if values changed, false otherwise.
@@ -124,21 +123,24 @@ public:
mThumbData == aThumbData)
{
return false;
}
mScrollbarTargetContainerId = aScrollId;
mThumbData = aThumbData;
return true;
}
- bool SetIsScrollbarContainer(FrameMetrics::ViewID aScrollId) {
- if (mIsScrollbarContainer && mScrollbarTargetContainerId == aScrollId) {
+ bool SetScrollbarContainer(FrameMetrics::ViewID aScrollId,
+ ScrollDirection aDirection) {
+ if (mScrollbarContainerDirection &&
+ *mScrollbarContainerDirection == aDirection &&
+ mScrollbarTargetContainerId == aScrollId) {
return false;
}
- mIsScrollbarContainer = true;
+ mScrollbarContainerDirection = Some(aDirection);
mScrollbarTargetContainerId = aScrollId;
return true;
}
bool SetMixBlendMode(gfx::CompositionOp aMixBlendMode) {
if (mMixBlendMode == aMixBlendMode) {
return false;
}
mMixBlendMode = aMixBlendMode;
@@ -205,17 +207,17 @@ public:
mStickyPositionData->mOuter = aOuter;
mStickyPositionData->mInner = aInner;
return true;
}
// This returns true if scrolling info is equivalent for the purposes of
// APZ hit testing.
bool HitTestingInfoIsEqual(const SimpleLayerAttributes& aOther) const {
- if (mIsScrollbarContainer != aOther.mIsScrollbarContainer) {
+ if (mScrollbarContainerDirection != aOther.mScrollbarContainerDirection) {
return false;
}
if (mScrollbarTargetContainerId != aOther.mScrollbarTargetContainerId) {
return false;
}
if (mThumbData != aOther.mThumbData) {
return false;
}
@@ -248,18 +250,18 @@ public:
return mIsFixedPosition;
}
FrameMetrics::ViewID ScrollbarTargetContainerId() const {
return mScrollbarTargetContainerId;
}
const ScrollThumbData& ThumbData() const {
return mThumbData;
}
- bool IsScrollbarContainer() const {
- return mIsScrollbarContainer;
+ Maybe<ScrollDirection> GetScrollbarContainerDirection() const {
+ return mScrollbarContainerDirection;
}
gfx::CompositionOp MixBlendMode() const {
return mMixBlendMode;
}
bool ForceIsolatedGroup() const {
return mForceIsolatedGroup;
}
const gfx::Matrix4x4& Transform() const {
@@ -301,33 +303,33 @@ public:
mScrolledClip == aOther.mScrolledClip &&
mPostXScale == aOther.mPostXScale &&
mPostYScale == aOther.mPostYScale &&
mContentFlags == aOther.mContentFlags &&
mOpacity == aOther.mOpacity &&
mIsFixedPosition == aOther.mIsFixedPosition &&
mScrollbarTargetContainerId == aOther.mScrollbarTargetContainerId &&
mThumbData == aOther.mThumbData &&
- mIsScrollbarContainer == aOther.mIsScrollbarContainer &&
+ mScrollbarContainerDirection == aOther.mScrollbarContainerDirection &&
mMixBlendMode == aOther.mMixBlendMode &&
mForceIsolatedGroup == aOther.mForceIsolatedGroup;
}
private:
gfx::Matrix4x4 mTransform;
bool mTransformIsPerspective;
Maybe<LayerClip> mScrolledClip;
float mPostXScale;
float mPostYScale;
uint32_t mContentFlags;
float mOpacity;
bool mIsFixedPosition;
uint64_t mScrollbarTargetContainerId;
ScrollThumbData mThumbData;
- bool mIsScrollbarContainer;
+ Maybe<ScrollDirection> mScrollbarContainerDirection;
gfx::CompositionOp mMixBlendMode;
bool mForceIsolatedGroup;
struct FixedPositionData {
FrameMetrics::ViewID mScrollId;
LayerPoint mAnchor;
int32_t mSides;
};
--- a/gfx/layers/LayerMetricsWrapper.h
+++ b/gfx/layers/LayerMetricsWrapper.h
@@ -428,20 +428,20 @@ public:
FrameMetrics::ViewID GetScrollbarTargetContainerId() const
{
MOZ_ASSERT(IsValid());
return mLayer->GetScrollbarTargetContainerId();
}
- bool IsScrollbarContainer() const
+ Maybe<ScrollDirection> GetScrollbarContainerDirection() const
{
MOZ_ASSERT(IsValid());
- return mLayer->IsScrollbarContainer();
+ return mLayer->GetScrollbarContainerDirection();
}
FrameMetrics::ViewID GetFixedPositionScrollContainerId() const
{
MOZ_ASSERT(IsValid());
return mLayer->GetFixedPositionScrollContainerId();
}
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1807,17 +1807,17 @@ Layer::PrintInfo(std::stringstream& aStr
aStream << " [extend3DContext]";
}
if (Combines3DTransformWithAncestors()) {
aStream << " [combines3DTransformWithAncestors]";
}
if (Is3DContextLeaf()) {
aStream << " [is3DContextLeaf]";
}
- if (IsScrollbarContainer()) {
+ if (GetScrollbarContainerDirection().isSome()) {
aStream << " [scrollbar]";
}
if (Maybe<ScrollDirection> thumbDirection = GetScrollThumbData().mDirection) {
if (*thumbDirection == ScrollDirection::eVertical) {
aStream << nsPrintfCString(" [vscrollbar=%" PRIu64 "]", GetScrollbarTargetContainerId()).get();
}
if (*thumbDirection == ScrollDirection::eHorizontal) {
aStream << nsPrintfCString(" [hscrollbar=%" PRIu64 "]", GetScrollbarTargetContainerId()).get();
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1307,19 +1307,20 @@ public:
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollbarData", this));
MutatedSimple();
}
}
// Set during construction for the container layer of scrollbar components.
// |aScrollId| holds the scroll identifier of the scrollable content that
// the scrollbar is for.
- void SetIsScrollbarContainer(FrameMetrics::ViewID aScrollId)
+ void SetScrollbarContainer(FrameMetrics::ViewID aScrollId,
+ ScrollDirection aDirection)
{
- if (mSimpleAttrs.SetIsScrollbarContainer(aScrollId)) {
+ if (mSimpleAttrs.SetScrollbarContainer(aScrollId, aDirection)) {
MutatedSimple();
}
}
// Used when forwarding transactions. Do not use at any other time.
void SetSimpleAttributes(const SimpleLayerAttributes& aAttrs) {
mSimpleAttrs = aAttrs;
}
@@ -1373,17 +1374,18 @@ public:
FrameMetrics::ViewID GetFixedPositionScrollContainerId() { return mSimpleAttrs.FixedPositionScrollContainerId(); }
LayerPoint GetFixedPositionAnchor() { return mSimpleAttrs.FixedPositionAnchor(); }
int32_t GetFixedPositionSides() { return mSimpleAttrs.FixedPositionSides(); }
FrameMetrics::ViewID GetStickyScrollContainerId() { return mSimpleAttrs.StickyScrollContainerId(); }
const LayerRect& GetStickyScrollRangeOuter() { return mSimpleAttrs.StickyScrollRangeOuter(); }
const LayerRect& GetStickyScrollRangeInner() { return mSimpleAttrs.StickyScrollRangeInner(); }
FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mSimpleAttrs.ScrollbarTargetContainerId(); }
const ScrollThumbData& GetScrollThumbData() const { return mSimpleAttrs.ThumbData(); }
- bool IsScrollbarContainer() { return mSimpleAttrs.IsScrollbarContainer(); }
+ bool IsScrollbarContainer() { return mSimpleAttrs.GetScrollbarContainerDirection().isSome(); }
+ Maybe<ScrollDirection> GetScrollbarContainerDirection() { return mSimpleAttrs.GetScrollbarContainerDirection(); }
Layer* GetMaskLayer() const { return mMaskLayer; }
bool HasPendingTransform() const { return mPendingTransform; }
void CheckCanary() const { mCanary.Check(); }
// Ancestor mask layers are associated with FrameMetrics, but for simplicity
// in maintaining the layer tree structure we attach them to the layer.
size_t GetAncestorMaskLayerCount() const {
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -753,17 +753,17 @@ APZCTreeManager::PrepareNodeForLayer(con
GetEventRegions(aLayer),
aLayer.GetVisibleRegion(),
aLayer.GetTransformTyped(),
aLayer.GetClipRect() ? Some(ParentLayerIntRegion(*aLayer.GetClipRect())) : Nothing(),
GetEventRegionsOverride(aParent, aLayer));
node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
aLayer.GetScrollbarAnimationId(),
aLayer.GetScrollThumbData(),
- aLayer.IsScrollbarContainer());
+ aLayer.GetScrollbarContainerDirection());
node->SetFixedPosData(aLayer.GetFixedPositionScrollContainerId());
return node;
}
AsyncPanZoomController* apzc = nullptr;
// If we get here, aLayer is a scrollable layer and somebody
// has registered a GeckoContentController for it, so we need to ensure
// it has an APZC instance to manage its scrolling.
@@ -947,17 +947,17 @@ APZCTreeManager::PrepareNodeForLayer(con
}
// Note: if layer properties must be propagated to nodes, RecvUpdate in
// LayerTransactionParent.cpp must ensure that APZ will be notified
// when those properties change.
node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
aLayer.GetScrollbarAnimationId(),
aLayer.GetScrollThumbData(),
- aLayer.IsScrollbarContainer());
+ aLayer.GetScrollbarContainerDirection());
node->SetFixedPosData(aLayer.GetFixedPositionScrollContainerId());
return node;
}
template<typename PanGestureOrScrollWheelInput>
static bool
WillHandleInput(const PanGestureOrScrollWheelInput& aPanInput)
{
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -23,17 +23,16 @@ namespace layers {
HitTestingTreeNode::HitTestingTreeNode(AsyncPanZoomController* aApzc,
bool aIsPrimaryHolder,
uint64_t aLayersId)
: mApzc(aApzc)
, mIsPrimaryApzcHolder(aIsPrimaryHolder)
, mLayersId(aLayersId)
, mScrollViewId(FrameMetrics::NULL_SCROLL_ID)
, mScrollbarAnimationId(0)
- , mIsScrollbarContainer(false)
, mFixedPosTarget(FrameMetrics::NULL_SCROLL_ID)
, mOverride(EventRegionsOverride::NoOverride)
{
if (mIsPrimaryApzcHolder) {
MOZ_ASSERT(mApzc);
}
MOZ_ASSERT(!mApzc || mApzc->GetLayersId() == mLayersId);
}
@@ -92,22 +91,22 @@ HitTestingTreeNode::SetLastChild(HitTest
}
}
}
void
HitTestingTreeNode::SetScrollbarData(FrameMetrics::ViewID aScrollViewId,
const uint64_t& aScrollbarAnimationId,
const ScrollThumbData& aThumbData,
- bool aIsScrollContainer)
+ const Maybe<ScrollDirection>& aScrollContainerDirection)
{
mScrollViewId = aScrollViewId;
mScrollbarAnimationId = aScrollbarAnimationId;
mScrollThumbData = aThumbData;
- mIsScrollbarContainer = aIsScrollContainer;
+ mScrollbarContainerDirection = aScrollContainerDirection;
}
bool
HitTestingTreeNode::MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const
{
return IsScrollThumbNode() &&
mScrollThumbData.mDirection == aDragMetrics.mDirection &&
mScrollViewId == aDragMetrics.mViewId;
@@ -117,17 +116,17 @@ bool
HitTestingTreeNode::IsScrollThumbNode() const
{
return mScrollThumbData.mDirection.isSome();
}
bool
HitTestingTreeNode::IsScrollbarNode() const
{
- return mIsScrollbarContainer || IsScrollThumbNode();
+ return mScrollbarContainerDirection.isSome() || IsScrollThumbNode();
}
FrameMetrics::ViewID
HitTestingTreeNode::GetScrollTargetId() const
{
return mScrollViewId;
}
@@ -341,17 +340,17 @@ HitTestingTreeNode::Dump(const char* aPr
printf_stderr("%sHitTestingTreeNode (%p) APZC (%p) g=(%s) %s%s%sr=(%s) t=(%s) c=(%s)%s%s\n",
aPrefix, this, mApzc.get(),
mApzc ? Stringify(mApzc->GetGuid()).c_str() : nsPrintfCString("l=0x%" PRIx64, mLayersId).get(),
(mOverride & EventRegionsOverride::ForceDispatchToContent) ? "fdtc " : "",
(mOverride & EventRegionsOverride::ForceEmptyHitRegion) ? "fehr " : "",
(mFixedPosTarget != FrameMetrics::NULL_SCROLL_ID) ? nsPrintfCString("fixed=%" PRIu64 " ", mFixedPosTarget).get() : "",
Stringify(mEventRegions).c_str(), Stringify(mTransform).c_str(),
mClipRegion ? Stringify(mClipRegion.ref()).c_str() : "none",
- mIsScrollbarContainer ? " scrollbar" : "",
+ mScrollbarContainerDirection.isSome() ? " scrollbar" : "",
IsScrollThumbNode() ? " scrollthumb" : "");
if (mLastChild) {
mLastChild->Dump(nsPrintfCString("%s ", aPrefix).get());
}
}
void
HitTestingTreeNode::SetApzcParent(AsyncPanZoomController* aParent)
--- a/gfx/layers/apz/src/HitTestingTreeNode.h
+++ b/gfx/layers/apz/src/HitTestingTreeNode.h
@@ -92,17 +92,17 @@ public:
const EventRegionsOverride& aOverride);
bool IsOutsideClip(const ParentLayerPoint& aPoint) const;
/* Scrollbar info */
void SetScrollbarData(FrameMetrics::ViewID aScrollViewId,
const uint64_t& aScrollbarAnimationId,
const ScrollThumbData& aThumbData,
- bool aIsScrollContainer);
+ const Maybe<ScrollDirection>& aScrollContainerDirection);
bool MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const;
bool IsScrollbarNode() const; // Scroll thumb or scrollbar container layer.
bool IsScrollThumbNode() const; // Scroll thumb container layer.
FrameMetrics::ViewID GetScrollTargetId() const;
const ScrollThumbData& GetScrollThumbData() const;
const uint64_t& GetScrollbarAnimationId() const;
/* Fixed pos info */
@@ -146,17 +146,17 @@ private:
// where IsScrollThumbNode() returns true. It holds the animation id that we
// use to move the thumb node to reflect async scrolling.
uint64_t mScrollbarAnimationId;
// This is set for scroll thumb Container layers only.
ScrollThumbData mScrollThumbData;
// This is set for scroll track Container layers only.
- bool mIsScrollbarContainer;
+ Maybe<ScrollDirection> mScrollbarContainerDirection;
FrameMetrics::ViewID mFixedPosTarget;
/* Let {L,M} be the {layer, scrollable metrics} pair that this node
* corresponds to in the layer tree. mEventRegions contains the event regions
* from L, in the case where event-regions are enabled. If event-regions are
* disabled, it will contain the visible region of L, which we use as an
* approximation to the hit region for the purposes of obscuring other layers.
--- a/gfx/layers/wr/WebRenderScrollData.cpp
+++ b/gfx/layers/wr/WebRenderScrollData.cpp
@@ -18,17 +18,16 @@ namespace mozilla {
namespace layers {
WebRenderLayerScrollData::WebRenderLayerScrollData()
: mDescendantCount(-1)
, mTransformIsPerspective(false)
, mEventRegionsOverride(EventRegionsOverride::NoOverride)
, mScrollbarAnimationId(0)
, mScrollbarTargetContainerId(FrameMetrics::NULL_SCROLL_ID)
- , mIsScrollbarContainer(false)
, mFixedPosScrollContainerId(FrameMetrics::NULL_SCROLL_ID)
{
}
WebRenderLayerScrollData::~WebRenderLayerScrollData()
{
}
@@ -113,17 +112,17 @@ WebRenderLayerScrollData::Dump(const Web
Stringify(mTransform).c_str(), mTransformIsPerspective,
Stringify(mVisibleRegion).c_str());
printf_stderr(" event regions: %s override: 0x%x\n",
Stringify(mEventRegions).c_str(), mEventRegionsOverride);
printf_stderr(" ref layers id: 0x%" PRIx64 "\n", mReferentId.valueOr(0));
//printf_stderr(" scroll thumb: %s animation: %" PRIu64 "\n",
// Stringify(mScrollThumbData).c_str(), mScrollbarAnimationId);
printf_stderr(" scroll container: %d target: %" PRIu64 "\n",
- mIsScrollbarContainer, mScrollbarTargetContainerId);
+ mScrollbarContainerDirection.isSome(), mScrollbarTargetContainerId);
printf_stderr(" fixed pos container: %" PRIu64 "\n",
mFixedPosScrollContainerId);
}
WebRenderScrollData::WebRenderScrollData()
: mManager(nullptr)
, mIsFirstPaint(false)
, mPaintSequenceNumber(0)
--- a/gfx/layers/wr/WebRenderScrollData.h
+++ b/gfx/layers/wr/WebRenderScrollData.h
@@ -76,18 +76,18 @@ public:
Maybe<uint64_t> GetReferentId() const { return mReferentId; }
void SetScrollThumbData(const ScrollThumbData& aData) { mScrollThumbData = aData; }
const ScrollThumbData& GetScrollThumbData() const { return mScrollThumbData; }
void SetScrollbarAnimationId(const uint64_t& aId) { mScrollbarAnimationId = aId; }
const uint64_t& GetScrollbarAnimationId() const { return mScrollbarAnimationId; }
void SetScrollbarTargetContainerId(FrameMetrics::ViewID aId) { mScrollbarTargetContainerId = aId; }
FrameMetrics::ViewID GetScrollbarTargetContainerId() const { return mScrollbarTargetContainerId; }
- void SetIsScrollbarContainer() { mIsScrollbarContainer = true; }
- bool IsScrollbarContainer() const { return mIsScrollbarContainer; }
+ void SetScrollbarContainerDirection(ScrollDirection aDirection) { mScrollbarContainerDirection = Some(aDirection); }
+ Maybe<ScrollDirection> GetScrollbarContainerDirection() const { return mScrollbarContainerDirection; }
void SetFixedPositionScrollContainerId(FrameMetrics::ViewID aId) { mFixedPosScrollContainerId = aId; }
FrameMetrics::ViewID GetFixedPositionScrollContainerId() const { return mFixedPosScrollContainerId; }
void Dump(const WebRenderScrollData& aOwner) const;
friend struct IPC::ParamTraits<WebRenderLayerScrollData>;
@@ -111,17 +111,17 @@ private:
bool mTransformIsPerspective;
EventRegions mEventRegions;
LayerIntRegion mVisibleRegion;
Maybe<uint64_t> mReferentId;
EventRegionsOverride mEventRegionsOverride;
ScrollThumbData mScrollThumbData;
uint64_t mScrollbarAnimationId;
FrameMetrics::ViewID mScrollbarTargetContainerId;
- bool mIsScrollbarContainer;
+ Maybe<ScrollDirection> mScrollbarContainerDirection;
FrameMetrics::ViewID mFixedPosScrollContainerId;
};
// Data needed by APZ, for the whole layer tree. One instance of this class
// is created for each transaction sent over PWebRenderBridge. It is populated
// with information from the WebRender layer tree on the client side and the
// information is used by APZ on the parent side.
class WebRenderScrollData
@@ -228,17 +228,17 @@ struct ParamTraits<mozilla::layers::WebR
WriteParam(aMsg, aParam.mTransformIsPerspective);
WriteParam(aMsg, aParam.mEventRegions);
WriteParam(aMsg, aParam.mVisibleRegion);
WriteParam(aMsg, aParam.mReferentId);
WriteParam(aMsg, aParam.mEventRegionsOverride);
WriteParam(aMsg, aParam.mScrollThumbData);
WriteParam(aMsg, aParam.mScrollbarAnimationId);
WriteParam(aMsg, aParam.mScrollbarTargetContainerId);
- WriteParam(aMsg, aParam.mIsScrollbarContainer);
+ WriteParam(aMsg, aParam.mScrollbarContainerDirection);
WriteParam(aMsg, aParam.mFixedPosScrollContainerId);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mDescendantCount)
&& ReadParam(aMsg, aIter, &aResult->mScrollIds)
@@ -246,17 +246,17 @@ struct ParamTraits<mozilla::layers::WebR
&& ReadParam(aMsg, aIter, &aResult->mTransformIsPerspective)
&& ReadParam(aMsg, aIter, &aResult->mEventRegions)
&& ReadParam(aMsg, aIter, &aResult->mVisibleRegion)
&& ReadParam(aMsg, aIter, &aResult->mReferentId)
&& ReadParam(aMsg, aIter, &aResult->mEventRegionsOverride)
&& ReadParam(aMsg, aIter, &aResult->mScrollThumbData)
&& ReadParam(aMsg, aIter, &aResult->mScrollbarAnimationId)
&& ReadParam(aMsg, aIter, &aResult->mScrollbarTargetContainerId)
- && ReadParam(aMsg, aIter, &aResult->mIsScrollbarContainer)
+ && ReadParam(aMsg, aIter, &aResult->mScrollbarContainerDirection)
&& ReadParam(aMsg, aIter, &aResult->mFixedPosScrollContainerId);
}
};
template<>
struct ParamTraits<mozilla::layers::WebRenderScrollData>
{
typedef mozilla::layers::WebRenderScrollData paramType;
--- a/gfx/layers/wr/WebRenderScrollDataWrapper.h
+++ b/gfx/layers/wr/WebRenderScrollDataWrapper.h
@@ -298,20 +298,20 @@ public:
}
FrameMetrics::ViewID GetScrollbarTargetContainerId() const
{
MOZ_ASSERT(IsValid());
return mLayer->GetScrollbarTargetContainerId();
}
- bool IsScrollbarContainer() const
+ Maybe<ScrollDirection> GetScrollbarContainerDirection() const
{
MOZ_ASSERT(IsValid());
- return mLayer->IsScrollbarContainer();
+ return mLayer->GetScrollbarContainerDirection();
}
FrameMetrics::ViewID GetFixedPositionScrollContainerId() const
{
MOZ_ASSERT(IsValid());
return mLayer->GetFixedPositionScrollContainerId();
}
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3023,22 +3023,30 @@ AppendToTop(nsDisplayListBuilder* aBuild
nsDisplayList* aSource, nsIFrame* aSourceFrame, uint32_t aFlags)
{
if (aSource->IsEmpty())
return;
nsDisplayWrapList* newItem;
const ActiveScrolledRoot* asr = aBuilder->CurrentActiveScrolledRoot();
if (aFlags & APPEND_OWN_LAYER) {
- nsDisplayOwnLayerFlags flags = (aFlags & APPEND_SCROLLBAR_CONTAINER)
- ? nsDisplayOwnLayerFlags::eScrollbarContainer
- : nsDisplayOwnLayerFlags::eNone;
- FrameMetrics::ViewID scrollTarget = (aFlags & APPEND_SCROLLBAR_CONTAINER)
- ? aBuilder->GetCurrentScrollbarTarget()
- : FrameMetrics::NULL_SCROLL_ID;
+ FrameMetrics::ViewID scrollTarget = FrameMetrics::NULL_SCROLL_ID;
+ nsDisplayOwnLayerFlags flags = aBuilder->GetCurrentScrollbarFlags();
+ // The flags here should be at most one scrollbar direction and nothing else
+ MOZ_ASSERT(flags == nsDisplayOwnLayerFlags::eNone ||
+ flags == nsDisplayOwnLayerFlags::eVerticalScrollbar ||
+ flags == nsDisplayOwnLayerFlags::eHorizontalScrollbar);
+
+ if (aFlags & APPEND_SCROLLBAR_CONTAINER) {
+ scrollTarget = aBuilder->GetCurrentScrollbarTarget();
+ // The flags here should be exactly one scrollbar direction
+ MOZ_ASSERT(flags != nsDisplayOwnLayerFlags::eNone);
+ flags |= nsDisplayOwnLayerFlags::eScrollbarContainer;
+ }
+
newItem = new (aBuilder) nsDisplayOwnLayer(aBuilder, aSourceFrame, aSource, asr, flags, scrollTarget);
} else {
newItem = new (aBuilder) nsDisplayWrapList(aBuilder, aSourceFrame, aSource, asr);
}
if (aFlags & APPEND_POSITIONED) {
// We want overlay scrollbars to always be on top of the scrolled content,
// but we don't want them to unnecessarily cover overlapping elements from
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6833,18 +6833,17 @@ nsDisplayOwnLayer::GetLayerState(nsDispl
}
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, mAnimatedGeometryRoot);
}
bool
nsDisplayOwnLayer::IsScrollThumbLayer() const
{
- return (mFlags & nsDisplayOwnLayerFlags::eVerticalScrollbar) ||
- (mFlags & nsDisplayOwnLayerFlags::eHorizontalScrollbar);
+ return mThumbData.mDirection.isSome();
}
bool
nsDisplayOwnLayer::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) const
{
// Render scroll thumb layers even if they are invisible, because async
// scrolling might bring them into view.
return IsScrollThumbLayer();
@@ -6855,37 +6854,40 @@ already_AddRefed<Layer>
nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters)
{
RefPtr<ContainerLayer> layer = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
aContainerParameters, nullptr,
FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR);
- if (mThumbData.mDirection.isSome()) {
+ if (IsScrollThumbLayer()) {
layer->SetScrollThumbData(mScrollTarget, mThumbData);
}
if (mFlags & nsDisplayOwnLayerFlags::eScrollbarContainer) {
- layer->SetIsScrollbarContainer(mScrollTarget);
+ ScrollDirection dir = (mFlags & nsDisplayOwnLayerFlags::eVerticalScrollbar)
+ ? ScrollDirection::eVertical
+ : ScrollDirection::eHorizontal;
+ layer->SetScrollbarContainer(mScrollTarget, dir);
}
if (mFlags & nsDisplayOwnLayerFlags::eGenerateSubdocInvalidations) {
mFrame->PresContext()->SetNotifySubDocInvalidationData(layer);
}
return layer.forget();
}
bool
nsDisplayOwnLayer::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
- if (!aManager->AsyncPanZoomEnabled() || mThumbData.mDirection.isNothing()) {
+ if (!aManager->AsyncPanZoomEnabled() || !IsScrollThumbLayer()) {
return nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, aSc,
aManager, aDisplayListBuilder);
}
// APZ is enabled and this is a scroll thumb, so we need to create and
// set an animation id. That way APZ can move this scrollthumb around as
// needed.
RefPtr<WebRenderAnimationData> animationData = aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
@@ -6917,17 +6919,20 @@ nsDisplayOwnLayer::UpdateScrollData(mozi
aLayerData->SetScrollThumbData(mThumbData);
aLayerData->SetScrollbarAnimationId(mWrAnimationId);
aLayerData->SetScrollbarTargetContainerId(mScrollTarget);
}
}
if (mFlags & nsDisplayOwnLayerFlags::eScrollbarContainer) {
ret = true;
if (aLayerData) {
- aLayerData->SetIsScrollbarContainer();
+ ScrollDirection dir = (mFlags & nsDisplayOwnLayerFlags::eVerticalScrollbar)
+ ? ScrollDirection::eVertical
+ : ScrollDirection::eHorizontal;
+ aLayerData->SetScrollbarContainerDirection(dir);
aLayerData->SetScrollbarTargetContainerId(mScrollTarget);
}
}
return ret;
}
nsDisplaySubDocument::nsDisplaySubDocument(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,