Backed out changeset 669d3fd3ea2b (bug 906877) for Mnw failures.

This commit is contained in:
Ryan VanderMeulen 2013-09-03 17:22:14 -04:00
Родитель 99509409ad
Коммит 374595fdca
11 изменённых файлов: 230 добавлений и 9 удалений

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

@ -48,7 +48,7 @@ const ContentPanning = {
// If we are using an AsyncPanZoomController for the parent frame,
// it will handle subframe scrolling too. We don't need to listen for
// these events.
if (!docShell.asyncPanZoomEnabled) {
if (!this._asyncPanZoomForViewportFrame) {
let els = Cc["@mozilla.org/eventlistenerservice;1"]
.getService(Ci.nsIEventListenerService);
@ -140,11 +140,23 @@ const ContentPanning = {
let oldTarget = this.target;
[this.target, this.scrollCallback] = this.getPannable(this.pointerDownTarget);
// If we have a pointer down target, we may need to fill in for EventStateManager
// in setting the active state on the target element. Set a timer to
// If we found a target, that means we have found a scrollable subframe. In
// this case, and if we are using async panning and zooming on the parent
// frame, inform the pan/zoom controller that it should not attempt to
// handle any touch events it gets until the next batch (meaning the next
// time we get a touch end).
if (this.target != null && this._asyncPanZoomForViewportFrame) {
this.detectingScrolling = true;
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
os.notifyObservers(docShell, 'detect-scrollable-subframe', null);
}
// If we have a pointer down target and we're not async
// pan/zooming, we may need to fill in for EventStateManager in
// setting the active state on the target element. Set a timer to
// ensure the pointer-down target is active. (If it's already
// active, the timer is a no-op.)
if (this.pointerDownTarget !== null) {
if (this.pointerDownTarget !== null && !this.detectingScrolling) {
// If there's no possibility this is a drag/pan, activate now.
// Otherwise wait a little bit to see if the gesture isn't a
// tap.
@ -214,6 +226,12 @@ const ContentPanning = {
this.pointerDownTarget = null;
},
// True when there's an async pan-zoom controll watching the
// outermost scrollable frame, and we're waiting to see whether
// we're going to take over from it and synchronously scroll an
// inner scrollable frame.
detectingScrolling: false,
onTouchMove: function cp_onTouchMove(evt) {
if (!this.dragging)
return;
@ -242,6 +260,27 @@ const ContentPanning = {
}
let isPan = KineticPanning.isPan();
if (!isPan && this.detectingScrolling) {
// If panning distance is not large enough and we're waiting to
// see whether we should use the sync scroll fallback or not,
// don't attempt scrolling.
return;
}
let isScroll = this.scrollCallback(delta.scale(-1));
if (this.detectingScrolling) {
this.detectingScrolling = false;
// Stop async-pan-zooming if the user is panning the subframe.
if (isScroll) {
// We're going to drive synchronously scrolling an inner frame.
Services.obs.notifyObservers(docShell, 'cancel-default-pan-zoom', null);
} else {
// Let AsyncPanZoomController handle the scrolling gesture.
this.scrollCallback = null;
return;
}
}
// If we've detected a pan gesture, cancel the active state of the
// current target.
@ -317,6 +356,13 @@ const ContentPanning = {
node = node.parentNode;
}
if (ContentPanning._asyncPanZoomForViewportFrame &&
nodeContent === content) {
// The parent context is asynchronously panning and zooming our
// root scrollable frame, so don't use our synchronous fallback.
return null;
}
if (nodeContent.scrollMaxX || nodeContent.scrollMaxY) {
return nodeContent;
}
@ -438,6 +484,10 @@ const ContentPanning = {
this._domUtils.setContentState(elt, kStateActive);
},
get _asyncPanZoomForViewportFrame() {
return docShell.asyncPanZoomEnabled;
},
_recvViewportChange: function(data) {
let metrics = data.json;
this._viewport = new Rect(metrics.x, metrics.y,
@ -549,6 +599,7 @@ const ContentPanning = {
_finishPanning: function() {
this._resetActive();
this.dragging = false;
this.detectingScrolling = false;
delete this.primaryPointerId;
this._activationTimer.cancel();

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

@ -105,8 +105,10 @@ NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
static const CSSSize kDefaultViewportSize(980, 480);
static const char CANCEL_DEFAULT_PAN_ZOOM[] = "cancel-default-pan-zoom";
static const char BROWSER_ZOOM_TO_RECT[] = "browser-zoom-to-rect";
static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
static const char DETECT_SCROLLABLE_SUBFRAME[] = "detect-scrollable-subframe";
static bool sCpowsEnabled = false;
@ -383,7 +385,13 @@ TabChild::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (!strcmp(aTopic, BROWSER_ZOOM_TO_RECT)) {
if (!strcmp(aTopic, CANCEL_DEFAULT_PAN_ZOOM)) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
if (tabChild == this) {
mRemoteFrame->CancelDefaultPanZoom();
}
} else if (!strcmp(aTopic, BROWSER_ZOOM_TO_RECT)) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
if (tabChild == this) {
@ -428,6 +436,12 @@ TabChild::Observe(nsISupports *aSubject,
HandlePossibleViewportChange();
}
}
} else if (!strcmp(aTopic, DETECT_SCROLLABLE_SUBFRAME)) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
if (tabChild == this) {
mRemoteFrame->DetectScrollableSubframe();
}
}
return NS_OK;
@ -2169,8 +2183,10 @@ TabChild::RecvDestroy()
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
observerService->RemoveObserver(this, CANCEL_DEFAULT_PAN_ZOOM);
observerService->RemoveObserver(this, BROWSER_ZOOM_TO_RECT);
observerService->RemoveObserver(this, BEFORE_FIRST_PAINT);
observerService->RemoveObserver(this, DETECT_SCROLLABLE_SUBFRAME);
const InfallibleTArray<PIndexedDBChild*>& idbActors =
ManagedPIndexedDBChild();
@ -2305,12 +2321,18 @@ TabChild::InitRenderingState()
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (observerService) {
observerService->AddObserver(this,
CANCEL_DEFAULT_PAN_ZOOM,
false);
observerService->AddObserver(this,
BROWSER_ZOOM_TO_RECT,
false);
observerService->AddObserver(this,
BEFORE_FIRST_PAINT,
false);
observerService->AddObserver(this,
DETECT_SCROLLABLE_SUBFRAME,
false);
}
// This state can't really change during the lifetime of the child.

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

@ -360,6 +360,24 @@ APZCTreeManager::UpdateCompositionBounds(const ScrollableLayerGuid& aGuid,
}
}
void
APZCTreeManager::CancelDefaultPanZoom(const ScrollableLayerGuid& aGuid)
{
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
if (apzc) {
apzc->CancelDefaultPanZoom();
}
}
void
APZCTreeManager::DetectScrollableSubframe(const ScrollableLayerGuid& aGuid)
{
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
if (apzc) {
apzc->DetectScrollableSubframe();
}
}
void
APZCTreeManager::ZoomToRect(const ScrollableLayerGuid& aGuid,
const CSSRect& aRect)

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

@ -168,6 +168,22 @@ public:
void UpdateCompositionBounds(const ScrollableLayerGuid& aGuid,
const ScreenIntRect& aCompositionBounds);
/**
* We are scrolling a subframe, so disable our machinery until we hit
* a touch end or a new touch start. This prevents us from accidentally
* panning both the subframe and the parent frame.
*
* XXX/bug 775452: We should eventually be supporting async scrollable
* subframes.
*/
void CancelDefaultPanZoom(const ScrollableLayerGuid& aGuid);
/**
* We have found a scrollable subframe, so we need to delay the scrolling
* gesture executed and let subframe do the scrolling first.
*/
void DetectScrollableSubframe(const ScrollableLayerGuid& aGuid);
/**
* Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
* in. The actual animation is done on the compositor thread after being set

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

@ -212,7 +212,9 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId,
mLastAsyncScrollOffset(0, 0),
mCurrentAsyncScrollOffset(0, 0),
mAsyncScrollTimeoutTask(nullptr),
mHandlingTouchQueue(false)
mDisableNextTouchBatch(false),
mHandlingTouchQueue(false),
mDelayPanning(false)
{
MOZ_COUNT_CTOR(AsyncPanZoomController);
@ -310,12 +312,29 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent)
nsEventStatus rv = nsEventStatus_eIgnore;
nsRefPtr<GestureEventListener> listener = GetGestureEventListener();
if (listener) {
if (listener && !mDisableNextTouchBatch) {
rv = listener->HandleInputEvent(aEvent);
if (rv == nsEventStatus_eConsumeNoDefault)
return rv;
}
if (mDelayPanning && aEvent.mInputType == MULTITOUCH_INPUT) {
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_MOVE) {
// Let BrowserElementScrolling perform panning gesture first.
SetState(WAITING_LISTENERS);
mTouchQueue.AppendElement(multiTouchInput);
if (!mTouchListenerTimeoutTask) {
mTouchListenerTimeoutTask =
NewRunnableMethod(this, &AsyncPanZoomController::TimeoutTouchListeners);
PostDelayedTask(mTouchListenerTimeoutTask, gTouchListenerTimeout);
}
return nsEventStatus_eConsumeNoDefault;
}
}
switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: {
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
@ -397,6 +416,10 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
}
nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent) {
if (mDisableNextTouchBatch) {
return nsEventStatus_eIgnore;
}
switch (mState) {
case FLING:
case NOTHING:
@ -436,6 +459,11 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
}
nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent) {
if (mDisableNextTouchBatch) {
mDisableNextTouchBatch = false;
return nsEventStatus_eIgnore;
}
{
ReentrantMonitorAutoEnter lock(mMonitor);
SendAsyncScrollEvent();
@ -1157,6 +1185,18 @@ void AsyncPanZoomController::UpdateCompositionBounds(const ScreenIntRect& aCompo
}
}
void AsyncPanZoomController::CancelDefaultPanZoom() {
mDisableNextTouchBatch = true;
nsRefPtr<GestureEventListener> listener = GetGestureEventListener();
if (listener) {
listener->CancelGesture();
}
}
void AsyncPanZoomController::DetectScrollableSubframe() {
mDelayPanning = true;
}
void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
SetState(ANIMATING_ZOOM);
@ -1236,7 +1276,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
}
void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) {
if (!mFrameMetrics.mMayHaveTouchListeners) {
if (!mFrameMetrics.mMayHaveTouchListeners && !mDelayPanning) {
mTouchQueue.Clear();
return;
}
@ -1248,12 +1288,21 @@ void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) {
if (mState == WAITING_LISTENERS) {
if (!aPreventDefault) {
SetState(NOTHING);
// Delayed scrolling gesture is pending at TOUCHING state.
if (mDelayPanning) {
SetState(TOUCHING);
} else {
SetState(NOTHING);
}
}
mHandlingTouchQueue = true;
while (!mTouchQueue.IsEmpty()) {
// we need to reset mDelayPanning before handling scrolling gesture.
if (!aPreventDefault && mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_MOVE) {
mDelayPanning = false;
}
if (!aPreventDefault) {
HandleInputEvent(mTouchQueue[0]);
}

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

@ -109,6 +109,22 @@ public:
*/
void UpdateCompositionBounds(const ScreenIntRect& aCompositionBounds);
/**
* We are scrolling a subframe, so disable our machinery until we hit
* a touch end or a new touch start. This prevents us from accidentally
* panning both the subframe and the parent frame.
*
* XXX/bug 775452: We should eventually be supporting async scrollable
* subframes.
*/
void CancelDefaultPanZoom();
/**
* We have found a scrollable subframe, so we need to delay the scrolling
* gesture executed and let subframe do the scrolling first.
*/
void DetectScrollableSubframe();
/**
* Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
* in. The actual animation is done on the compositor thread after being set
@ -564,12 +580,22 @@ private:
// ensures the last mozbrowserasyncscroll event is always been fired.
CancelableTask* mAsyncScrollTimeoutTask;
// Flag used to determine whether or not we should disable handling of the
// next batch of touch events. This is used for sync scrolling of subframes.
bool mDisableNextTouchBatch;
// Flag used to determine whether or not we should try to enter the
// WAITING_LISTENERS state. This is used in the case that we are processing a
// queued up event block. If set, this means that we are handling this queue
// and we don't want to queue the events back up again.
bool mHandlingTouchQueue;
// Flag used to determine whether or not we should try scrolling by
// BrowserElementScrolling first. If set, we delay delivering
// touchmove events to GestureListener until BrowserElementScrolling
// decides whether it wants to handle panning for this touch series.
bool mDelayPanning;
friend class Axis;
/* The functions and members in this section are used to build a tree

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

@ -45,6 +45,9 @@ parent:
async NotifyCompositorTransaction();
async CancelDefaultPanZoom();
async DetectScrollableSubframe();
async UpdateHitRegion(nsRegion aRegion);
async __delete__();

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

@ -32,6 +32,18 @@ RenderFrameChild::Destroy()
// WARNING: |this| is dead, hands off
}
void
RenderFrameChild::CancelDefaultPanZoom()
{
SendCancelDefaultPanZoom();
}
void
RenderFrameChild::DetectScrollableSubframe()
{
SendDetectScrollableSubframe();
}
PLayerTransactionChild*
RenderFrameChild::AllocPLayerTransactionChild()
{

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

@ -19,6 +19,9 @@ public:
RenderFrameChild() {}
virtual ~RenderFrameChild() {}
void CancelDefaultPanZoom();
void DetectScrollableSubframe();
void Destroy();
protected:

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

@ -846,6 +846,24 @@ RenderFrameParent::RecvNotifyCompositorTransaction()
return true;
}
bool
RenderFrameParent::RecvCancelDefaultPanZoom()
{
if (GetApzcTreeManager()) {
GetApzcTreeManager()->CancelDefaultPanZoom(ScrollableLayerGuid(mLayersId));
}
return true;
}
bool
RenderFrameParent::RecvDetectScrollableSubframe()
{
if (GetApzcTreeManager()) {
GetApzcTreeManager()->DetectScrollableSubframe(ScrollableLayerGuid(mLayersId));
}
return true;
}
bool
RenderFrameParent::RecvUpdateHitRegion(const nsRegion& aRegion)
{

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

@ -117,6 +117,9 @@ protected:
virtual bool RecvNotifyCompositorTransaction() MOZ_OVERRIDE;
virtual bool RecvCancelDefaultPanZoom() MOZ_OVERRIDE;
virtual bool RecvDetectScrollableSubframe() MOZ_OVERRIDE;
virtual bool RecvUpdateHitRegion(const nsRegion& aRegion) MOZ_OVERRIDE;
virtual PLayerTransactionParent* AllocPLayerTransactionParent() MOZ_OVERRIDE;