Bug 845169 - Update touch region from remote frame. r=roc

This commit is contained in:
Kan-Ru Chen (陳侃如) 2013-08-13 15:56:57 +08:00
Родитель 79f2e1f7bf
Коммит 41345e7739
12 изменённых файлов: 155 добавлений и 16 удалений

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

@ -2072,6 +2072,13 @@ nsFrameLoader::TryRemoteBrowser()
mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
mContentParent = mRemoteBrowser->Manager();
if (mOwnerContent->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::mozpasspointerevents,
nsGkAtoms::_true,
eCaseMatters)) {
unused << mRemoteBrowser->SendSetUpdateHitRegion(true);
}
}
return true;
}

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

@ -405,6 +405,13 @@ child:
*/
Destroy();
/**
* Tell the child side if it has to update it's touchable region
* to the parent.
*/
SetUpdateHitRegion(bool aEnabled);
/*
* FIXME: write protocol!

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

@ -294,6 +294,7 @@ TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t
, mContentDocumentIsDisplayed(false)
, mTriedBrowserInit(false)
, mOrientation(eScreenOrientation_PortraitPrimary)
, mUpdateHitRegion(false)
{
printf("creating %d!\n", NS_IsMainThread());
}
@ -2142,6 +2143,13 @@ TabChild::RecvDestroy()
return Send__delete__(this);
}
bool
TabChild::RecvSetUpdateHitRegion(const bool& aEnabled)
{
mUpdateHitRegion = aEnabled;
return true;
}
PRenderFrameChild*
TabChild::AllocPRenderFrameChild(ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
@ -2353,6 +2361,12 @@ TabChild::MakeHidden()
}
}
void
TabChild::UpdateHitRegion(const nsRegion& aRegion)
{
mRemoteFrame->SendUpdateHitRegion(aRegion);
}
NS_IMETHODIMP
TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult)
{

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

@ -340,12 +340,17 @@ public:
ContentChild* Manager() { return mManager; }
bool GetUpdateHitRegion() { return mUpdateHitRegion; }
void UpdateHitRegion(const nsRegion& aRegion);
protected:
virtual PRenderFrameChild* AllocPRenderFrameChild(ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId) MOZ_OVERRIDE;
virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) MOZ_OVERRIDE;
virtual bool RecvDestroy() MOZ_OVERRIDE;
virtual bool RecvSetUpdateHitRegion(const bool& aEnabled) MOZ_OVERRIDE;
nsEventStatus DispatchWidgetEvent(nsGUIEvent& event);
@ -471,6 +476,7 @@ private:
bool mContentDocumentIsDisplayed;
bool mTriedBrowserInit;
ScreenOrientation mOrientation;
bool mUpdateHitRegion;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};

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

@ -763,24 +763,24 @@ struct ParamTraits<nsIntRect>
}
};
template<>
struct ParamTraits<nsIntRegion>
template<typename Region, typename Rect, typename Iter>
struct RegionParamTraits
{
typedef nsIntRegion paramType;
typedef Region paramType;
static void Write(Message* msg, const paramType& param)
{
nsIntRegionRectIterator it(param);
while (const nsIntRect* r = it.Next())
Iter it(param);
while (const Rect* r = it.Next())
WriteParam(msg, *r);
// empty rects are sentinel values because nsRegions will never
// contain them
WriteParam(msg, nsIntRect());
WriteParam(msg, Rect());
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
nsIntRect rect;
Rect rect;
while (ReadParam(msg, iter, &rect)) {
if (rect.IsEmpty())
return true;
@ -790,6 +790,11 @@ struct ParamTraits<nsIntRegion>
}
};
template<>
struct ParamTraits<nsIntRegion>
: RegionParamTraits<nsIntRegion, nsIntRect, nsIntRegionRectIterator>
{};
template<>
struct ParamTraits<nsIntSize>
{
@ -988,6 +993,11 @@ struct ParamTraits<nsRect>
}
};
template<>
struct ParamTraits<nsRegion>
: RegionParamTraits<nsRegion, nsRect, nsRegionRectIterator>
{};
template<>
struct ParamTraits<nsID>
{

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

@ -40,6 +40,7 @@
#include "BasicLayers.h"
#include "nsBoxFrame.h"
#include "nsViewportFrame.h"
#include "nsSubDocumentFrame.h"
#include "nsSVGEffects.h"
#include "nsSVGElement.h"
#include "nsSVGClipPathFrame.h"
@ -1270,6 +1271,17 @@ GetMouseThrough(const nsIFrame* aFrame)
return false;
}
static bool
IsFrameReceivingPointerEvents(nsIFrame* aFrame)
{
nsSubDocumentFrame* frame = do_QueryFrame(aFrame);
if (frame && frame->PassPointerEventsToChildren()) {
return true;
}
return NS_STYLE_POINTER_EVENTS_NONE !=
aFrame->StyleVisibility()->GetEffectivePointerEvents(aFrame);
}
// A list of frames, and their z depth. Used for sorting
// the results of hit testing.
struct FramesWithDepth
@ -1352,8 +1364,7 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
for (uint32_t j = 0; j < outFrames.Length(); j++) {
nsIFrame *f = outFrames.ElementAt(j);
// Handle the XUL 'mousethrough' feature and 'pointer-events'.
if (!GetMouseThrough(f) &&
f->StyleVisibility()->GetEffectivePointerEvents(f) != NS_STYLE_POINTER_EVENTS_NONE) {
if (!GetMouseThrough(f) && IsFrameReceivingPointerEvents(f)) {
writeFrames->AppendElement(f);
}
}

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

@ -5489,6 +5489,47 @@ private:
uint32_t mFlags;
};
class AutoUpdateHitRegion
{
public:
AutoUpdateHitRegion(PresShell* aShell, nsIFrame* aFrame)
: mShell(aShell), mFrame(aFrame)
{
}
~AutoUpdateHitRegion()
{
if (XRE_GetProcessType() != GeckoProcessType_Content ||
!mFrame || !mShell) {
return;
}
TabChild* tabChild = GetTabChildFrom(mShell);
if (!tabChild || !tabChild->GetUpdateHitRegion()) {
return;
}
nsRegion region;
nsDisplayListBuilder builder(mFrame,
nsDisplayListBuilder::EVENT_DELIVERY,
/* aBuildCert= */ false);
nsDisplayList list;
nsAutoTArray<nsIFrame*, 100> outFrames;
nsDisplayItem::HitTestState hitTestState;
nsRect bounds = mShell->GetPresContext()->GetVisibleArea();
builder.EnterPresShell(mFrame, bounds);
mFrame->BuildDisplayListForStackingContext(&builder, bounds, &list);
builder.LeavePresShell(mFrame, bounds);
list.HitTest(&builder, bounds, &hitTestState, &outFrames);
list.DeleteAll();
for (int32_t i = outFrames.Length() - 1; i >= 0; --i) {
region.Or(region, nsLayoutUtils::TransformFrameRectToAncestor(
outFrames[i], nsRect(nsPoint(0, 0), outFrames[i]->GetSize()), mFrame));
}
tabChild->UpdateHitRegion(region);
}
private:
PresShell* mShell;
nsIFrame* mFrame;
};
void
PresShell::Paint(nsView* aViewToPaint,
const nsRegion& aDirtyRegion,
@ -5520,6 +5561,7 @@ PresShell::Paint(nsView* aViewToPaint,
didPaintFlags |= PAINT_COMPOSITE;
}
nsAutoNotifyDidPaint notifyDidPaint(this, didPaintFlags);
AutoUpdateHitRegion updateHitRegion(this, frame);
// Whether or not we should set first paint when painting is
// suppressed is debatable. For now we'll do it because

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

@ -303,7 +303,11 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (aBuilder->IsForEventDelivery() && !PassPointerEventsToChildren())
return;
DisplayBorderBackgroundOutline(aBuilder, aLists);
// If we are pointer-events:none then we don't need to HitTest background
if (!aBuilder->IsForEventDelivery() ||
StyleVisibility()->mPointerEvents != NS_STYLE_POINTER_EVENTS_NONE) {
DisplayBorderBackgroundOutline(aBuilder, aLists);
}
if (!mInnerView)
return;

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

@ -107,6 +107,12 @@ public:
return !frameLoader || frameLoader->ShouldClampScrollPosition();
}
/**
* Return true if pointer event hit-testing should be allowed to target
* content in the subdocument.
*/
bool PassPointerEventsToChildren();
protected:
friend class AsyncFrameInit;
@ -135,12 +141,6 @@ protected:
*/
nsIFrame* ObtainIntrinsicSizeFrame();
/**
* Return true if pointer event hit-testing should be allowed to target
* content in the subdocument.
*/
bool PassPointerEventsToChildren();
nsRefPtr<nsFrameLoader> mFrameLoader;
nsView* mInnerView;
bool mIsInline;

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

@ -8,6 +8,10 @@
include protocol PBrowser;
include protocol PLayerTransaction;
include "nsRegion.h";
using nsRegion;
namespace mozilla {
namespace layout {
@ -44,15 +48,19 @@ parent:
async CancelDefaultPanZoom();
async DetectScrollableSubframe();
async UpdateHitRegion(nsRegion aRegion);
async __delete__();
state EMPTY_OR_DIRECT_COMPOSITOR:
recv PLayerTransaction goto HAVE_CONTENT;
recv NotifyCompositorTransaction goto EMPTY_OR_DIRECT_COMPOSITOR;
recv UpdateHitRegion goto EMPTY_OR_DIRECT_COMPOSITOR;
recv __delete__;
state HAVE_CONTENT:
recv NotifyCompositorTransaction goto HAVE_CONTENT;
recv UpdateHitRegion goto HAVE_CONTENT;
recv __delete__;
};

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

@ -862,6 +862,13 @@ RenderFrameParent::RecvDetectScrollableSubframe()
return true;
}
bool
RenderFrameParent::RecvUpdateHitRegion(const nsRegion& aRegion)
{
mTouchRegion = aRegion;
return true;
}
PLayerTransactionParent*
RenderFrameParent::AllocPLayerTransactionParent()
{
@ -1007,6 +1014,12 @@ RenderFrameParent::UpdateZoomConstraints(bool aAllowZoom, float aMinZoom, float
}
}
bool
RenderFrameParent::HitTest(const nsRect& aRect)
{
return mTouchRegion.Contains(aRect);
}
} // namespace layout
} // namespace mozilla
@ -1022,6 +1035,14 @@ nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
return layer.forget();
}
void
nsDisplayRemote::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
{
if (mRemoteFrame->HitTest(aRect)) {
aOutFrames->AppendElement(mFrame);
}
}
void
nsDisplayRemoteShadow::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,

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

@ -104,6 +104,8 @@ public:
void UpdateZoomConstraints(bool aAllowZoom, float aMinZoom, float aMaxZoom);
bool HitTest(const nsRect& aRect);
protected:
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
@ -112,6 +114,8 @@ protected:
virtual bool RecvCancelDefaultPanZoom() MOZ_OVERRIDE;
virtual bool RecvDetectScrollableSubframe() MOZ_OVERRIDE;
virtual bool RecvUpdateHitRegion(const nsRegion& aRegion) MOZ_OVERRIDE;
virtual PLayerTransactionParent* AllocPLayerTransactionParent() MOZ_OVERRIDE;
virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) MOZ_OVERRIDE;
@ -160,6 +164,8 @@ private:
bool mFrameLoaderDestroyed;
// this is gfxRGBA because that's what ColorLayer wants.
gfxRGBA mBackgroundColor;
nsRegion mTouchRegion;
};
} // namespace layout
@ -190,6 +196,9 @@ public:
BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerParameters& aContainerParameters) MOZ_OVERRIDE;
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("Remote", TYPE_REMOTE)
private: