mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 918273 - Add an apzc tree manager helper for translating device to gecko coordinate space, and use it when sending events to the dom in cases where content is consuming touch. r=kats
This commit is contained in:
parent
4b7c1d4e1c
commit
719c8ac7d1
@ -398,6 +398,24 @@ APZCTreeManager::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
APZCTreeManager::TransformCoordinateToGecko(const ScreenIntPoint& aPoint,
|
||||
LayoutDeviceIntPoint* aOutTransformedPoint)
|
||||
{
|
||||
MOZ_ASSERT(aOutTransformedPoint);
|
||||
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aPoint);
|
||||
if (apzc && aOutTransformedPoint) {
|
||||
gfx3DMatrix transformToApzc;
|
||||
gfx3DMatrix transformToGecko;
|
||||
GetInputTransforms(apzc, transformToApzc, transformToGecko);
|
||||
gfx3DMatrix outTransform = transformToApzc * transformToGecko;
|
||||
aOutTransformedPoint->x = aPoint.x;
|
||||
aOutTransformedPoint->y = aPoint.y;
|
||||
ApplyTransform(aOutTransformedPoint, outTransform);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsEventStatus
|
||||
APZCTreeManager::ProcessMouseEvent(const WidgetMouseEvent& aEvent,
|
||||
ScrollableLayerGuid* aOutTargetGuid,
|
||||
@ -579,7 +597,7 @@ APZCTreeManager::HandleOverscroll(AsyncPanZoomController* aChild, ScreenPoint aS
|
||||
}
|
||||
|
||||
bool
|
||||
APZCTreeManager::HitTestAPZC(const ScreenPoint& aPoint)
|
||||
APZCTreeManager::HitTestAPZC(const ScreenIntPoint& aPoint)
|
||||
{
|
||||
MonitorAutoLock lock(mTreeLock);
|
||||
nsRefPtr<AsyncPanZoomController> target;
|
||||
|
@ -190,6 +190,15 @@ public:
|
||||
nsEventStatus ReceiveInputEvent(WidgetInputEvent& aEvent,
|
||||
ScrollableLayerGuid* aOutTargetGuid);
|
||||
|
||||
/**
|
||||
* A helper for transforming coordinates to gecko coordinate space.
|
||||
*
|
||||
* @param aPoint point to transform
|
||||
* @param aOutTransformedPoint resulting transformed point
|
||||
*/
|
||||
void TransformCoordinateToGecko(const ScreenIntPoint& aPoint,
|
||||
LayoutDeviceIntPoint* aOutTransformedPoint);
|
||||
|
||||
/**
|
||||
* Updates the composition bounds, i.e. the dimensions of the final size of
|
||||
* the frame this is tied to during composition onto, in device pixels. In
|
||||
@ -254,7 +263,7 @@ public:
|
||||
/**
|
||||
* Tests if a screen point intersect an apz in the tree.
|
||||
*/
|
||||
bool HitTestAPZC(const ScreenPoint& aPoint);
|
||||
bool HitTestAPZC(const ScreenIntPoint& aPoint);
|
||||
|
||||
/**
|
||||
* Set the dpi value used by all AsyncPanZoomControllers.
|
||||
|
@ -174,12 +174,22 @@ APZController::ContentReceivedTouch(const ScrollableLayerGuid& aGuid, bool aPrev
|
||||
}
|
||||
|
||||
bool
|
||||
APZController::HitTestAPZC(ScreenPoint& pt)
|
||||
APZController::HitTestAPZC(ScreenIntPoint& aPoint)
|
||||
{
|
||||
if (!sAPZC) {
|
||||
return false;
|
||||
}
|
||||
return sAPZC->HitTestAPZC(pt);
|
||||
return sAPZC->HitTestAPZC(aPoint);
|
||||
}
|
||||
|
||||
void
|
||||
APZController::TransformCoordinateToGecko(const ScreenIntPoint& aPoint,
|
||||
LayoutDeviceIntPoint* aRefPointOut)
|
||||
{
|
||||
if (!sAPZC || !aRefPointOut) {
|
||||
return;
|
||||
}
|
||||
sAPZC->TransformCoordinateToGecko(aPoint, aRefPointOut);
|
||||
}
|
||||
|
||||
nsEventStatus
|
||||
|
@ -38,7 +38,9 @@ public:
|
||||
void SetWidgetListener(nsIWidgetListener* aWidgetListener);
|
||||
void UpdateScrollOffset(const mozilla::layers::ScrollableLayerGuid& aScrollLayerId, CSSIntPoint& aScrollOffset);
|
||||
|
||||
bool HitTestAPZC(mozilla::ScreenPoint& pt);
|
||||
bool HitTestAPZC(mozilla::ScreenIntPoint& aPoint);
|
||||
void TransformCoordinateToGecko(const mozilla::ScreenIntPoint& aPoint,
|
||||
LayoutDeviceIntPoint* aRefPointOut);
|
||||
void ContentReceivedTouch(const ScrollableLayerGuid& aGuid, bool aPreventDefault);
|
||||
nsEventStatus ReceiveInputEvent(mozilla::WidgetInputEvent* aEvent,
|
||||
ScrollableLayerGuid* aOutTargetGuid);
|
||||
|
@ -668,19 +668,35 @@ MetroInput::TransformRefPoint(const Foundation::Point& aPosition, LayoutDeviceIn
|
||||
{
|
||||
// If this event is destined for content we need to transform our ref point through
|
||||
// the apz so that zoom can be accounted for.
|
||||
LayoutDeviceIntPoint pt = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(aPosition));
|
||||
aRefPointOut = pt;
|
||||
aRefPointOut = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(aPosition));
|
||||
ScreenIntPoint spt;
|
||||
spt.x = aRefPointOut.x;
|
||||
spt.y = aRefPointOut.y;
|
||||
// This is currently a general contained rect hit test, it may produce a false positive for
|
||||
// overlay chrome elements.
|
||||
bool apzIntersect = mWidget->ApzHitTest(mozilla::ScreenPoint(pt.x, pt.y));
|
||||
if (apzIntersect && HitTestChrome(pt)) {
|
||||
bool apzIntersect = mWidget->ApzHitTest(spt);
|
||||
if (apzIntersect && HitTestChrome(aRefPointOut)) {
|
||||
return;
|
||||
}
|
||||
WidgetMouseEvent event(true, NS_MOUSE_MOVE, mWidget.Get(),
|
||||
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
|
||||
event.refPoint = aRefPointOut;
|
||||
mWidget->ApzReceiveInputEvent(&event, nullptr);
|
||||
aRefPointOut = event.refPoint;
|
||||
mWidget->ApzTransformGeckoCoordinate(spt, &aRefPointOut);
|
||||
}
|
||||
|
||||
void
|
||||
MetroInput::TransformTouchEvent(WidgetTouchEvent* aEvent)
|
||||
{
|
||||
nsTArray< nsRefPtr<dom::Touch> >& touches = aEvent->touches;
|
||||
for (uint32_t i = 0; i < touches.Length(); ++i) {
|
||||
dom::Touch* touch = touches[i];
|
||||
if (touch) {
|
||||
LayoutDeviceIntPoint lpt;
|
||||
ScreenIntPoint spt;
|
||||
spt.x = touch->mRefPoint.x;
|
||||
spt.y = touch->mRefPoint.y;
|
||||
mWidget->ApzTransformGeckoCoordinate(spt, &lpt);
|
||||
touch->mRefPoint.x = lpt.x;
|
||||
touch->mRefPoint.y = lpt.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1115,7 +1131,7 @@ MetroInput::DeliverNextQueuedTouchEvent()
|
||||
if (mCancelable && event->message == NS_TOUCH_START) {
|
||||
nsRefPtr<Touch> touch = event->touches[0];
|
||||
LayoutDeviceIntPoint pt = LayoutDeviceIntPoint::FromUntyped(touch->mRefPoint);
|
||||
bool apzIntersect = mWidget->ApzHitTest(mozilla::ScreenPoint(pt.x, pt.y));
|
||||
bool apzIntersect = mWidget->ApzHitTest(mozilla::ScreenIntPoint(pt.x, pt.y));
|
||||
mChromeHitTestCacheForTouch = (apzIntersect && HitTestChrome(pt));
|
||||
}
|
||||
|
||||
@ -1172,11 +1188,14 @@ MetroInput::DeliverNextQueuedTouchEvent()
|
||||
return;
|
||||
}
|
||||
|
||||
// Forward event data to apz. Even if content is consuming input, we still
|
||||
// need APZC to transform the coordinates. It won't actually react to the
|
||||
// event if ContentReceivedTouch was called previously.
|
||||
DUMP_TOUCH_IDS("APZC(2)", event);
|
||||
status = mWidget->ApzReceiveInputEvent(event, nullptr);
|
||||
// If content is consuming touch, we need to transform event coords
|
||||
// through the apzc before sending. Otherwise send the event to apzc.
|
||||
if (mContentConsumingTouch) {
|
||||
TransformTouchEvent(event);
|
||||
} else {
|
||||
DUMP_TOUCH_IDS("APZC(2)", event);
|
||||
status = mWidget->ApzReceiveInputEvent(event, nullptr);
|
||||
}
|
||||
|
||||
// If content called preventDefault on touchstart or first touchmove send
|
||||
// the event to content only.
|
||||
|
@ -171,6 +171,7 @@ private:
|
||||
// Event processing helpers. See function definitions for more info.
|
||||
void TransformRefPoint(const Point& aPosition,
|
||||
LayoutDeviceIntPoint& aRefPointOut);
|
||||
void TransformTouchEvent(WidgetTouchEvent* aEvent);
|
||||
void OnPointerNonTouch(IPointerPoint* aPoint);
|
||||
void AddPointerMoveDataToRecognizer(IPointerEventArgs* aArgs);
|
||||
void InitGeckoMouseEventFromPointerPoint(WidgetMouseEvent* aEvent,
|
||||
|
@ -993,7 +993,7 @@ MetroWidget::ApzContentIgnoringTouch(const ScrollableLayerGuid& aGuid)
|
||||
}
|
||||
|
||||
bool
|
||||
MetroWidget::ApzHitTest(ScreenPoint& pt)
|
||||
MetroWidget::ApzHitTest(ScreenIntPoint& pt)
|
||||
{
|
||||
if (!mController) {
|
||||
return false;
|
||||
@ -1001,6 +1001,16 @@ MetroWidget::ApzHitTest(ScreenPoint& pt)
|
||||
return mController->HitTestAPZC(pt);
|
||||
}
|
||||
|
||||
void
|
||||
MetroWidget::ApzTransformGeckoCoordinate(const ScreenIntPoint& aPoint,
|
||||
LayoutDeviceIntPoint* aRefPointOut)
|
||||
{
|
||||
if (!mController) {
|
||||
return;
|
||||
}
|
||||
mController->TransformCoordinateToGecko(aPoint, aRefPointOut);
|
||||
}
|
||||
|
||||
nsEventStatus
|
||||
MetroWidget::ApzReceiveInputEvent(WidgetInputEvent* aEvent,
|
||||
ScrollableLayerGuid* aOutTargetGuid)
|
||||
|
@ -202,7 +202,11 @@ public:
|
||||
// apzc controller related api
|
||||
|
||||
// Hit test a point to see if an apzc would consume input there
|
||||
bool ApzHitTest(mozilla::ScreenPoint& pt);
|
||||
bool ApzHitTest(mozilla::ScreenIntPoint& pt);
|
||||
// Transforms a coord so that it properly targets gecko content based
|
||||
// on apzc transforms currently applied.
|
||||
void ApzTransformGeckoCoordinate(const mozilla::ScreenIntPoint& pt,
|
||||
mozilla::LayoutDeviceIntPoint* aRefPointOut);
|
||||
// send ContentRecievedTouch calls to the apz with appropriate preventDefault params
|
||||
void ApzContentConsumingTouch(const ScrollableLayerGuid& aGuid);
|
||||
void ApzContentIgnoringTouch(const ScrollableLayerGuid& aGuid);
|
||||
|
Loading…
Reference in New Issue
Block a user