Bug 918273 - Cache the target scrollable layer id in metro input code and use it instead of the root layer id in ContentReceivedEvent calls. r=mbrbeck

This commit is contained in:
Jim Mathies 2013-11-10 10:43:18 -06:00
Родитель 2974de401e
Коммит bea9a62350
6 изменённых файлов: 100 добавлений и 30 удалений

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

@ -17,6 +17,7 @@
#include "nsIDOMWindowUtils.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsLayoutUtils.h"
#include "mozilla/TouchEvents.h"
//#define DEBUG_CONTROLLER 1
@ -163,6 +164,52 @@ APZController::SetWidgetListener(nsIWidgetListener* aWidgetListener)
mWidgetListener = aWidgetListener;
}
void
APZController::ContentReceivedTouch(const ScrollableLayerGuid& aGuid, bool aPreventDefault)
{
if (!sAPZC) {
return;
}
sAPZC->ContentReceivedTouch(aGuid, aPreventDefault);
}
bool
APZController::HitTestAPZC(ScreenPoint& pt)
{
if (!sAPZC) {
return false;
}
return sAPZC->HitTestAPZC(pt);
}
nsEventStatus
APZController::ReceiveInputEvent(WidgetInputEvent* aEvent,
ScrollableLayerGuid* aOutTargetGuid)
{
MOZ_ASSERT(aEvent);
if (!sAPZC) {
return nsEventStatus_eIgnore;
}
return sAPZC->ReceiveInputEvent(*aEvent->AsInputEvent(), aOutTargetGuid);
}
nsEventStatus
APZController::ReceiveInputEvent(WidgetInputEvent* aInEvent,
ScrollableLayerGuid* aOutTargetGuid,
WidgetInputEvent* aOutEvent)
{
MOZ_ASSERT(aInEvent);
MOZ_ASSERT(aOutEvent);
if (!sAPZC) {
return nsEventStatus_eIgnore;
}
return sAPZC->ReceiveInputEvent(*aInEvent->AsInputEvent(),
aOutTargetGuid,
aOutEvent);
}
// APZC sends us this request when we need to update the display port on
// the scrollable frame the apzc is managing.
void

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

@ -8,6 +8,7 @@
#include "mozilla/layers/GeckoContentController.h"
#include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/EventForwards.h"
#include "FrameMetrics.h"
#include "Units.h"
@ -21,6 +22,7 @@ class APZController :
public mozilla::layers::GeckoContentController
{
typedef mozilla::layers::FrameMetrics FrameMetrics;
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
public:
// GeckoContentController interface
@ -36,7 +38,16 @@ public:
void SetWidgetListener(nsIWidgetListener* aWidgetListener);
void UpdateScrollOffset(const mozilla::layers::ScrollableLayerGuid& aScrollLayerId, CSSIntPoint& aScrollOffset);
bool HitTestAPZC(mozilla::ScreenPoint& pt);
void ContentReceivedTouch(const ScrollableLayerGuid& aGuid, bool aPreventDefault);
nsEventStatus ReceiveInputEvent(mozilla::WidgetInputEvent* aEvent,
ScrollableLayerGuid* aOutTargetGuid);
nsEventStatus ReceiveInputEvent(mozilla::WidgetInputEvent* aInEvent,
ScrollableLayerGuid* aOutTargetGuid,
mozilla::WidgetInputEvent* aOutEvent);
public:
// todo: make this a member variable as prep for multiple views
static nsRefPtr<mozilla::layers::APZCTreeManager> sAPZC;
private:

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

@ -672,14 +672,14 @@ MetroInput::TransformRefPoint(const Foundation::Point& aPosition, LayoutDeviceIn
aRefPointOut = pt;
// This is currently a general contained rect hit test, it may produce a false positive for
// overlay chrome elements.
bool apzIntersect = mWidget->HitTestAPZC(mozilla::ScreenPoint(pt.x, pt.y));
bool apzIntersect = mWidget->ApzHitTest(mozilla::ScreenPoint(pt.x, pt.y));
if (apzIntersect && HitTestChrome(pt)) {
return;
}
WidgetMouseEvent event(true, NS_MOUSE_MOVE, mWidget.Get(),
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
event.refPoint = aRefPointOut;
mWidget->ApzReceiveInputEvent(&event);
mWidget->ApzReceiveInputEvent(&event, nullptr);
aRefPointOut = event.refPoint;
}
@ -1115,7 +1115,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->HitTestAPZC(mozilla::ScreenPoint(pt.x, pt.y));
bool apzIntersect = mWidget->ApzHitTest(mozilla::ScreenPoint(pt.x, pt.y));
mChromeHitTestCacheForTouch = (apzIntersect && HitTestChrome(pt));
}
@ -1133,7 +1133,7 @@ MetroInput::DeliverNextQueuedTouchEvent()
if (mCancelable) {
WidgetTouchEvent transformedEvent(*event);
DUMP_TOUCH_IDS("APZC(1)", event);
mWidget->ApzReceiveInputEvent(event, &transformedEvent);
mWidget->ApzReceiveInputEvent(event, &mTargetAPZCGuid, &transformedEvent);
DUMP_TOUCH_IDS("DOM(2)", event);
mWidget->DispatchEvent(mChromeHitTestCacheForTouch ? event : &transformedEvent, status);
if (event->message == NS_TOUCH_START) {
@ -1150,10 +1150,10 @@ MetroInput::DeliverNextQueuedTouchEvent()
// Let the apz know if content wants to consume touch events, or cancel
// the touch block for content.
if (mContentConsumingTouch) {
mWidget->ApzContentConsumingTouch();
mWidget->ApzContentConsumingTouch(mTargetAPZCGuid);
DispatchTouchCancel(event);
} else {
mWidget->ApzContentIgnoringTouch();
mWidget->ApzContentIgnoringTouch(mTargetAPZCGuid);
}
}
// If content is consuming touch don't generate any gesture based
@ -1168,7 +1168,7 @@ MetroInput::DeliverNextQueuedTouchEvent()
// 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);
status = mWidget->ApzReceiveInputEvent(event, nullptr);
// If content called preventDefault on touchstart or first touchmove send
// the event to content only.
@ -1216,7 +1216,7 @@ MetroInput::DispatchTouchCancel(WidgetTouchEvent* aEvent)
}
if (mContentConsumingTouch) {
DUMP_TOUCH_IDS("APZC(3)", &touchEvent);
mWidget->ApzReceiveInputEvent(&touchEvent);
mWidget->ApzReceiveInputEvent(&touchEvent, nullptr);
} else {
DUMP_TOUCH_IDS("DOM(5)", &touchEvent);
mWidget->DispatchEvent(&touchEvent, sThrowawayStatus);

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

@ -12,6 +12,7 @@
#include "mozwrlbase.h"
#include "nsDeque.h"
#include "mozilla/EventForwards.h"
#include "mozilla/layers/APZCTreeManager.h"
// System headers (alphabetical)
#include <EventToken.h> // EventRegistrationToken
@ -100,6 +101,8 @@ private:
typedef ABI::Windows::UI::Input::ITappedEventArgs ITappedEventArgs;
typedef ABI::Windows::UI::Input::ManipulationDelta ManipulationDelta;
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
public:
MetroInput(MetroWidget* aWidget,
ICoreWindow* aWindow);
@ -277,6 +280,7 @@ private:
void DispatchTouchCancel(WidgetTouchEvent* aEvent);
nsDeque mInputEventQueue;
mozilla::layers::ScrollableLayerGuid mTargetAPZCGuid;
static nsEventStatus sThrowawayStatus;
};

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

@ -973,57 +973,60 @@ CompositorParent* MetroWidget::NewCompositorParent(int aSurfaceWidth, int aSurfa
}
void
MetroWidget::ApzContentConsumingTouch()
MetroWidget::ApzContentConsumingTouch(const ScrollableLayerGuid& aGuid)
{
LogFunction();
if (!APZController::sAPZC) {
if (!mController) {
return;
}
APZController::sAPZC->ContentReceivedTouch(mRootLayerTreeId, true);
mController->ContentReceivedTouch(aGuid, true);
}
void
MetroWidget::ApzContentIgnoringTouch()
MetroWidget::ApzContentIgnoringTouch(const ScrollableLayerGuid& aGuid)
{
LogFunction();
if (!APZController::sAPZC) {
if (!mController) {
return;
}
APZController::sAPZC->ContentReceivedTouch(mRootLayerTreeId, false);
mController->ContentReceivedTouch(aGuid, false);
}
bool
MetroWidget::HitTestAPZC(ScreenPoint& pt)
MetroWidget::ApzHitTest(ScreenPoint& pt)
{
if (!APZController::sAPZC) {
if (!mController) {
return false;
}
return APZController::sAPZC->HitTestAPZC(pt);
return mController->HitTestAPZC(pt);
}
nsEventStatus
MetroWidget::ApzReceiveInputEvent(WidgetInputEvent* aEvent)
MetroWidget::ApzReceiveInputEvent(WidgetInputEvent* aEvent,
ScrollableLayerGuid* aOutTargetGuid)
{
MOZ_ASSERT(aEvent);
if (!APZController::sAPZC) {
if (!mController) {
return nsEventStatus_eIgnore;
}
return APZController::sAPZC->ReceiveInputEvent(*aEvent->AsInputEvent());
return mController->ReceiveInputEvent(aEvent, aOutTargetGuid);
}
nsEventStatus
MetroWidget::ApzReceiveInputEvent(WidgetInputEvent* aInEvent,
ScrollableLayerGuid* aOutTargetGuid,
WidgetInputEvent* aOutEvent)
{
MOZ_ASSERT(aInEvent);
MOZ_ASSERT(aOutEvent);
if (!APZController::sAPZC) {
if (!mController) {
return nsEventStatus_eIgnore;
}
return APZController::sAPZC->ReceiveInputEvent(*aInEvent->AsInputEvent(),
aOutEvent);
return mController->ReceiveInputEvent(aInEvent,
aOutTargetGuid,
aOutEvent);
}
LayerManager*

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

@ -56,6 +56,7 @@ class MetroWidget : public nsWindowBase,
typedef ABI::Windows::UI::Core::ICharacterReceivedEventArgs ICharacterReceivedEventArgs;
typedef mozilla::widget::winrt::FrameworkView FrameworkView;
typedef mozilla::widget::winrt::APZController APZController;
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
static LRESULT CALLBACK
StaticWindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParan, LPARAM aLParam);
@ -198,15 +199,19 @@ public:
virtual void SetTransparencyMode(nsTransparencyMode aMode);
virtual nsTransparencyMode GetTransparencyMode();
// APZ related apis
void ApzContentConsumingTouch();
void ApzContentIgnoringTouch();
nsEventStatus ApzReceiveInputEvent(mozilla::WidgetInputEvent* aEvent);
// apzc controller related api
// Hit test a point to see if an apzc would consume input there
bool ApzHitTest(mozilla::ScreenPoint& pt);
// send ContentRecievedTouch calls to the apz with appropriate preventDefault params
void ApzContentConsumingTouch(const ScrollableLayerGuid& aGuid);
void ApzContentIgnoringTouch(const ScrollableLayerGuid& aGuid);
// Input handling
nsEventStatus ApzReceiveInputEvent(mozilla::WidgetInputEvent* aEvent,
ScrollableLayerGuid* aOutTargetGuid);
nsEventStatus ApzReceiveInputEvent(mozilla::WidgetInputEvent* aInEvent,
ScrollableLayerGuid* aOutTargetGuid,
mozilla::WidgetInputEvent* aOutEvent);
bool HitTestAPZC(mozilla::ScreenPoint& pt);
nsresult RequestContentScroll();
void RequestContentRepaintImplMainThread();
protected:
friend class FrameworkView;