Skip to content

Commit

Permalink
Temporary return updateScrollOffset API
Browse files Browse the repository at this point in the history
  • Loading branch information
tmeshkova committed Jan 8, 2014
1 parent d8f10d7 commit 805e0bd
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 13 deletions.
7 changes: 7 additions & 0 deletions dom/ipc/PBrowser.ipdl
Expand Up @@ -296,6 +296,13 @@ parent:
UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId, bool aIsRoot,
bool aAllowZoom, CSSToScreenScale aMinZoom, CSSToScreenScale aMaxZoom);

/**
* Notifies the parent about a scroll event. The pres shell ID and
* view ID identify which scrollable (sub-)frame was scrolled, and
* the new scroll offset for that frame is sent.
*/
UpdateScrollOffset(uint32_t aPresShellId, ViewID aViewId, CSSIntPoint aScrollOffset);

__delete__();

child:
Expand Down
49 changes: 49 additions & 0 deletions dom/ipc/TabChild.cpp
Expand Up @@ -299,6 +299,53 @@ TabChild::HandleEvent(nsIDOMEvent* aEvent)
// This meta data may or may not have been a meta viewport tag. If it was,
// we should handle it immediately.
HandlePossibleViewportChange();
} else if (eventType.EqualsLiteral("scroll")) {
nsCOMPtr<nsIDOMEventTarget> target;
aEvent->GetTarget(getter_AddRefs(target));

ViewID viewId;
uint32_t presShellId;

nsCOMPtr<nsIContent> content;
if (nsCOMPtr<nsIDocument> doc = do_QueryInterface(target))
content = doc->GetDocumentElement();
else
content = do_QueryInterface(target);

nsCOMPtr<nsIDOMWindowUtils> utils = APZCCallbackHelper::GetDOMWindowUtils(content);
utils->GetPresShellId(&presShellId);

if (!nsLayoutUtils::FindIDFor(content, &viewId))
return NS_ERROR_UNEXPECTED;

nsIScrollableFrame* scrollFrame = nsLayoutUtils::FindScrollableFrameFor(viewId);
if (!scrollFrame)
return NS_OK;

CSSIntPoint scrollOffset = scrollFrame->GetScrollPositionCSSPixels();

if (viewId == mLastRootMetrics.mScrollId) {
// We store the last metrics that was sent via the TabParent (This is
// updated in ProcessUpdateFrame and RecvUpdateFrame).
// We use this here to avoid sending APZC back a scroll event that
// originally came from APZC (besides being unnecessary, the event might
// be slightly out of date by the time it reaches APZC).
if (RoundedToInt(mLastRootMetrics.mScrollOffset) == scrollOffset) {
return NS_OK;
}

// Update the last scroll offset now, otherwise RecvUpdateDimensions()
// might trigger a scroll to the old offset before RecvUpdateFrame()
// gets a chance to update it.
mLastRootMetrics.mScrollOffset = scrollOffset;
} else if (viewId == mLastSubFrameMetrics.mScrollId) {
if (RoundedToInt(mLastSubFrameMetrics.mScrollOffset) == scrollOffset) {
return NS_OK;
}
mLastSubFrameMetrics.mScrollOffset = scrollOffset;
}

SendUpdateScrollOffset(presShellId, viewId, scrollOffset);
}

return NS_OK;
Expand Down Expand Up @@ -1502,6 +1549,7 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
if (content) {
FrameMetrics newSubFrameMetrics(aFrameMetrics);
APZCCallbackHelper::UpdateSubFrame(content, newSubFrameMetrics);
mLastSubFrameMetrics = newSubFrameMetrics;
return true;
}
}
Expand Down Expand Up @@ -2196,6 +2244,7 @@ TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
root->SetParentTarget(scope);

chromeHandler->AddEventListener(NS_LITERAL_STRING("DOMMetaAdded"), this, false);
chromeHandler->AddEventListener(NS_LITERAL_STRING("scroll"), this, true);
}

if (aScriptLoading != DONT_LOAD_SCRIPTS && !mTriedBrowserInit) {
Expand Down
1 change: 1 addition & 0 deletions dom/ipc/TabChild.h
Expand Up @@ -469,6 +469,7 @@ class TabChild : public PBrowserChild,
nsCOMPtr<nsIWidget> mWidget;
nsCOMPtr<nsIURI> mLastURI;
FrameMetrics mLastRootMetrics;
FrameMetrics mLastSubFrameMetrics;
RenderFrameChild* mRemoteFrame;
nsRefPtr<ContentChild> mManager;
nsRefPtr<TabChildGlobal> mTabChildGlobal;
Expand Down
11 changes: 11 additions & 0 deletions dom/ipc/TabParent.cpp
Expand Up @@ -1721,6 +1721,17 @@ TabParent::RecvUpdateZoomConstraints(const uint32_t& aPresShellId,
return true;
}

bool
TabParent::RecvUpdateScrollOffset(const uint32_t& aPresShellId,
const ViewID& aViewId,
const CSSIntPoint& aScrollOffset)
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->UpdateScrollOffset(aPresShellId, aViewId, aScrollOffset);
}
return true;
}

bool
TabParent::RecvContentReceivedTouch(const ScrollableLayerGuid& aGuid,
const bool& aPreventDefault)
Expand Down
1 change: 1 addition & 0 deletions dom/ipc/TabParent.h
Expand Up @@ -171,6 +171,7 @@ class TabParent : public PBrowserParent
const bool& aAllowZoom,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom);
virtual bool RecvUpdateScrollOffset(const uint32_t& aPresShellId, const ViewID& aViewId, const CSSIntPoint& aScrollOffset);
virtual bool RecvContentReceivedTouch(const ScrollableLayerGuid& aGuid,
const bool& aPreventDefault);
virtual PContentDialogParent* AllocPContentDialogParent(const uint32_t& aType,
Expand Down
4 changes: 4 additions & 0 deletions embedding/embedlite/embedthread/EmbedLiteViewThreadParent.cpp
Expand Up @@ -275,6 +275,10 @@ EmbedLiteViewThreadParent::RecvUpdateScrollOffset(const uint32_t& aPresShellId,
const ViewID& aViewId,
const CSSIntPoint& aScrollOffset)
{
if (mController) {
// TODO: currently aPresShelId and aViewId aren't used (But they're used in TabChild to dispatch many APZCs).
mController->GetManager()->UpdateScrollOffset(ScrollableLayerGuid(mRootLayerTreeId, 0, 0), aScrollOffset);
}
return true;
}

Expand Down
45 changes: 45 additions & 0 deletions embedding/embedlite/utils/TabChildHelper.cpp
Expand Up @@ -293,6 +293,51 @@ TabChildHelper::HandleEvent(nsIDOMEvent* aEvent)
// This meta data may or may not have been a meta viewport tag. If it was,
// we should handle it immediately.
HandlePossibleViewportChange();
} else if (eventType.EqualsLiteral("scroll")) {
// Handle a scroll event originated from content.
nsCOMPtr<nsIDOMEventTarget> target;
aEvent->GetTarget(getter_AddRefs(target));

FrameMetrics::ViewID viewId;
uint32_t presShellId;

nsCOMPtr<nsIContent> content;
if (nsCOMPtr<nsIDocument> doc = do_QueryInterface(target))
content = doc->GetDocumentElement();
else
content = do_QueryInterface(target);

nsCOMPtr<nsIDOMWindowUtils> utils = ::GetDOMWindowUtils(content);
utils->GetPresShellId(&presShellId);

if (!nsLayoutUtils::FindIDFor(content, &viewId))
return NS_ERROR_UNEXPECTED;

nsIScrollableFrame* scrollFrame = nsLayoutUtils::FindScrollableFrameFor(viewId);
if (!scrollFrame)
return NS_OK;

CSSIntPoint scrollOffset = scrollFrame->GetScrollPositionCSSPixels();

if (viewId == mLastMetrics.mScrollId) {
// For the root frame, we store the last metrics, including the last
// scroll offset, sent by APZC. (This is updated in ProcessUpdateFrame()).
// We use this here to avoid sending APZC back a scroll event that
// originally came from APZC (besides being unnecessary, the event might
// be slightly out of date by the time it reaches APZC).
// We should probably do this for subframes, too.
if (RoundedToInt(mLastMetrics.mScrollOffset) == scrollOffset) {
return NS_OK;
}

// Update the last scroll offset now, otherwise RecvUpdateDimensions()
// might trigger a scroll to the old offset before RecvUpdateFrame()
// gets a chance to update it.
mLastMetrics.mScrollOffset = scrollOffset;
}

// TODO: currently presShellId, viewId are not used in EmbedLiteViewThread
mView->SendUpdateScrollOffset(presShellId, viewId, scrollOffset);
}

return NS_OK;
Expand Down
10 changes: 10 additions & 0 deletions gfx/layers/composite/APZCTreeManager.cpp
Expand Up @@ -619,6 +619,16 @@ APZCTreeManager::UpdateZoomConstraintsRecursively(AsyncPanZoomController* aApzc,
}
}

void
APZCTreeManager::UpdateScrollOffset(const ScrollableLayerGuid& aGuid,
const CSSPoint& aScrollOffset)
{
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
if (apzc) {
apzc->UpdateScrollOffset(aScrollOffset);
}
}

void
APZCTreeManager::CancelAnimation(const ScrollableLayerGuid &aGuid)
{
Expand Down
8 changes: 8 additions & 0 deletions gfx/layers/composite/APZCTreeManager.h
Expand Up @@ -172,6 +172,14 @@ class APZCTreeManager {
const CSSToScreenScale& aMinScale,
const CSSToScreenScale& aMaxScale);

/**
* Update mFrameMetrics.mScrollOffset to the given offset.
* This is necessary in cases where a scroll is not caused by user
* input (for example, a content scrollTo()).
*/
void UpdateScrollOffset(const ScrollableLayerGuid& aGuid,
const CSSPoint& aScrollOffset);

/**
* Cancels any currently running animation. Note that all this does is set the
* state of the AsyncPanZoomController back to NOTHING, but it is the
Expand Down
25 changes: 12 additions & 13 deletions gfx/layers/ipc/AsyncPanZoomController.cpp
Expand Up @@ -61,16 +61,15 @@
#define APZC_LOG_FM(fm, prefix, ...) \
APZC_LOG(prefix ":" \
" i=(%ld %lld) cb=(%d %d %d %d) dp=(%.3f %.3f %.3f %.3f) v=(%.3f %.3f %.3f %.3f) " \
"s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) %d\n", \
"s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f)\n", \
__VA_ARGS__, \
fm.mPresShellId, fm.mScrollId, \
fm.mCompositionBounds.x, fm.mCompositionBounds.y, fm.mCompositionBounds.width, fm.mCompositionBounds.height, \
fm.mDisplayPort.x, fm.mDisplayPort.y, fm.mDisplayPort.width, fm.mDisplayPort.height, \
fm.mViewport.x, fm.mViewport.y, fm.mViewport.width, fm.mViewport.height, \
fm.mScrollOffset.x, fm.mScrollOffset.y, \
fm.mScrollableRect.x, fm.mScrollableRect.y, fm.mScrollableRect.width, fm.mScrollableRect.height, \
fm.mDevPixelsPerCSSPixel.scale, fm.mResolution.scale, fm.mCumulativeResolution.scale, fm.mZoom.scale, \
fm.mUpdateScrollOffset); \
fm.mDevPixelsPerCSSPixel.scale, fm.mResolution.scale, fm.mCumulativeResolution.scale, fm.mZoom.scale); \

// Static helper functions
namespace {
Expand Down Expand Up @@ -1463,16 +1462,6 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
mFrameMetrics.mZoom.scale *= parentResolutionChange;
mFrameMetrics.mResolution = aLayerMetrics.mResolution;
mFrameMetrics.mCumulativeResolution = aLayerMetrics.mCumulativeResolution;

// If the layers update was not triggered by our own repaint request, then
// we want to take the new scroll offset.
if (aLayerMetrics.mUpdateScrollOffset) {
APZC_LOG("Updating scroll offset from (%f, %f) to (%f, %f)\n",
mFrameMetrics.mScrollOffset.x, mFrameMetrics.mScrollOffset.y,
aLayerMetrics.mScrollOffset.x, aLayerMetrics.mScrollOffset.y);

mFrameMetrics.mScrollOffset = aLayerMetrics.mScrollOffset;
}
}

if (needContentRepaint) {
Expand Down Expand Up @@ -1720,6 +1709,16 @@ void AsyncPanZoomController::SendAsyncScrollEvent() {
controller->ScrollUpdate(scrollOffset, resolution.scale);
}

void AsyncPanZoomController::UpdateScrollOffset(const CSSPoint& aScrollOffset)
{
APZC_LOG("Updating scroll offset from (%f, %f) to (%f, %f)\n",
mFrameMetrics.mScrollOffset.x, mFrameMetrics.mScrollOffset.y,
aScrollOffset.x, aScrollOffset.y);

ReentrantMonitorAutoEnter lock(mMonitor);
mFrameMetrics.mScrollOffset = aScrollOffset;
}

bool AsyncPanZoomController::Matches(const ScrollableLayerGuid& aGuid)
{
return aGuid == ScrollableLayerGuid(mLayersId, mFrameMetrics);
Expand Down
7 changes: 7 additions & 0 deletions gfx/layers/ipc/AsyncPanZoomController.h
Expand Up @@ -260,6 +260,13 @@ class AsyncPanZoomController {
*/
static void SetFrameTime(const TimeStamp& aMilliseconds);

/**
* Update mFrameMetrics.mScrollOffset to the given offset.
* This is necessary in cases where a scroll is not caused by user
* input (for example, a content scrollTo()).
*/
void UpdateScrollOffset(const CSSPoint& aScrollOffset);

void StartAnimation(AsyncPanZoomAnimation* aAnimation);

/**
Expand Down
9 changes: 9 additions & 0 deletions layout/ipc/RenderFrameParent.cpp
Expand Up @@ -1119,6 +1119,15 @@ RenderFrameParent::UpdateZoomConstraints(uint32_t aPresShellId,
}
}

void
RenderFrameParent::UpdateScrollOffset(uint32_t aPresShellId, ViewID aViewId, const CSSIntPoint& aScrollOffset)
{
if (GetApzcTreeManager()) {
GetApzcTreeManager()->UpdateScrollOffset(ScrollableLayerGuid(mLayersId, aPresShellId, aViewId),
aScrollOffset);
}
}

bool
RenderFrameParent::HitTest(const nsRect& aRect)
{
Expand Down
4 changes: 4 additions & 0 deletions layout/ipc/RenderFrameParent.h
Expand Up @@ -124,6 +124,10 @@ class RenderFrameParent : public PRenderFrameParent,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom);

void UpdateScrollOffset(uint32_t aPresShellId,
ViewID aViewId,
const CSSIntPoint& aScrollOffset);

bool HitTest(const nsRect& aRect);

protected:
Expand Down

0 comments on commit 805e0bd

Please sign in to comment.