diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index d5fc444f69ed..4b682f0d1227 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -231,7 +231,7 @@ AccumulateLayerTransforms(Layer* aLayer, static LayerPoint GetLayerFixedMarginsOffset(Layer* aLayer, - const LayerMargin& aFixedLayerMargins) + const ScreenMargin& aFixedLayerMargins) { // Work out the necessary translation, in root scrollable layer space. // Because fixed layer margins are stored relative to the root scrollable @@ -272,7 +272,7 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer, FrameMetrics::ViewID aTransformScrollId, const Matrix4x4& aPreviousTransformForRoot, const Matrix4x4& aCurrentTransformForRoot, - const LayerMargin& aFixedLayerMargins) + const ScreenMargin& aFixedLayerMargins) { bool isRootFixedForSubtree = aLayer->GetIsFixedPosition() && aLayer->GetFixedPositionScrollContainerId() == aTransformScrollId && @@ -597,7 +597,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer) Matrix4x4 combinedAsyncTransform; bool hasAsyncTransform = false; - LayerMargin fixedLayerMargins(0, 0, 0, 0); + ScreenMargin fixedLayerMargins(0, 0, 0, 0); // Each layer has multiple clips. Its local clip, which must move with async // transforms, and its scrollframe clips, which are the clips between each @@ -1012,7 +1012,7 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer) ) * geckoZoom); displayPort += scrollOffsetLayerPixels; - LayerMargin fixedLayerMargins(0, 0, 0, 0); + ScreenMargin fixedLayerMargins(0, 0, 0, 0); // Ideally we would initialize userZoom to AsyncPanZoomController::CalculateResolution(metrics) // but this causes a reftest-ipc test to fail (see bug 883646 comment 27). The reason for this @@ -1088,6 +1088,25 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer) // when we're asynchronously panning or zooming AlignFixedAndStickyLayers(aLayer, aLayer, metrics.GetScrollId(), oldTransform, aLayer->GetLocalTransform(), fixedLayerMargins); + + // For Fennec we want to expand the root scrollable layer clip rect based on + // the fixed position margins. In particular, we want this while the dynamic + // toolbar is in the process of sliding offscreen and the area of the + // LayerView visible to the user is larger than the viewport size that Gecko + // knows about (and therefore larger than the clip rect). We could also just + // clear the clip rect on aLayer entirely but this seems more precise. + Maybe rootClipRect = aLayer->AsLayerComposite()->GetShadowClipRect(); + if (rootClipRect && fixedLayerMargins != ScreenMargin()) { +#ifndef MOZ_WIDGET_ANDROID + // We should never enter here on anything other than Fennec, since + // fixedLayerMargins should be empty everywhere else. + MOZ_ASSERT(false); +#endif + ParentLayerRect rect(rootClipRect.value()); + rect.Deflate(ViewAs(fixedLayerMargins, + PixelCastJustification::ScreenIsParentLayerForRoot)); + aLayer->AsLayerComposite()->SetShadowClipRect(Some(RoundedOut(rect))); + } } void @@ -1180,7 +1199,7 @@ AsyncCompositionManager::SyncViewportInfo(const LayerIntRect& aDisplayPort, bool aLayersUpdated, ParentLayerPoint& aScrollOffset, CSSToParentLayerScale& aScale, - LayerMargin& aFixedLayerMargins) + ScreenMargin& aFixedLayerMargins) { #ifdef MOZ_WIDGET_ANDROID AndroidBridge::Bridge()->SyncViewportInfo(aDisplayPort, @@ -1200,7 +1219,7 @@ AsyncCompositionManager::SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, bool aIsFirstPaint, - LayerMargin& aFixedLayerMargins) + ScreenMargin& aFixedLayerMargins) { #ifdef MOZ_WIDGET_ANDROID AndroidBridge::Bridge()->SyncFrameMetrics(aScrollOffset, aZoom, aCssPageRect, diff --git a/gfx/layers/composite/AsyncCompositionManager.h b/gfx/layers/composite/AsyncCompositionManager.h index a6cea14b34d1..2434390d793c 100644 --- a/gfx/layers/composite/AsyncCompositionManager.h +++ b/gfx/layers/composite/AsyncCompositionManager.h @@ -141,7 +141,7 @@ private: bool aLayersUpdated, ParentLayerPoint& aScrollOffset, CSSToParentLayerScale& aScale, - LayerMargin& aFixedLayerMargins); + ScreenMargin& aFixedLayerMargins); void SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect, @@ -149,7 +149,7 @@ private: const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, bool aIsFirstPaint, - LayerMargin& aFixedLayerMargins); + ScreenMargin& aFixedLayerMargins); /** * Adds a translation to the transform of any fixed position (whose parent @@ -170,7 +170,7 @@ private: FrameMetrics::ViewID aTransformScrollId, const gfx::Matrix4x4& aPreviousTransformForRoot, const gfx::Matrix4x4& aCurrentTransformForRoot, - const LayerMargin& aFixedLayerMargins); + const ScreenMargin& aFixedLayerMargins); /** * DRAWING PHASE ONLY diff --git a/layout/base/UnitTransforms.h b/layout/base/UnitTransforms.h index 058b584e95fe..493ae3a6ec72 100644 --- a/layout/base/UnitTransforms.h +++ b/layout/base/UnitTransforms.h @@ -69,6 +69,14 @@ template gfx::IntRectTyped ViewAs(const gfx::IntRectTyped& aRect, PixelCastJustification) { return gfx::IntRectTyped(aRect.x, aRect.y, aRect.width, aRect.height); } +template +gfx::MarginTyped ViewAs(const gfx::MarginTyped& aMargin, PixelCastJustification) { + return gfx::MarginTyped(aMargin.top, aMargin.right, aMargin.bottom, aMargin.left); +} +template +gfx::IntMarginTyped ViewAs(const gfx::IntMarginTyped& aMargin, PixelCastJustification) { + return gfx::IntMarginTyped(aMargin.top, aMargin.right, aMargin.bottom, aMargin.left); +} template gfx::ScaleFactor ViewTargetAs( const gfx::ScaleFactor& aScaleFactor, diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index 45d691aa6069..30727d531724 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -1455,7 +1455,7 @@ AndroidBridge::SetPageRect(const CSSRect& aCssPageRect) void AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, bool aLayersUpdated, ParentLayerPoint& aScrollOffset, CSSToParentLayerScale& aScale, - LayerMargin& aFixedLayerMargins) + ScreenMargin& aFixedLayerMargins) { if (!mLayerClient) { ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); @@ -1479,7 +1479,7 @@ AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLay void AndroidBridge::SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect, bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, - bool aIsFirstPaint, LayerMargin& aFixedLayerMargins) + bool aIsFirstPaint, ScreenMargin& aFixedLayerMargins) { if (!mLayerClient) { ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); diff --git a/widget/android/AndroidBridge.h b/widget/android/AndroidBridge.h index 9527b635831e..f79dd8387431 100644 --- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -252,10 +252,10 @@ public: void SetPageRect(const CSSRect& aCssPageRect); void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, bool aLayersUpdated, ParentLayerPoint& aScrollOffset, CSSToParentLayerScale& aScale, - LayerMargin& aFixedLayerMargins); + ScreenMargin& aFixedLayerMargins); void SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect, bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, - bool aIsFirstPaint, LayerMargin& aFixedLayerMargins); + bool aIsFirstPaint, ScreenMargin& aFixedLayerMargins); void AddPluginView(jobject view, const LayoutDeviceRect& rect, bool isFullScreen);