Bug 775448: Disable async scrolling when we detect a scrollable subframe r=cjones

This commit is contained in:
Doug Sherk 2012-08-07 18:51:02 -07:00
parent 54d7cdc02b
commit daacd19d06
9 changed files with 69 additions and 1 deletions

View File

@ -43,6 +43,16 @@ const ContentPanning = {
let oldTarget = this.target;
[this.target, this.scrollCallback] = this.getPannable(evt.target);
// 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 && ContentPanning._asyncPanZoomForViewportFrame) {
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
os.notifyObservers(docShell, 'cancel-default-pan-zoom', null);
}
// If there is a pan animation running (from a previous pan gesture) and
// the user touch back the screen, stop this animation immediatly and
// prevent the possible click action if the touch happens on the same

View File

@ -120,6 +120,12 @@ TabChild::Observe(nsISupports *aSubject,
if (win == topSubject) {
SendNotifyDOMTouchListenerAdded();
}
} else if (!strcmp(aTopic, "cancel-default-pan-zoom")) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
if (tabChild == this) {
mRemoteFrame->CancelDefaultPanZoom();
}
}
return NS_OK;
@ -148,6 +154,9 @@ TabChild::Init()
observerService->AddObserver(this,
"dom-touch-listener-added",
false);
observerService->AddObserver(this,
"cancel-default-pan-zoom",
false);
}
return NS_OK;

View File

@ -54,7 +54,8 @@ AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoCon
mState(NOTHING),
mDPI(72),
mContentPainterStatus(CONTENT_IDLE),
mMayHaveTouchListeners(false)
mMayHaveTouchListeners(false),
mDisableNextTouchBatch(false)
{
if (aGestures == USE_GESTURE_DETECTOR) {
mGestureEventListener = new GestureEventListener(this);
@ -223,6 +224,10 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
}
nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent) {
if (mDisableNextTouchBatch) {
return nsEventStatus_eIgnore;
}
switch (mState) {
case FLING:
case NOTHING:
@ -254,6 +259,11 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
}
nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent) {
if (mDisableNextTouchBatch) {
mDisableNextTouchBatch = false;
return nsEventStatus_eIgnore;
}
switch (mState) {
case FLING:
// Should never happen.
@ -811,5 +821,9 @@ void AsyncPanZoomController::NotifyDOMTouchListenerAdded() {
mMayHaveTouchListeners = true;
}
void AsyncPanZoomController::CancelDefaultPanZoom() {
mDisableNextTouchBatch = true;
}
}
}

View File

@ -109,6 +109,16 @@ public:
*/
void NotifyDOMTouchListenerAdded();
/**
* We have found a scrollable 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();
// --------------------------------------------------------------------------
// These methods must only be called on the compositor thread.
//
@ -408,6 +418,10 @@ private:
// approximation and may not be accurate.
bool mMayHaveTouchListeners;
// 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;
friend class Axis;
};

View File

@ -41,6 +41,8 @@ parent:
async NotifyCompositorTransaction();
async CancelDefaultPanZoom();
async __delete__();
state EMPTY_OR_DIRECT_COMPOSITOR:

View File

@ -32,6 +32,12 @@ RenderFrameChild::Destroy()
// WARNING: |this| is dead, hands off
}
void
RenderFrameChild::CancelDefaultPanZoom()
{
SendCancelDefaultPanZoom();
}
PLayersChild*
RenderFrameChild::AllocPLayers()
{

View File

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

View File

@ -720,6 +720,15 @@ RenderFrameParent::RecvNotifyCompositorTransaction()
return true;
}
bool
RenderFrameParent::RecvCancelDefaultPanZoom()
{
if (mPanZoomController) {
mPanZoomController->CancelDefaultPanZoom();
}
return true;
}
PLayersParent*
RenderFrameParent::AllocPLayers()
{

View File

@ -100,6 +100,8 @@ protected:
virtual bool RecvNotifyCompositorTransaction() MOZ_OVERRIDE;
virtual bool RecvCancelDefaultPanZoom() MOZ_OVERRIDE;
virtual PLayersParent* AllocPLayers() MOZ_OVERRIDE;
virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE;