Bug 775447: Properly count number of touch listeners in AsyncPanZoomController r=cjones

This commit is contained in:
Doug Sherk 2012-08-08 13:37:57 -07:00
Родитель 1895527d8c
Коммит 6b3965aa7c
9 изменённых файлов: 78 добавлений и 2 удалений

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

@ -247,6 +247,8 @@ parent:
nsString aName, nsString aFeatures)
returns (bool windowOpened);
NotifyDOMTouchListenerAdded();
__delete__();
child:

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

@ -20,6 +20,7 @@
#include "mozilla/layers/CompositorChild.h"
#include "mozilla/layers/PLayersChild.h"
#include "mozilla/layout/RenderFrameChild.h"
#include "mozilla/unused.h"
#include "nsComponentManagerUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
@ -106,6 +107,24 @@ TabChild::TabChild(PRUint32 aChromeFlags, bool aIsBrowserElement,
printf("creating %d!\n", NS_IsMainThread());
}
nsresult
TabChild::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (!strcmp(aTopic, "dom-touch-listener-added")) {
nsCOMPtr<nsIDOMWindow> subject(do_QueryInterface(aSubject));
nsCOMPtr<nsIDOMWindow> win(do_GetInterface(mWebNav));
nsCOMPtr<nsIDOMWindow> topSubject;
subject->GetTop(getter_AddRefs(topSubject));
if (win == topSubject) {
SendNotifyDOMTouchListenerAdded();
}
}
return NS_OK;
}
nsresult
TabChild::Init()
{
@ -121,6 +140,16 @@ TabChild::Init()
nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(mWebNav));
docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (observerService) {
observerService->AddObserver(this,
"dom-touch-listener-added",
false);
}
return NS_OK;
}

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

@ -140,7 +140,8 @@ class TabChild : public PBrowserChild,
public nsIWindowProvider,
public nsSupportsWeakReference,
public nsIDialogCreator,
public nsITabChild
public nsITabChild,
public nsIObserver
{
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
@ -166,6 +167,7 @@ public:
NS_DECL_NSIWINDOWPROVIDER
NS_DECL_NSIDIALOGCREATOR
NS_DECL_NSITABCHILD
NS_DECL_NSIOBSERVER
virtual bool RecvLoadURL(const nsCString& uri);
virtual bool RecvShow(const nsIntSize& size);

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

@ -1090,5 +1090,14 @@ TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
return true;
}
bool
TabParent::RecvNotifyDOMTouchListenerAdded()
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->NotifyDOMTouchListenerAdded();
}
return true;
}
} // namespace tabs
} // namespace mozilla

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

@ -101,6 +101,7 @@ public:
virtual bool RecvSetBackgroundColor(const nscolor& aValue);
virtual bool RecvGetDPI(float* aValue);
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue);
virtual bool RecvNotifyDOMTouchListenerAdded();
virtual PContentDialogParent* AllocPContentDialog(const PRUint32& aType,
const nsCString& aName,
const nsCString& aFeatures,

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

@ -53,7 +53,8 @@ AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoCon
mLastSampleTime(TimeStamp::Now()),
mState(NOTHING),
mDPI(72),
mContentPainterStatus(CONTENT_IDLE)
mContentPainterStatus(CONTENT_IDLE),
mMayHaveTouchListeners(false)
{
if (aGestures == USE_GESTURE_DETECTOR) {
mGestureEventListener = new GestureEventListener(this);
@ -784,6 +785,10 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
// we get a larger displayport. This is very bad because we're wasting a
// paint and not initializating the displayport correctly.
RequestContentRepaint();
// Assuming a first paint means a new page has been loaded, clear the flag
// indicating that we may have touch listeners.
mMayHaveTouchListeners = false;
} else if (!mFrameMetrics.mContentRect.IsEqualEdges(aViewportFrame.mContentRect)) {
mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect;
SetPageRect(mFrameMetrics.mCSSContentRect);
@ -802,5 +807,9 @@ void AsyncPanZoomController::UpdateViewportSize(int aWidth, int aHeight) {
mFrameMetrics = metrics;
}
void AsyncPanZoomController::NotifyDOMTouchListenerAdded() {
mMayHaveTouchListeners = true;
}
}
}

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

@ -99,6 +99,16 @@ public:
*/
void UpdateViewportSize(int aWidth, int aHeight);
/**
* A DOM touch listener has been added. When called, we enable the machinery
* that allows touch listeners to preventDefault any touch inputs. This should
* not be called unless there are actually touch listeners as it introduces
* potentially unbounded lag because it causes a round-trip through content.
* Usually, if content is responding in a timely fashion, this only introduces
* a nearly constant few hundred ms of lag.
*/
void NotifyDOMTouchListenerAdded();
// --------------------------------------------------------------------------
// These methods must only be called on the compositor thread.
//
@ -394,6 +404,10 @@ private:
// requests a repaint.
ContentPainterStatus mContentPainterStatus;
// Whether or not we might have touch listeners. This is a conservative
// approximation and may not be accurate.
bool mMayHaveTouchListeners;
friend class Axis;
};

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

@ -852,6 +852,14 @@ RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder,
bounds));
}
void
RenderFrameParent::NotifyDOMTouchListenerAdded()
{
if (mPanZoomController) {
mPanZoomController->NotifyDOMTouchListenerAdded();
}
}
} // namespace layout
} // namespace mozilla

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

@ -93,6 +93,8 @@ public:
void NotifyDimensionsChanged(int width, int height);
void NotifyDOMTouchListenerAdded();
protected:
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;