Bug 1367765 - Factor out a SetupScrollbarDrag() helper function. r=rhunt
MozReview-Commit-ID: 9IMZRMUHpDy
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1039,71 +1039,18 @@ APZCTreeManager::ReceiveInputEvent(Input
}
result = mInputQueue->ReceiveInputEvent(
apzc, targetConfirmed,
mouseInput, aOutInputBlockId);
// If we're starting an async scrollbar drag
if (apzDragEnabled && startsDrag && hitScrollbarNode &&
hitScrollbarNode->IsScrollThumbNode() &&
- hitScrollbarNode->GetScrollThumbData().mIsAsyncDraggable &&
- mInputQueue->GetCurrentDragBlock()) {
- DragBlockState* dragBlock = mInputQueue->GetCurrentDragBlock();
- const ScrollThumbData& thumbData = hitScrollbarNode->GetScrollThumbData();
-
- // Record the thumb's position at the start of the drag.
- // We snap back to this position if, during the drag, the mouse
- // gets sufficiently far away from the scrollbar.
- dragBlock->SetInitialThumbPos(thumbData.mThumbStart);
-
- // Under some conditions, we can confirm the drag block right away.
- // Otherwise, we have to wait for a main-thread confirmation.
- if (gfxPrefs::APZDragInitiationEnabled() &&
- // check that the scrollbar's target scroll frame is layerized
- hitScrollbarNode->GetScrollTargetId() == apzc->GetGuid().mScrollId &&
- !apzc->IsScrollInfoLayer()) {
- uint64_t dragBlockId = dragBlock->GetBlockId();
- // AsyncPanZoomController::HandleInputEvent() will call
- // TransformToLocal() on the event, but we need its mLocalOrigin now
- // to compute a drag start offset for the AsyncDragMetrics.
- mouseInput.TransformToLocal(apzc->GetTransformToThis());
- CSSCoord dragStart = apzc->ConvertScrollbarPoint(
- mouseInput.mLocalOrigin, thumbData);
- // ConvertScrollbarPoint() got the drag start offset relative to
- // the scroll track. Now get it relative to the thumb.
- // ScrollThumbData::mThumbStart stores the offset of the thumb
- // relative to the scroll track at the time of the last paint.
- // Since that paint, the thumb may have acquired an async transform
- // due to async scrolling, so look that up and apply it.
- LayerToParentLayerMatrix4x4 thumbTransform;
- {
- MutexAutoLock lock(mTreeLock);
- thumbTransform = ComputeTransformForNode(hitScrollbarNode);
- }
- // Only consider the translation, since we do not support both
- // zooming and scrollbar dragging on any platform.
- CSSCoord thumbStart = thumbData.mThumbStart
- + ((thumbData.mDirection == ScrollDirection::HORIZONTAL)
- ? thumbTransform._41 : thumbTransform._42);
- dragStart -= thumbStart;
-
- // Content can't prevent scrollbar dragging with preventDefault(),
- // so we don't need to wait for a content response. It's important
- // to do this before calling ConfirmDragBlock() since that can
- // potentially process and consume the block.
- dragBlock->SetContentResponse(false);
-
- mInputQueue->ConfirmDragBlock(
- dragBlockId, apzc,
- AsyncDragMetrics(apzc->GetGuid().mScrollId,
- apzc->GetGuid().mPresShellId,
- dragBlockId,
- dragStart,
- thumbData.mDirection));
- }
+ hitScrollbarNode->GetScrollThumbData().mIsAsyncDraggable) {
+ SetupScrollbarDrag(mouseInput, hitScrollbarNode.get(), apzc.get());
}
if (result == nsEventStatus_eConsumeDoDefault) {
// This input event is part of a drag block, so whether or not it is
// directed at a scrollbar depends on whether the drag block started
// on a scrollbar.
hitScrollbar = mInputQueue->IsDragOnScrollbar(hitScrollbar);
}
@@ -1541,16 +1488,80 @@ APZCTreeManager::ProcessTouchInput(Multi
mHitResultForInputBlock = HitNothing;
mRetainedTouchIdentifier = -1;
}
return result;
}
void
+APZCTreeManager::SetupScrollbarDrag(MouseInput& aMouseInput,
+ const HitTestingTreeNode* aScrollThumbNode,
+ AsyncPanZoomController* aApzc)
+{
+ DragBlockState* dragBlock = mInputQueue->GetCurrentDragBlock();
+ if (!dragBlock) {
+ return;
+ }
+
+ const ScrollThumbData& thumbData = aScrollThumbNode->GetScrollThumbData();
+
+ // Record the thumb's position at the start of the drag.
+ // We snap back to this position if, during the drag, the mouse
+ // gets sufficiently far away from the scrollbar.
+ dragBlock->SetInitialThumbPos(thumbData.mThumbStart);
+
+ // Under some conditions, we can confirm the drag block right away.
+ // Otherwise, we have to wait for a main-thread confirmation.
+ if (gfxPrefs::APZDragInitiationEnabled() &&
+ // check that the scrollbar's target scroll frame is layerized
+ aScrollThumbNode->GetScrollTargetId() == aApzc->GetGuid().mScrollId &&
+ !aApzc->IsScrollInfoLayer()) {
+ uint64_t dragBlockId = dragBlock->GetBlockId();
+ // AsyncPanZoomController::HandleInputEvent() will call
+ // TransformToLocal() on the event, but we need its mLocalOrigin now
+ // to compute a drag start offset for the AsyncDragMetrics.
+ aMouseInput.TransformToLocal(aApzc->GetTransformToThis());
+ CSSCoord dragStart = aApzc->ConvertScrollbarPoint(
+ aMouseInput.mLocalOrigin, thumbData);
+ // ConvertScrollbarPoint() got the drag start offset relative to
+ // the scroll track. Now get it relative to the thumb.
+ // ScrollThumbData::mThumbStart stores the offset of the thumb
+ // relative to the scroll track at the time of the last paint.
+ // Since that paint, the thumb may have acquired an async transform
+ // due to async scrolling, so look that up and apply it.
+ LayerToParentLayerMatrix4x4 thumbTransform;
+ {
+ MutexAutoLock lock(mTreeLock);
+ thumbTransform = ComputeTransformForNode(aScrollThumbNode);
+ }
+ // Only consider the translation, since we do not support both
+ // zooming and scrollbar dragging on any platform.
+ CSSCoord thumbStart = thumbData.mThumbStart
+ + ((thumbData.mDirection == ScrollDirection::HORIZONTAL)
+ ? thumbTransform._41 : thumbTransform._42);
+ dragStart -= thumbStart;
+
+ // Content can't prevent scrollbar dragging with preventDefault(),
+ // so we don't need to wait for a content response. It's important
+ // to do this before calling ConfirmDragBlock() since that can
+ // potentially process and consume the block.
+ dragBlock->SetContentResponse(false);
+
+ mInputQueue->ConfirmDragBlock(
+ dragBlockId, aApzc,
+ AsyncDragMetrics(aApzc->GetGuid().mScrollId,
+ aApzc->GetGuid().mPresShellId,
+ dragBlockId,
+ dragStart,
+ thumbData.mDirection));
+ }
+}
+
+void
APZCTreeManager::UpdateWheelTransaction(LayoutDeviceIntPoint aRefPoint,
EventMessage aEventMessage)
{
WheelBlockState* txn = mInputQueue->GetActiveWheelTransaction();
if (!txn) {
return;
}
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -528,16 +528,32 @@ private:
already_AddRefed<AsyncPanZoomController> GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const MultiTouchInput& aEvent,
nsTArray<TouchBehaviorFlags>* aOutTouchBehaviors,
HitTestResult* aOutHitResult);
nsEventStatus ProcessTouchInput(MultiTouchInput& aInput,
ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutInputBlockId);
+ /**
+ * Given a mouse-down event that hit a scroll thumb node, set up APZ
+ * dragging of the scroll thumb.
+ *
+ * Must be called after the mouse event has been sent to InputQueue.
+ *
+ * @param aMouseInput The mouse-down event.
+ * @param aScrollThumbNode Tthe scroll thumb node that was hit.
+ * @param aApzc
+ * The APZC for the scroll frame scrolled by the scroll thumb, if that
+ * scroll frame is layerized. (A thumb can be layerized without its
+ * target scroll frame being layerized.) Otherwise, an enclosing APZC.
+ */
+ void SetupScrollbarDrag(MouseInput& aMouseInput,
+ const HitTestingTreeNode* aScrollThumbNode,
+ AsyncPanZoomController* aApzc);
void FlushRepaintsToClearScreenToGeckoTransform();
already_AddRefed<HitTestingTreeNode> RecycleOrCreateNode(TreeBuildingState& aState,
AsyncPanZoomController* aApzc,
uint64_t aLayersId);
template<class ScrollNode>
HitTestingTreeNode* PrepareNodeForLayer(const ScrollNode& aLayer,
const FrameMetrics& aMetrics,