Back out bug 1119497 and one patch from bug 920036 for causing bug 1121033. r=me

This commit is contained in:
Kartikaya Gupta 2015-01-13 21:16:51 -05:00
Родитель 3af458857c
Коммит cdac1b867f
8 изменённых файлов: 85 добавлений и 159 удалений

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

@ -2195,11 +2195,7 @@ TabParent::MaybeForwardEventToRenderFrame(WidgetInputEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid, ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutInputBlockId) uint64_t* aOutInputBlockId)
{ {
if (aEvent.mClass == eWheelEventClass if (aEvent.mClass == eWheelEventClass) {
#ifdef MOZ_WIDGET_GONK
|| aEvent.mClass == eTouchEventClass
#endif
) {
// Wheel events must be sent to APZ directly from the widget. New APZ- // Wheel events must be sent to APZ directly from the widget. New APZ-
// aware events should follow suit and move there as well. However, we // aware events should follow suit and move there as well. However, we
// do need to inform the child process of the correct target and block // do need to inform the child process of the correct target and block

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

@ -89,7 +89,7 @@ APZCTreeManager::CalculatePendingDisplayPort(
APZCTreeManager::APZCTreeManager() APZCTreeManager::APZCTreeManager()
: mInputQueue(new InputQueue()), : mInputQueue(new InputQueue()),
mTreeLock("APZCTreeLock"), mTreeLock("APZCTreeLock"),
mHitResultForInputBlock(HitNothing), mHitResultForInputBlock(NoApzcHit),
mRetainedTouchIdentifier(-1), mRetainedTouchIdentifier(-1),
mTouchCount(0), mTouchCount(0),
mApzcTreeLog("apzctree") mApzcTreeLog("apzctree")
@ -561,7 +561,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
} }
nsEventStatus result = nsEventStatus_eIgnore; nsEventStatus result = nsEventStatus_eIgnore;
Matrix4x4 transformToApzc; Matrix4x4 transformToApzc;
HitTestResult hitResult = HitNothing; HitTestResult hitResult = NoApzcHit;
switch (aEvent.mInputType) { switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: { case MULTITOUCH_INPUT: {
MultiTouchInput& touchInput = aEvent.AsMultiTouchInput(); MultiTouchInput& touchInput = aEvent.AsMultiTouchInput();
@ -572,7 +572,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(wheelInput.mOrigin, nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(wheelInput.mOrigin,
&hitResult); &hitResult);
if (apzc) { if (apzc) {
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion); MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
transformToApzc = GetScreenToApzcTransform(apzc); transformToApzc = GetScreenToApzcTransform(apzc);
wheelInput.mLocalOrigin = wheelInput.mLocalOrigin =
@ -580,7 +580,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
result = mInputQueue->ReceiveInputEvent( result = mInputQueue->ReceiveInputEvent(
apzc, apzc,
/* aTargetConfirmed = */ hitResult == HitLayer, /* aTargetConfirmed = */ hitResult == ApzcHitRegion,
wheelInput, aOutInputBlockId); wheelInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects. // Update the out-parameters so they are what the caller expects.
@ -595,7 +595,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(panInput.mPanStartPoint, nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(panInput.mPanStartPoint,
&hitResult); &hitResult);
if (apzc) { if (apzc) {
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion); MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
transformToApzc = GetScreenToApzcTransform(apzc); transformToApzc = GetScreenToApzcTransform(apzc);
panInput.mLocalPanStartPoint = TransformTo<ParentLayerPixel>( panInput.mLocalPanStartPoint = TransformTo<ParentLayerPixel>(
transformToApzc, panInput.mPanStartPoint); transformToApzc, panInput.mPanStartPoint);
@ -603,7 +603,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
transformToApzc, panInput.mPanDisplacement, panInput.mPanStartPoint); transformToApzc, panInput.mPanDisplacement, panInput.mPanStartPoint);
result = mInputQueue->ReceiveInputEvent( result = mInputQueue->ReceiveInputEvent(
apzc, apzc,
/* aTargetConfirmed = */ hitResult == HitLayer, /* aTargetConfirmed = */ hitResult == ApzcHitRegion,
panInput, aOutInputBlockId); panInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects. // Update the out-parameters so they are what the caller expects.
@ -620,13 +620,13 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(pinchInput.mFocusPoint, nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(pinchInput.mFocusPoint,
&hitResult); &hitResult);
if (apzc) { if (apzc) {
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion); MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
transformToApzc = GetScreenToApzcTransform(apzc); transformToApzc = GetScreenToApzcTransform(apzc);
pinchInput.mLocalFocusPoint = TransformTo<ParentLayerPixel>( pinchInput.mLocalFocusPoint = TransformTo<ParentLayerPixel>(
transformToApzc, pinchInput.mFocusPoint); transformToApzc, pinchInput.mFocusPoint);
result = mInputQueue->ReceiveInputEvent( result = mInputQueue->ReceiveInputEvent(
apzc, apzc,
/* aTargetConfirmed = */ hitResult == HitLayer, /* aTargetConfirmed = */ hitResult == ApzcHitRegion,
pinchInput, aOutInputBlockId); pinchInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects. // Update the out-parameters so they are what the caller expects.
@ -641,13 +641,13 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(tapInput.mPoint, nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(tapInput.mPoint,
&hitResult); &hitResult);
if (apzc) { if (apzc) {
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion); MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
transformToApzc = GetScreenToApzcTransform(apzc); transformToApzc = GetScreenToApzcTransform(apzc);
tapInput.mLocalPoint = TransformTo<ParentLayerPixel>( tapInput.mLocalPoint = TransformTo<ParentLayerPixel>(
transformToApzc, tapInput.mPoint); transformToApzc, tapInput.mPoint);
result = mInputQueue->ReceiveInputEvent( result = mInputQueue->ReceiveInputEvent(
apzc, apzc,
/* aTargetConfirmed = */ hitResult == HitLayer, /* aTargetConfirmed = */ hitResult == ApzcHitRegion,
tapInput, aOutInputBlockId); tapInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects. // Update the out-parameters so they are what the caller expects.
@ -658,7 +658,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
break; break;
} }
} }
if (hitResult == HitOverscrolledApzc) { if (hitResult == OverscrolledApzc) {
result = nsEventStatus_eConsumeNoDefault; result = nsEventStatus_eConsumeNoDefault;
} }
return result; return result;
@ -715,9 +715,9 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
// NS_TOUCH_START event contains all active touches of the current // NS_TOUCH_START event contains all active touches of the current
// session thus resetting mTouchCount. // session thus resetting mTouchCount.
mTouchCount = aInput.mTouches.Length(); mTouchCount = aInput.mTouches.Length();
mHitResultForInputBlock = HitNothing; mHitResultForInputBlock = NoApzcHit;
nsRefPtr<AsyncPanZoomController> apzc = GetTouchInputBlockAPZC(aInput, &mHitResultForInputBlock); nsRefPtr<AsyncPanZoomController> apzc = GetTouchInputBlockAPZC(aInput, &mHitResultForInputBlock);
// XXX the following check assumes mHitResultForInputBlock == HitLayer // XXX the following check assumes mHitResultForInputBlock == ApzcHitRegion
// (and that mApzcForInputBlock was the confirmed target of the previous // (and that mApzcForInputBlock was the confirmed target of the previous
// input block). Eventually it would be better to move this into InputQueue // input block). Eventually it would be better to move this into InputQueue
// and have it auto-generated when we start processing events in a new // and have it auto-generated when we start processing events in a new
@ -769,7 +769,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
nsEventStatus result = nsEventStatus_eIgnore; nsEventStatus result = nsEventStatus_eIgnore;
if (mApzcForInputBlock) { if (mApzcForInputBlock) {
MOZ_ASSERT(mHitResultForInputBlock == HitLayer || mHitResultForInputBlock == HitDispatchToContentRegion); MOZ_ASSERT(mHitResultForInputBlock == ApzcHitRegion || mHitResultForInputBlock == ApzcContentRegion);
mApzcForInputBlock->GetGuid(aOutTargetGuid); mApzcForInputBlock->GetGuid(aOutTargetGuid);
// For computing the input for the APZC, used the cached transform. // For computing the input for the APZC, used the cached transform.
@ -782,7 +782,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
transformToApzc, ScreenPoint(touchData.mScreenPoint)); transformToApzc, ScreenPoint(touchData.mScreenPoint));
} }
result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock, result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock,
/* aTargetConfirmed = */ mHitResultForInputBlock == HitLayer, /* aTargetConfirmed = */ mHitResultForInputBlock == ApzcHitRegion,
aInput, aOutInputBlockId); aInput, aOutInputBlockId);
// For computing the event to pass back to Gecko, use the up-to-date transforms. // For computing the event to pass back to Gecko, use the up-to-date transforms.
@ -797,7 +797,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
outTransform, touchData.mScreenPoint); outTransform, touchData.mScreenPoint);
} }
} }
if (mHitResultForInputBlock == HitOverscrolledApzc) { if (mHitResultForInputBlock == OverscrolledApzc) {
result = nsEventStatus_eConsumeNoDefault; result = nsEventStatus_eConsumeNoDefault;
} }
@ -817,7 +817,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
// don't keep dangling references and leak things. // don't keep dangling references and leak things.
if (mTouchCount == 0) { if (mTouchCount == 0) {
mApzcForInputBlock = nullptr; mApzcForInputBlock = nullptr;
mHitResultForInputBlock = HitNothing; mHitResultForInputBlock = NoApzcHit;
mRetainedTouchIdentifier = -1; mRetainedTouchIdentifier = -1;
} }
@ -848,18 +848,18 @@ APZCTreeManager::ProcessEvent(WidgetInputEvent& aEvent,
// Transform the refPoint. // Transform the refPoint.
// If the event hits an overscrolled APZC, instruct the caller to ignore it. // If the event hits an overscrolled APZC, instruct the caller to ignore it.
HitTestResult hitResult = HitNothing; HitTestResult hitResult = NoApzcHit;
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y), nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y),
&hitResult); &hitResult);
if (apzc) { if (apzc) {
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion); MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
apzc->GetGuid(aOutTargetGuid); apzc->GetGuid(aOutTargetGuid);
Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc); Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc); Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
Matrix4x4 outTransform = transformToApzc * transformToGecko; Matrix4x4 outTransform = transformToApzc * transformToGecko;
aEvent.refPoint = TransformTo<LayoutDevicePixel>(outTransform, aEvent.refPoint); aEvent.refPoint = TransformTo<LayoutDevicePixel>(outTransform, aEvent.refPoint);
} }
if (hitResult == HitOverscrolledApzc) { if (hitResult == OverscrolledApzc) {
result = nsEventStatus_eConsumeNoDefault; result = nsEventStatus_eConsumeNoDefault;
} }
return result; return result;
@ -1215,13 +1215,13 @@ already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint, HitTestResult* aOutHitResult) APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint, HitTestResult* aOutHitResult)
{ {
MonitorAutoLock lock(mTreeLock); MonitorAutoLock lock(mTreeLock);
HitTestResult hitResult = HitNothing; HitTestResult hitResult = NoApzcHit;
ParentLayerPoint point = ViewAs<ParentLayerPixel>(aPoint, ParentLayerPoint point = ViewAs<ParentLayerPixel>(aPoint,
PixelCastJustification::ScreenIsParentLayerForRoot); PixelCastJustification::ScreenIsParentLayerForRoot);
nsRefPtr<AsyncPanZoomController> target = GetAPZCAtPoint(mRootNode, point, &hitResult); nsRefPtr<AsyncPanZoomController> target = GetAPZCAtPoint(mRootNode, point, &hitResult);
// If we are in an overscrolled APZC, we should be returning nullptr. // If we are in an overscrolled APZC, we should be returning nullptr.
MOZ_ASSERT(!(target && (hitResult == HitOverscrolledApzc))); MOZ_ASSERT(!(target && (hitResult == OverscrolledApzc)));
if (aOutHitResult) { if (aOutHitResult) {
*aOutHitResult = hitResult; *aOutHitResult = hitResult;
} }
@ -1366,25 +1366,25 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
ParentLayerPoint childPoint = ViewAs<ParentLayerPixel>(hitTestPointForChildLayers.ref(), ParentLayerPoint childPoint = ViewAs<ParentLayerPixel>(hitTestPointForChildLayers.ref(),
PixelCastJustification::MovingDownToChildren); PixelCastJustification::MovingDownToChildren);
result = GetAPZCAtPoint(node->GetLastChild(), childPoint, aOutHitResult); result = GetAPZCAtPoint(node->GetLastChild(), childPoint, aOutHitResult);
if (*aOutHitResult == HitOverscrolledApzc) { if (*aOutHitResult == OverscrolledApzc) {
// We matched an overscrolled APZC, abort. // We matched an overscrolled APZC, abort.
return nullptr; return nullptr;
} }
} }
// If we didn't match anything in the subtree, check |node|. // If we didn't match anything in the subtree, check |node|.
if (*aOutHitResult == HitNothing) { if (!result) {
APZCTM_LOG("Testing ParentLayer point %s (Layer %s) against node %p\n", APZCTM_LOG("Testing ParentLayer point %s (Layer %s) against node %p\n",
Stringify(aHitTestPoint).c_str(), Stringify(aHitTestPoint).c_str(),
hitTestPointForChildLayers ? Stringify(hitTestPointForChildLayers.ref()).c_str() : "nil", hitTestPointForChildLayers ? Stringify(hitTestPointForChildLayers.ref()).c_str() : "nil",
node); node);
HitTestResult hitResult = node->HitTest(aHitTestPoint); HitTestResult hitResult = node->HitTest(aHitTestPoint);
if (hitResult != HitTestResult::HitNothing) { if (hitResult != HitTestResult::NoApzcHit) {
result = node->GetNearestContainingApzc(); result = node->GetNearestContainingApzc();
APZCTM_LOG("Successfully matched APZC %p via node %p (hit result %d)\n", APZCTM_LOG("Successfully matched APZC %p via node %p (hit result %d)\n",
result, node, hitResult); result, node, hitResult);
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion); MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
// If event regions are disabled, *aOutHitResult will be HitLayer // If event regions are disabled, *aOutHitResult will be ApzcHitRegion
*aOutHitResult = hitResult; *aOutHitResult = hitResult;
} }
} }
@ -1392,14 +1392,14 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
// If we are overscrolled, and the point matches us or one of our children, // If we are overscrolled, and the point matches us or one of our children,
// the result is inside an overscrolled APZC, inform our caller of this // the result is inside an overscrolled APZC, inform our caller of this
// (callers typically ignore events targeted at overscrolled APZCs). // (callers typically ignore events targeted at overscrolled APZCs).
if (*aOutHitResult != HitNothing && apzc && apzc->IsOverscrolled()) { if (result && apzc && apzc->IsOverscrolled()) {
APZCTM_LOG("Result is inside overscrolled APZC %p\n", apzc); APZCTM_LOG("Result is inside overscrolled APZC %p\n", apzc);
*aOutHitResult = HitOverscrolledApzc; *aOutHitResult = OverscrolledApzc;
return nullptr; return nullptr;
} }
if (*aOutHitResult != HitNothing) { if (result) {
if (result && !gfxPrefs::LayoutEventRegionsEnabled()) { if (!gfxPrefs::LayoutEventRegionsEnabled()) {
// When event-regions are disabled, we treat scrollinfo layers as // When event-regions are disabled, we treat scrollinfo layers as
// regular scrollable layers. Unfortunately, their "hit region" (which // regular scrollable layers. Unfortunately, their "hit region" (which
// we create from the composition bounds) is their full area, and they // we create from the composition bounds) is their full area, and they

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

@ -11,10 +11,10 @@ namespace mozilla {
namespace layers { namespace layers {
enum HitTestResult { enum HitTestResult {
HitNothing, NoApzcHit,
HitLayer, ApzcHitRegion,
HitDispatchToContentRegion, ApzcContentRegion,
HitOverscrolledApzc, OverscrolledApzc,
}; };
} }

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

@ -195,24 +195,24 @@ HitTestingTreeNode::HitTest(const ParentLayerPoint& aPoint) const
// If there's no APZC, then we do need to check against the mEventRegions // If there's no APZC, then we do need to check against the mEventRegions
// (which contains the layer's visible region) for obscuration purposes. // (which contains the layer's visible region) for obscuration purposes.
if (!gfxPrefs::LayoutEventRegionsEnabled() && GetApzc()) { if (!gfxPrefs::LayoutEventRegionsEnabled() && GetApzc()) {
return HitTestResult::HitLayer; return HitTestResult::ApzcHitRegion;
} }
// convert into Layer coordinate space // convert into Layer coordinate space
Maybe<LayerPoint> pointInLayerPixels = Untransform(aPoint); Maybe<LayerPoint> pointInLayerPixels = Untransform(aPoint);
if (!pointInLayerPixels) { if (!pointInLayerPixels) {
return HitTestResult::HitNothing; return HitTestResult::NoApzcHit;
} }
LayerIntPoint point = RoundedToInt(pointInLayerPixels.ref()); LayerIntPoint point = RoundedToInt(pointInLayerPixels.ref());
// test against event regions in Layer coordinate space // test against event regions in Layer coordinate space
if (!mEventRegions.mHitRegion.Contains(point.x, point.y)) { if (!mEventRegions.mHitRegion.Contains(point.x, point.y)) {
return HitTestResult::HitNothing; return HitTestResult::NoApzcHit;
} }
if (mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y)) { if (mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y)) {
return HitTestResult::HitDispatchToContentRegion; return HitTestResult::ApzcContentRegion;
} }
return HitTestResult::HitLayer; return HitTestResult::ApzcHitRegion;
} }
void void

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

@ -2551,25 +2551,6 @@ protected:
manager->UpdateHitTestingTree(nullptr, root, false, 0, 0); manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
rootApzc = ApzcOf(root); rootApzc = ApzcOf(root);
} }
void CreateBug1119497LayerTree() {
const char* layerTreeSyntax = "c(tt)";
// LayerID 0 12
// 0 is the root and doesn't have an APZC
// 1 is behind 2 and does have an APZC
// 2 entirely covers 1 and should take all the input events
nsIntRegion layerVisibleRegions[] = {
nsIntRegion(nsIntRect(0, 0, 100, 100)),
nsIntRegion(nsIntRect(0, 0, 100, 100)),
nsIntRegion(nsIntRect(0, 0, 100, 100)),
};
root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
}
}; };
TEST_F(APZEventRegionsTester, HitRegionImmediateResponse) { TEST_F(APZEventRegionsTester, HitRegionImmediateResponse) {
@ -2659,20 +2640,7 @@ TEST_F(APZEventRegionsTester, Obscuration) {
HitTestResult result; HitTestResult result;
nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 75), &result); nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 75), &result);
EXPECT_EQ(child, hit.get()); EXPECT_EQ(child, hit.get());
EXPECT_EQ(HitTestResult::HitLayer, result); EXPECT_EQ(HitTestResult::ApzcHitRegion, result);
}
TEST_F(APZEventRegionsTester, Bug1119497) {
SCOPED_GFX_PREF(LayoutEventRegionsEnabled, bool, true);
CreateBug1119497LayerTree();
HitTestResult result;
nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 50), &result);
// We should hit layers[2], so |result| will be HitLayer but there's no
// actual APZC in that parent chain, so |hit| should be nullptr.
EXPECT_EQ(nullptr, hit.get());
EXPECT_EQ(HitTestResult::HitLayer, result);
} }
class TaskRunMetrics { class TaskRunMetrics {

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

@ -24,6 +24,7 @@
#include "gfxPrefs.h" #include "gfxPrefs.h"
#include "libui/Input.h" #include "libui/Input.h"
#include "mozilla/ClearOnShutdown.h" #include "mozilla/ClearOnShutdown.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/Mutex.h" #include "mozilla/Mutex.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#include "mozilla/TouchEvents.h" #include "mozilla/TouchEvents.h"
@ -332,6 +333,21 @@ GeckoTouchDispatcher::ResampleTouchMoves(MultiTouchInput& aOutTouch, TimeStamp a
aOutTouch.mTimeStamp = sampleTime; aOutTouch.mTimeStamp = sampleTime;
} }
// Some touch events get sent as mouse events. If APZ doesn't capture the event
// and if a touch only has 1 touch input, we can send a mouse event.
void
GeckoTouchDispatcher::DispatchMouseEvent(MultiTouchInput& aMultiTouch,
bool aForwardToChildren)
{
WidgetMouseEvent mouseEvent = aMultiTouch.ToWidgetMouseEvent(nullptr);
if (mouseEvent.message == NS_EVENT_NULL) {
return;
}
mouseEvent.mFlags.mNoCrossProcessBoundaryForwarding = !aForwardToChildren;
nsWindow::DispatchInputEvent(mouseEvent);
}
static bool static bool
IsExpired(const MultiTouchInput& aTouch) IsExpired(const MultiTouchInput& aTouch)
{ {
@ -356,7 +372,9 @@ GeckoTouchDispatcher::DispatchTouchEvent(MultiTouchInput& aMultiTouch)
return; return;
} }
nsWindow::DispatchTouchInput(aMultiTouch); bool captured = false;
WidgetTouchEvent event = aMultiTouch.ToWidgetTouchEvent(nullptr);
nsEventStatus status = nsWindow::DispatchInputEvent(event, &captured);
if (mEnabledUniformityInfo && profiler_is_active()) { if (mEnabledUniformityInfo && profiler_is_active()) {
const char* touchAction = "Invalid"; const char* touchAction = "Invalid";
@ -377,6 +395,11 @@ GeckoTouchDispatcher::DispatchTouchEvent(MultiTouchInput& aMultiTouch)
TouchDataPayload* payload = new TouchDataPayload(touchPoint); TouchDataPayload* payload = new TouchDataPayload(touchPoint);
PROFILER_MARKER_PAYLOAD(touchAction, payload); PROFILER_MARKER_PAYLOAD(touchAction, payload);
} }
if (!captured && (aMultiTouch.mTouches.Length() == 1)) {
bool forwardToChildren = status != nsEventStatus_eConsumeNoDefault;
DispatchMouseEvent(aMultiTouch, forwardToChildren);
}
} }
} // namespace mozilla } // namespace mozilla

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

@ -47,9 +47,6 @@
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/layers/APZCTreeManager.h" #include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/layers/CompositorParent.h" #include "mozilla/layers/CompositorParent.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/TouchEvents.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "HwcComposer2D.h" #include "HwcComposer2D.h"
@ -230,91 +227,35 @@ nsWindow::NotifyVsync(TimeStamp aVsyncTimestamp)
} }
} }
/*static*/ nsEventStatus nsEventStatus
nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent) nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent, bool* aWasCaptured)
{ {
if (aWasCaptured) {
*aWasCaptured = false;
}
if (!gFocusedWindow) { if (!gFocusedWindow) {
return nsEventStatus_eIgnore; return nsEventStatus_eIgnore;
} }
gFocusedWindow->UserActivity(); gFocusedWindow->UserActivity();
nsEventStatus status;
aEvent.widget = gFocusedWindow; aEvent.widget = gFocusedWindow;
if (TabParent* capturer = TabParent::GetEventCapturer()) {
bool captured = capturer->TryCapture(aEvent);
if (aWasCaptured) {
*aWasCaptured = captured;
}
if (captured) {
return nsEventStatus_eConsumeNoDefault;
}
}
nsEventStatus status;
gFocusedWindow->DispatchEvent(&aEvent, status); gFocusedWindow->DispatchEvent(&aEvent, status);
return status; return status;
} }
/*static*/ void
nsWindow::DispatchTouchInput(MultiTouchInput& aInput)
{
if (!gFocusedWindow) {
return;
}
gFocusedWindow->UserActivity();
gFocusedWindow->DispatchTouchInputViaAPZ(aInput);
}
void
nsWindow::DispatchTouchInputViaAPZ(MultiTouchInput& aInput)
{
if (!mAPZC) {
// In general mAPZC should not be null, but during initial setup
// it might be, so we handle that case by ignoring touch input there.
return;
}
// First send it through the APZ code
mozilla::layers::ScrollableLayerGuid guid;
uint64_t inputBlockId;
nsEventStatus rv = mAPZC->ReceiveInputEvent(aInput, &guid, &inputBlockId);
// If the APZ says to drop it, then we drop it
if (rv == nsEventStatus_eConsumeNoDefault) {
return;
}
// Convert it to an event we can send to Gecko
WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this);
// If there is an event capturing child process, send it directly there.
// This happens if we already sent a touchstart event through the root
// process hit test and it ended up going to a child process. The event
// capturing process should get all subsequent touch events in the same
// event block. In this case the TryCapture call below will return true,
// and the child process will take care of responding to the event as needed
// so we don't need to do anything else here.
if (TabParent* capturer = TabParent::GetEventCapturer()) {
InputAPZContext context(guid, inputBlockId);
if (capturer->TryCapture(event)) {
return;
}
}
// If it didn't get captured, dispatch the event into the gecko root process
// for "normal" flow. The event might get sent to the child process still,
// but if it doesn't we need to notify the APZ of various things. All of
// that happens in DispatchEventForAPZ
rv = DispatchEventForAPZ(&event, guid, inputBlockId);
// Finally, if the touch event had only one touch point, generate a mouse
// event for it and send it through the gecko root process.
// Technically we should not need to do this if the touch event was routed
// to the child process, but that seems to expose a bug in B2G where the
// keyboard doesn't go away in some cases.
// Also for now we're dispatching mouse events from all touch events because
// we need this for click events to work in the chrome process. Once we have
// APZ and ChromeProcessController::HandleSingleTap working for the chrome
// process we shouldn't need to do this at all.
if (event.touches.Length() == 1) {
WidgetMouseEvent mouseEvent = aInput.ToWidgetMouseEvent(this);
if (mouseEvent.message != NS_EVENT_NULL) {
mouseEvent.mFlags.mNoCrossProcessBoundaryForwarding = (rv == nsEventStatus_eConsumeNoDefault);
DispatchEvent(&mouseEvent, rv);
}
}
}
NS_IMETHODIMP NS_IMETHODIMP
nsWindow::Create(nsIWidget *aParent, nsWindow::Create(nsIWidget *aParent,
void *aNativeParent, void *aNativeParent,

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

@ -16,7 +16,6 @@
#ifndef nsWindow_h #ifndef nsWindow_h
#define nsWindow_h #define nsWindow_h
#include "InputData.h"
#include "nsBaseWidget.h" #include "nsBaseWidget.h"
#include "nsRegion.h" #include "nsRegion.h"
#include "nsIIdleServiceInternal.h" #include "nsIIdleServiceInternal.h"
@ -52,8 +51,8 @@ public:
static void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp); static void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp);
static void DoDraw(void); static void DoDraw(void);
static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent); static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent,
static void DispatchTouchInput(mozilla::MultiTouchInput& aInput); bool* aWasCaptured = nullptr);
NS_IMETHOD Create(nsIWidget *aParent, NS_IMETHOD Create(nsIWidget *aParent,
void *aNativeParent, void *aNativeParent,
@ -88,7 +87,6 @@ public:
return NS_OK; return NS_OK;
} }
virtual nsIntPoint WidgetToScreenOffset(); virtual nsIntPoint WidgetToScreenOffset();
void DispatchTouchInputViaAPZ(mozilla::MultiTouchInput& aInput);
NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
nsEventStatus& aStatus); nsEventStatus& aStatus);
NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,