Bug 1105109 - Have the parent process notify APZ of the start and stop of autoscrolling. r=kats

The messages are routed through nsITabParent, nsIWidget, and IAPZCTreeManager
(the latter possibly remoted via PAPZCTreeManager if out-of-process compositing
is used).

MozReview-Commit-ID: 1zXzLa1fqpG

--HG--
extra : rebase_source : c482816ecbaec0a889d817851ee15be186b2a49c
This commit is contained in:
Botond Ballo 2017-07-26 19:33:02 -04:00
Родитель 23e65cc51e
Коммит e54b8b4984
14 изменённых файлов: 225 добавлений и 1 удалений

Просмотреть файл

@ -7,6 +7,8 @@
interface nsIPrincipal;
typedef unsigned long long nsViewID;
[builtinclass, scriptable, uuid(8e49f7b0-1f98-4939-bf91-e9c39cd56434)]
interface nsITabParent : nsISupports
{
@ -75,4 +77,20 @@ interface nsITabParent : nsISupports
* an onbeforeunload event handler.
*/
readonly attribute boolean hasBeforeUnload;
/**
* Notify APZ to start autoscrolling.
* (aAnchorX, aAnchorY) are the coordinates of the autoscroll anchor,
* in LayoutDevice coordinates relative to the screen. aScrollId and
* aPresShellId identify the scroll frame that content chose to scroll.
*/
void startApzAutoscroll(in float aAnchorX, in float aAnchorY,
in nsViewID aScrollId, in uint32_t aPresShellId);
/**
* Notify APZ to stop autoscrolling.
* aScrollId and aPresShellId identify the scroll frame that is being
* autoscrolled.
*/
void stopApzAutoscroll(in nsViewID aScrollId, in uint32_t aPresShellId);
};

Просмотреть файл

@ -3263,6 +3263,50 @@ TabParent::StartPersistence(uint64_t aOuterWindowID,
// (The actor will be destroyed on constructor failure.)
}
NS_IMETHODIMP
TabParent::StartApzAutoscroll(float aAnchorX, float aAnchorY,
nsViewID aScrollId, uint32_t aPresShellId)
{
if (!AsyncPanZoomEnabled()) {
return NS_OK;
}
if (RenderFrameParent* renderFrame = GetRenderFrame()) {
uint64_t layersId = renderFrame->GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
ScrollableLayerGuid guid{layersId, aPresShellId, aScrollId};
// The anchor coordinates that are passed in are relative to the origin
// of the screen, but we are sending them to APZ which only knows about
// coordinates relative to the widget, so convert them accordingly.
LayoutDeviceIntPoint anchor = RoundedToInt(LayoutDevicePoint{aAnchorX, aAnchorY});
anchor -= widget->WidgetToScreenOffset();
widget->StartAsyncAutoscroll(
ViewAs<ScreenPixel>(anchor, PixelCastJustification::LayoutDeviceIsScreenForBounds),
guid);
}
}
return NS_OK;
}
NS_IMETHODIMP
TabParent::StopApzAutoscroll(nsViewID aScrollId, uint32_t aPresShellId)
{
if (!AsyncPanZoomEnabled()) {
return NS_OK;
}
if (RenderFrameParent* renderFrame = GetRenderFrame()) {
uint64_t layersId = renderFrame->GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
ScrollableLayerGuid guid{layersId, aPresShellId, aScrollId};
widget->StopAsyncAutoscroll(guid);
}
}
return NS_OK;
}
ShowInfo
TabParent::GetShowInfo()
{

Просмотреть файл

@ -183,6 +183,12 @@ public:
const ScrollableLayerGuid& aGuid,
const AsyncDragMetrics& aDragMetrics) = 0;
virtual void StartAutoscroll(
const ScrollableLayerGuid& aGuid,
const ScreenPoint& aAnchorLocation) = 0;
virtual void StopAutoscroll(const ScrollableLayerGuid& aGuid) = 0;
/**
* Function used to disable LongTap gestures.
*

Просмотреть файл

@ -669,6 +669,23 @@ APZCTreeManager::StartScrollbarDrag(const ScrollableLayerGuid& aGuid,
mInputQueue->ConfirmDragBlock(inputBlockId, apzc, aDragMetrics);
}
void
APZCTreeManager::StartAutoscroll(const ScrollableLayerGuid& aGuid,
const ScreenPoint& aAnchorLocation)
{
if (RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid)) {
apzc->StartAutoscroll(aAnchorLocation);
}
}
void
APZCTreeManager::StopAutoscroll(const ScrollableLayerGuid& aGuid)
{
if (RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid)) {
apzc->StopAutoscroll();
}
}
void
APZCTreeManager::NotifyScrollbarDragRejected(const ScrollableLayerGuid& aGuid) const
{

Просмотреть файл

@ -435,6 +435,11 @@ public:
const ScrollableLayerGuid& aGuid,
const AsyncDragMetrics& aDragMetrics) override;
void StartAutoscroll(const ScrollableLayerGuid& aGuid,
const ScreenPoint& aAnchorLocation) override;
void StopAutoscroll(const ScrollableLayerGuid& aGuid) override;
/*
* Build the chain of APZCs that will handle overscroll for a pan starting at |aInitialTarget|.
*/

Просмотреть файл

@ -207,6 +207,20 @@ APZCTreeManagerChild::StartScrollbarDrag(
SendStartScrollbarDrag(aGuid, aDragMetrics);
}
void
APZCTreeManagerChild::StartAutoscroll(
const ScrollableLayerGuid& aGuid,
const ScreenPoint& aAnchorLocation)
{
SendStartAutoscroll(aGuid, aAnchorLocation);
}
void
APZCTreeManagerChild::StopAutoscroll(const ScrollableLayerGuid& aGuid)
{
SendStopAutoscroll(aGuid);
}
void
APZCTreeManagerChild::SetLongTapEnabled(bool aTapGestureEnabled)
{

Просмотреть файл

@ -70,6 +70,14 @@ public:
const ScrollableLayerGuid& aGuid,
const AsyncDragMetrics& aDragMetrics) override;
void
StartAutoscroll(
const ScrollableLayerGuid& aGuid,
const ScreenPoint& aAnchorLocation) override;
void
StopAutoscroll(const ScrollableLayerGuid& aGuid) override;
void
SetLongTapEnabled(bool aTapGestureEnabled) override;

Просмотреть файл

@ -300,6 +300,43 @@ APZCTreeManagerParent::RecvStartScrollbarDrag(
return IPC_OK();
}
mozilla::ipc::IPCResult
APZCTreeManagerParent::RecvStartAutoscroll(
const ScrollableLayerGuid& aGuid,
const ScreenPoint& aAnchorLocation)
{
// Unlike RecvStartScrollbarDrag(), this message comes from the parent
// process (via nsBaseWidget::mAPZC) rather than from the child process
// (via TabChild::mApzcTreeManager), so there is no need to check the
// layers id against mLayersId (and in any case, it wouldn't match, because
// mLayersId stores the parent process's layers id, while nsBaseWidget is
// sending the child process's layers id).
APZThreadUtils::RunOnControllerThread(
NewRunnableMethod<ScrollableLayerGuid, ScreenPoint>(
"layers::IAPZCTreeManager::StartAutoscroll",
mTreeManager,
&IAPZCTreeManager::StartAutoscroll,
aGuid, aAnchorLocation));
return IPC_OK();
}
mozilla::ipc::IPCResult
APZCTreeManagerParent::RecvStopAutoscroll(const ScrollableLayerGuid& aGuid)
{
// See RecvStartAutoscroll() for why we don't check the layers id.
APZThreadUtils::RunOnControllerThread(
NewRunnableMethod<ScrollableLayerGuid>(
"layers::IAPZCTreeManager::StopAutoscroll",
mTreeManager,
&IAPZCTreeManager::StopAutoscroll,
aGuid));
return IPC_OK();
}
mozilla::ipc::IPCResult
APZCTreeManagerParent::RecvSetLongTapEnabled(const bool& aTapGestureEnabled)
{

Просмотреть файл

@ -126,6 +126,14 @@ public:
const ScrollableLayerGuid& aGuid,
const AsyncDragMetrics& aDragMetrics) override;
mozilla::ipc::IPCResult
RecvStartAutoscroll(
const ScrollableLayerGuid& aGuid,
const ScreenPoint& aAnchorLocation) override;
mozilla::ipc::IPCResult
RecvStopAutoscroll(const ScrollableLayerGuid& aGuid) override;
mozilla::ipc::IPCResult
RecvSetLongTapEnabled(const bool& aTapGestureEnabled) override;

Просмотреть файл

@ -10,6 +10,7 @@ include "mozilla/dom/TabMessageUtils.h"; // Needed for IPC::ParamTraits<nsEventS
include protocol PCompositorBridge;
using CSSPoint from "Units.h";
using CSSRect from "Units.h";
using LayoutDeviceCoord from "Units.h";
using LayoutDeviceIntPoint from "Units.h";
@ -79,6 +80,10 @@ parent:
async StartScrollbarDrag(ScrollableLayerGuid aGuid, AsyncDragMetrics aDragMetrics);
async StartAutoscroll(ScrollableLayerGuid aGuid, ScreenPoint aAnchorLocation);
async StopAutoscroll(ScrollableLayerGuid aGuid);
async SetLongTapEnabled(bool aTapGestureEnabled);
async ProcessTouchVelocity(uint32_t aTimestampMs, float aSpeedY);

Просмотреть файл

@ -1091,6 +1091,16 @@
return false;
}
this.startScroll(data.scrolldir, data.screenX, data.screenY);
if (this.isRemoteBrowser && data.scrollId != null) {
let { tabParent } = this.frameLoader;
if (tabParent) {
tabParent.startApzAutoscroll(data.screenX, data.screenY,
data.scrollId, data.presShellId);
}
// Save the IDs for later
this._autoScrollScrollId = data.scrollId;
this._autoScrollPresShellId = data.presShellId;
}
return true;
}
case "Autoscroll:Cancel":
@ -1190,6 +1200,9 @@
<field name="_startY">null</field>
<field name="_autoScrollPopup">null</field>
<field name="_autoScrollNeedsCleanup">false</field>
<!-- These IDs identify the scroll frame being autoscrolled. -->
<field name="_autoScrollScrollId">null</field>
<field name="_autoScrollPresShellId">null</field>
<method name="stopScroll">
<body>
@ -1205,6 +1218,16 @@
window.removeEventListener("keypress", this, true);
window.removeEventListener("keyup", this, true);
this.messageManager.sendAsyncMessage("Autoscroll:Stop");
if (this.isRemoteBrowser) {
let { tabParent } = this.frameLoader;
if (tabParent) {
tabParent.stopApzAutoscroll(this._autoScrollScrollId,
this._autoScrollPresShellId);
}
this._autoScrollScrollId = null;
this._autoScrollPresShellId = null;
}
}
]]>
</body>

Просмотреть файл

@ -1956,6 +1956,24 @@ nsBaseWidget::StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics)
aDragMetrics));
}
void
nsBaseWidget::StartAsyncAutoscroll(const ScreenPoint& aAnchorLocation,
const ScrollableLayerGuid& aGuid)
{
MOZ_ASSERT(XRE_IsParentProcess() && AsyncPanZoomEnabled());
mAPZC->StartAutoscroll(aGuid, aAnchorLocation);
}
void
nsBaseWidget::StopAsyncAutoscroll(const ScrollableLayerGuid& aGuid)
{
MOZ_ASSERT(XRE_IsParentProcess() && AsyncPanZoomEnabled());
mAPZC->StopAutoscroll(aGuid);
}
already_AddRefed<nsIScreen>
nsBaseWidget::GetWidgetScreen()
{

Просмотреть файл

@ -366,6 +366,11 @@ public:
virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override;
virtual void StartAsyncAutoscroll(const ScreenPoint& aAnchorLocation,
const ScrollableLayerGuid& aGuid) override;
virtual void StopAsyncAutoscroll(const ScrollableLayerGuid& aGuid) override;
/**
* Use this when GetLayerManager() returns a BasicLayerManager
* (nsBaseWidget::GetLayerManager() does). This sets up the widget's

Просмотреть файл

@ -340,6 +340,7 @@ class nsIWidget : public nsISupports
typedef mozilla::layers::LayerManagerComposite LayerManagerComposite;
typedef mozilla::layers::LayersBackend LayersBackend;
typedef mozilla::layers::PLayerTransactionChild PLayerTransactionChild;
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
typedef mozilla::layers::ZoomConstraints ZoomConstraints;
typedef mozilla::widget::IMEMessage IMEMessage;
typedef mozilla::widget::IMENotification IMENotification;
@ -362,6 +363,7 @@ class nsIWidget : public nsISupports
typedef mozilla::ScreenPoint ScreenPoint;
typedef mozilla::CSSToScreenScale CSSToScreenScale;
typedef mozilla::DesktopIntRect DesktopIntRect;
typedef mozilla::CSSPoint CSSPoint;
typedef mozilla::CSSRect CSSRect;
// Used in UpdateThemeGeometries.
@ -1402,7 +1404,7 @@ class nsIWidget : public nsISupports
* not need a layers update to process the event.
*/
virtual void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
const nsTArray<mozilla::layers::ScrollableLayerGuid>& aTargets) const = 0;
const nsTArray<ScrollableLayerGuid>& aTargets) const = 0;
/**
* Returns true if APZ is in use, false otherwise.
@ -1686,6 +1688,20 @@ class nsIWidget : public nsISupports
virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) = 0;
/**
* Notify APZ to start autoscrolling.
* @param aAnchorLocation the location of the autoscroll anchor
* @param aGuid identifies the scroll frame to be autoscrolled
*/
virtual void StartAsyncAutoscroll(const ScreenPoint& aAnchorLocation,
const ScrollableLayerGuid& aGuid) = 0;
/**
* Notify APZ to stop autoscrolling.
* @param aGuid identifies the scroll frame which is being autoscrolled.
*/
virtual void StopAsyncAutoscroll(const ScrollableLayerGuid& aGuid) = 0;
// If this widget supports out-of-process compositing, it can override
// this method to provide additional information to the compositor.
virtual void GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData)