зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1509575 - Extend the internal visual scroll API to allow specifying "restore" vs. regular priority. r=kats
The distinction is not exposed at the JS level which currently always uses "restore", but it could be if necessary. Differential Revision: https://phabricator.services.mozilla.com/D16346 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
d5f06efae5
Коммит
e99815f1f0
|
@ -1406,8 +1406,12 @@ nsDOMWindowUtils::ScrollToVisual(float aOffsetX, float aOffsetY) {
|
|||
// This should only be called on the root content document.
|
||||
NS_ENSURE_TRUE(presContext->IsRootContentDocument(), NS_ERROR_INVALID_ARG);
|
||||
|
||||
presContext->PresShell()->SetPendingVisualViewportOffset(
|
||||
Some(CSSPoint::ToAppUnits(CSSPoint(aOffsetX, aOffsetY))));
|
||||
// Use |eRestore| as the priority for now, as it's the conservative choice.
|
||||
// If a JS call site needs higher priority, we can expose the update type
|
||||
// as a parameter.
|
||||
presContext->PresShell()->SetPendingVisualScrollUpdate(
|
||||
CSSPoint::ToAppUnits(CSSPoint(aOffsetX, aOffsetY)),
|
||||
FrameMetrics::eRestore);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -4262,8 +4262,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(
|
|||
(aLayerMetrics.GetScrollGeneration() != Metrics().GetScrollGeneration());
|
||||
|
||||
if (scrollOffsetUpdated && userScrolled &&
|
||||
aLayerMetrics.GetScrollUpdateType() ==
|
||||
FrameMetrics::ScrollOffsetUpdateType::eRestore) {
|
||||
aLayerMetrics.GetScrollUpdateType() == FrameMetrics::eRestore) {
|
||||
APZC_LOG(
|
||||
"%p dropping scroll update of type eRestore because of user scroll\n",
|
||||
this);
|
||||
|
@ -4274,6 +4273,23 @@ void AsyncPanZoomController::NotifyLayersUpdated(
|
|||
aLayerMetrics.GetDoSmoothScroll() &&
|
||||
(aLayerMetrics.GetScrollGeneration() != Metrics().GetScrollGeneration());
|
||||
|
||||
// The main thread may also ask us to scroll the visual viewport to a
|
||||
// particular location. This is different from a layout viewport offset update
|
||||
// in that the layout viewport offset is limited to the layout scroll range
|
||||
// (this will be enforced by the main thread once bug 1516056 is fixed),
|
||||
// while the visual viewport offset is not.
|
||||
// The update type indicates the priority; an eMainThread layout update (or
|
||||
// a smooth scroll request which is similar) takes precedence over an eRestore
|
||||
// visual update, but we allow the possibility for the main thread to ask us
|
||||
// to scroll both the layout and visual viewports to distinct (but compatible)
|
||||
// locations (via e.g. both updates being eRestore).
|
||||
bool visualScrollOffsetUpdated =
|
||||
aLayerMetrics.GetVisualScrollUpdateType() != FrameMetrics::eNone;
|
||||
if (aLayerMetrics.GetScrollUpdateType() == FrameMetrics::eMainThread ||
|
||||
smoothScrollRequested) {
|
||||
visualScrollOffsetUpdated = false;
|
||||
}
|
||||
|
||||
// TODO if we're in a drag and scrollOffsetUpdated is set then we want to
|
||||
// ignore it
|
||||
|
||||
|
@ -4500,18 +4516,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(
|
|||
SmoothScrollTo(Metrics().GetSmoothScrollOffset());
|
||||
}
|
||||
|
||||
// If the main thread asked us to scroll the visual viewport to a particular
|
||||
// location, do so. This is different from a layout viewport offset update
|
||||
// in that the layout viewport offset is limited to the layout scroll range
|
||||
// (this will be enforced by the main thread once bug 1516056 is fixed),
|
||||
// while the visual viewport offset is not. The main thread can also ask
|
||||
// us to scroll both the layout and visual viewports to distinct (but
|
||||
// compatible) locations.
|
||||
FrameMetrics::ScrollOffsetUpdateType visualUpdateType =
|
||||
aLayerMetrics.GetVisualScrollUpdateType();
|
||||
MOZ_ASSERT(visualUpdateType == FrameMetrics::eNone ||
|
||||
visualUpdateType == FrameMetrics::eMainThread);
|
||||
if (visualUpdateType == FrameMetrics::eMainThread) {
|
||||
if (visualScrollOffsetUpdated) {
|
||||
Metrics().ClampAndSetScrollOffset(aLayerMetrics.GetVisualViewportOffset());
|
||||
|
||||
// The rest of this branch largely follows the code in the
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "mozilla/StyleSheet.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "FrameMetrics.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "gfxPoint.h"
|
||||
#include "nsTHashtable.h"
|
||||
|
@ -176,6 +177,7 @@ class nsIPresShell : public nsStubDocumentObserver {
|
|||
|
||||
protected:
|
||||
typedef mozilla::dom::Document Document;
|
||||
typedef mozilla::layers::FrameMetrics FrameMetrics;
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
typedef mozilla::gfx::SourceSurface SourceSurface;
|
||||
|
||||
|
@ -1660,18 +1662,32 @@ class nsIPresShell : public nsStubDocumentObserver {
|
|||
|
||||
nsPoint GetVisualViewportOffsetRelativeToLayoutViewport() const;
|
||||
|
||||
// Ask APZ in the next transaction to scroll to the given visual viewport
|
||||
// Represents an update to the visual scroll offset that will be sent to APZ.
|
||||
// The update type is used to determine priority compared to other scroll
|
||||
// updates.
|
||||
struct VisualScrollUpdate {
|
||||
nsPoint mVisualScrollOffset;
|
||||
FrameMetrics::ScrollOffsetUpdateType mUpdateType;
|
||||
};
|
||||
|
||||
// Ask APZ in the next transaction to scroll to the given visual viewport
|
||||
// offset (relative to the document).
|
||||
// Use this sparingly, as it will clobber JS-driven scrolling that happens
|
||||
// in the same frame. This is mostly intended to be used in special
|
||||
// situations like "first paint" or session restore.
|
||||
// Please request APZ review if adding a new call site.
|
||||
void SetPendingVisualViewportOffset(
|
||||
const mozilla::Maybe<nsPoint>& aPendingVisualViewportOffset) {
|
||||
mPendingVisualViewportOffset = aPendingVisualViewportOffset;
|
||||
void SetPendingVisualScrollUpdate(
|
||||
const nsPoint& aVisualViewportOffset,
|
||||
FrameMetrics::ScrollOffsetUpdateType aUpdateType) {
|
||||
mPendingVisualScrollUpdate =
|
||||
mozilla::Some(VisualScrollUpdate{aVisualViewportOffset, aUpdateType});
|
||||
}
|
||||
const mozilla::Maybe<nsPoint>& GetPendingVisualViewportOffset() const {
|
||||
return mPendingVisualViewportOffset;
|
||||
void ClearPendingVisualScrollUpdate() {
|
||||
mPendingVisualScrollUpdate = mozilla::Nothing();
|
||||
}
|
||||
const mozilla::Maybe<VisualScrollUpdate>& GetPendingVisualScrollUpdate()
|
||||
const {
|
||||
return mPendingVisualScrollUpdate;
|
||||
}
|
||||
|
||||
nsPoint GetLayoutViewportOffset() const;
|
||||
|
@ -1755,10 +1771,10 @@ class nsIPresShell : public nsStubDocumentObserver {
|
|||
|
||||
nsPoint mVisualViewportOffset;
|
||||
|
||||
// A pending visual viewport offset that we will ask APZ to scroll to
|
||||
// A pending visual scroll offset that we will ask APZ to scroll to
|
||||
// during the next transaction. Cleared when we send the transaction.
|
||||
// Only applicable to the RCD pres shell.
|
||||
mozilla::Maybe<nsPoint> mPendingVisualViewportOffset;
|
||||
mozilla::Maybe<VisualScrollUpdate> mPendingVisualScrollUpdate;
|
||||
|
||||
// A list of stack weak frames. This is a pointer to the last item in the
|
||||
// list.
|
||||
|
|
|
@ -8708,11 +8708,12 @@ static void MaybeReflowForInflationScreenSizeChange(
|
|||
metrics.SetBaseScrollOffset(apzScrollPosition);
|
||||
|
||||
if (aIsRootContent) {
|
||||
if (const Maybe<nsPoint>& visualOffset =
|
||||
presShell->GetPendingVisualViewportOffset()) {
|
||||
metrics.SetVisualViewportOffset(CSSPoint::FromAppUnits(*visualOffset));
|
||||
metrics.SetVisualScrollUpdateType(FrameMetrics::eMainThread);
|
||||
presShell->SetPendingVisualViewportOffset(Nothing());
|
||||
if (const Maybe<nsIPresShell::VisualScrollUpdate>& visualUpdate =
|
||||
presShell->GetPendingVisualScrollUpdate()) {
|
||||
metrics.SetVisualViewportOffset(
|
||||
CSSPoint::FromAppUnits(visualUpdate->mVisualScrollOffset));
|
||||
metrics.SetVisualScrollUpdateType(visualUpdate->mUpdateType);
|
||||
presShell->ClearPendingVisualScrollUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче