зеркало из https://github.com/mozilla/gecko-dev.git
Bug 845169 - Update touch region from remote frame. r=roc
This commit is contained in:
Родитель
79f2e1f7bf
Коммит
41345e7739
|
@ -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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче