Bug 1005815 - Extract TabChild::FireSingleTapEvent and its helpers into APZCCallbackHelper. r=kats,smaug

This commit is contained in:
Botond Ballo 2015-01-21 19:46:27 -05:00
parent c3768e9f48
commit e06320456a
4 changed files with 106 additions and 79 deletions

View File

@ -124,10 +124,10 @@ class TabChild::DelayedFireSingleTapEvent MOZ_FINAL : public nsITimerCallback
public:
NS_DECL_ISUPPORTS
DelayedFireSingleTapEvent(TabChild* aTabChild,
DelayedFireSingleTapEvent(nsIWidget* aWidget,
LayoutDevicePoint& aPoint,
nsITimer* aTimer)
: mTabChild(do_GetWeakReference(static_cast<nsITabChild*>(aTabChild)))
: mWidget(do_GetWeakReference(aWidget))
, mPoint(aPoint)
// Hold the reference count until we are called back.
, mTimer(aTimer)
@ -136,9 +136,9 @@ public:
NS_IMETHODIMP Notify(nsITimer*) MOZ_OVERRIDE
{
nsCOMPtr<nsITabChild> tabChild = do_QueryReferent(mTabChild);
if (tabChild) {
static_cast<TabChild*>(tabChild.get())->FireSingleTapEvent(mPoint);
nsCOMPtr<nsIWidget> widget = do_QueryReferent(mWidget);
if (widget) {
APZCCallbackHelper::FireSingleTapEvent(mPoint, widget);
}
mTimer = nullptr;
return NS_OK;
@ -153,7 +153,7 @@ private:
{
}
nsWeakPtr mTabChild;
nsWeakPtr mWidget;
LayoutDevicePoint mPoint;
nsCOMPtr<nsITimer> mTimer;
};
@ -602,46 +602,6 @@ TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
return newMetrics;
}
nsEventStatus
TabChildBase::DispatchSynthesizedMouseEvent(uint32_t aMsg, uint64_t aTime,
const LayoutDevicePoint& aRefPoint,
nsIWidget* aWidget)
{
MOZ_ASSERT(aMsg == NS_MOUSE_MOVE || aMsg == NS_MOUSE_BUTTON_DOWN ||
aMsg == NS_MOUSE_BUTTON_UP || aMsg == NS_MOUSE_MOZLONGTAP);
WidgetMouseEvent event(true, aMsg, nullptr,
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
event.refPoint = LayoutDeviceIntPoint(aRefPoint.x, aRefPoint.y);
event.time = aTime;
event.button = WidgetMouseEvent::eLeftButton;
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
event.ignoreRootScrollFrame = true;
if (aMsg != NS_MOUSE_MOVE) {
event.clickCount = 1;
}
event.widget = aWidget;
return DispatchWidgetEvent(event);
}
nsEventStatus
TabChildBase::DispatchWidgetEvent(WidgetGUIEvent& event)
{
if (!event.widget)
return nsEventStatus_eConsumeNoDefault;
if (TabParent* capturer = TabParent::GetEventCapturer()) {
if (capturer->TryCapture(event)) {
return nsEventStatus_eConsumeNoDefault;
}
}
nsEventStatus status;
NS_ENSURE_SUCCESS(event.widget->DispatchEvent(&event, status),
nsEventStatus_eConsumeNoDefault);
return status;
}
bool
TabChildBase::IsAsyncPanZoomEnabled()
{
@ -2155,14 +2115,14 @@ TabChild::RecvHandleSingleTap(const CSSPoint& aPoint, const ScrollableLayerGuid&
// If the active element isn't visually affected by the :active style, we
// have no need to wait the extra sActiveDurationMs to make the activation
// visually obvious to the user.
FireSingleTapEvent(currentPoint);
APZCCallbackHelper::FireSingleTapEvent(currentPoint, mWidget);
return true;
}
TABC_LOG("Active element uses style, scheduling timer for click event\n");
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
nsRefPtr<DelayedFireSingleTapEvent> callback =
new DelayedFireSingleTapEvent(this, currentPoint, timer);
new DelayedFireSingleTapEvent(mWidget, currentPoint, timer);
nsresult rv = timer->InitWithCallback(callback,
sActiveDurationMs,
nsITimer::TYPE_ONE_SHOT);
@ -2174,20 +2134,6 @@ TabChild::RecvHandleSingleTap(const CSSPoint& aPoint, const ScrollableLayerGuid&
return true;
}
void
TabChild::FireSingleTapEvent(LayoutDevicePoint aPoint)
{
if (mDestroyed) {
return;
}
TABC_LOG("Dispatching single-tap component events to %s\n",
Stringify(aPoint).c_str());
int time = 0;
DispatchSynthesizedMouseEvent(NS_MOUSE_MOVE, time, aPoint, mWidget);
DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_DOWN, time, aPoint, mWidget);
DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_UP, time, aPoint, mWidget);
}
bool
TabChild::RecvHandleLongTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId)
{
@ -2215,7 +2161,7 @@ TabChild::RecvHandleLongTap(const CSSPoint& aPoint, const ScrollableLayerGuid& a
* mWidget->GetDefaultScale();
int time = 0;
nsEventStatus status =
DispatchSynthesizedMouseEvent(NS_MOUSE_MOZLONGTAP, time, currentPoint, mWidget);
APZCCallbackHelper::DispatchSynthesizedMouseEvent(NS_MOUSE_MOZLONGTAP, time, currentPoint, mWidget);
eventHandled = (status == nsEventStatus_eConsumeNoDefault);
TABC_LOG("MOZLONGTAP event handled: %d\n", eventHandled);
}
@ -2342,7 +2288,7 @@ TabChild::RecvRealMouseEvent(const WidgetMouseEvent& event)
{
WidgetMouseEvent localEvent(event);
localEvent.widget = mWidget;
DispatchWidgetEvent(localEvent);
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
return true;
}
@ -2367,7 +2313,7 @@ TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
WidgetWheelEvent event(aEvent);
event.widget = mWidget;
DispatchWidgetEvent(event);
APZCCallbackHelper::DispatchWidgetEvent(event);
if (IsAsyncPanZoomEnabled()) {
SendContentReceivedInputBlock(aGuid, aInputBlockId, event.mFlags.mDefaultPrevented);
@ -2461,9 +2407,9 @@ TabChild::UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus)
case NS_TOUCH_END:
if (!nsIPresShell::gPreventMouseEvents) {
DispatchSynthesizedMouseEvent(NS_MOUSE_MOVE, time, currentPoint, mWidget);
DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_DOWN, time, currentPoint, mWidget);
DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_UP, time, currentPoint, mWidget);
APZCCallbackHelper::DispatchSynthesizedMouseEvent(NS_MOUSE_MOVE, time, currentPoint, mWidget);
APZCCallbackHelper::DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_DOWN, time, currentPoint, mWidget);
APZCCallbackHelper::DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_UP, time, currentPoint, mWidget);
}
// fall through
case NS_TOUCH_CANCEL:
@ -2702,7 +2648,7 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
WidgetTouchEvent localEvent(aEvent);
localEvent.widget = mWidget;
// Dispatch event to content (potentially a long-running operation)
nsEventStatus status = DispatchWidgetEvent(localEvent);
nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
if (!IsAsyncPanZoomEnabled()) {
UpdateTapState(localEvent, status);
@ -2807,7 +2753,7 @@ TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event,
WidgetKeyboardEvent localEvent(event);
localEvent.widget = mWidget;
nsEventStatus status = DispatchWidgetEvent(localEvent);
nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
if (event.message == NS_KEY_DOWN) {
mIgnoreKeyPressEvent = status == nsEventStatus_eConsumeNoDefault;
@ -2844,7 +2790,7 @@ TabChild::RecvCompositionEvent(const WidgetCompositionEvent& event)
{
WidgetCompositionEvent localEvent(event);
localEvent.widget = mWidget;
DispatchWidgetEvent(localEvent);
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
return true;
}
@ -2853,7 +2799,7 @@ TabChild::RecvSelectionEvent(const WidgetSelectionEvent& event)
{
WidgetSelectionEvent localEvent(event);
localEvent.widget = mWidget;
DispatchWidgetEvent(localEvent);
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
return true;
}

View File

@ -196,10 +196,6 @@ public:
const bool& aIsRoot,
const mozilla::layers::ZoomConstraints& aConstraints) = 0;
nsEventStatus DispatchSynthesizedMouseEvent(uint32_t aMsg, uint64_t aTime,
const LayoutDevicePoint& aRefPoint,
nsIWidget* aWidget);
protected:
virtual ~TabChildBase();
CSSSize GetPageSize(nsCOMPtr<nsIDocument> aDocument, const CSSSize& aViewport);
@ -221,8 +217,6 @@ protected:
void DispatchMessageManagerMessage(const nsAString& aMessageName,
const nsAString& aJSONData);
nsEventStatus DispatchWidgetEvent(WidgetGUIEvent& event);
void InitializeRootMetrics();
mozilla::layers::FrameMetrics ProcessUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
@ -659,7 +653,6 @@ private:
bool mPendingTouchPreventedResponse;
ScrollableLayerGuid mPendingTouchPreventedGuid;
uint64_t mPendingTouchPreventedBlockId;
void FireSingleTapEvent(LayoutDevicePoint aPoint);
bool mTouchEndCancelled;
bool mEndTouchIsClick;

View File

@ -4,7 +4,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "APZCCallbackHelper.h"
#include "gfxPlatform.h" // For gfxPlatform::UseTiling
#include "mozilla/dom/TabParent.h"
#include "nsIScrollableFrame.h"
#include "nsLayoutUtils.h"
#include "nsIDOMElement.h"
@ -13,9 +15,14 @@
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#define APZCCH_LOG(...)
// #define APZCCH_LOG(...) printf_stderr("APZCCH: " __VA_ARGS__)
namespace mozilla {
namespace layers {
using dom::TabParent;
bool
APZCCallbackHelper::HasValidPresShellId(nsIDOMWindowUtils* aUtils,
const FrameMetrics& aMetrics)
@ -360,5 +367,67 @@ APZCCallbackHelper::ApplyCallbackTransform(const nsIntPoint& aPoint,
return nsIntPoint(ret.x, ret.y);
}
nsEventStatus
APZCCallbackHelper::DispatchWidgetEvent(WidgetGUIEvent& aEvent)
{
if (!aEvent.widget)
return nsEventStatus_eConsumeNoDefault;
// A nested process may be capturing events.
if (TabParent* capturer = TabParent::GetEventCapturer()) {
if (capturer->TryCapture(aEvent)) {
// Only touch events should be captured, and touch events from a parent
// process should not make it here. Capture for those is done elsewhere
// (for gonk, in nsWindow::DispatchTouchInputViaAPZ).
MOZ_ASSERT(!XRE_IsParentProcess());
return nsEventStatus_eConsumeNoDefault;
}
}
nsEventStatus status;
NS_ENSURE_SUCCESS(aEvent.widget->DispatchEvent(&aEvent, status),
nsEventStatus_eConsumeNoDefault);
return status;
}
nsEventStatus
APZCCallbackHelper::DispatchSynthesizedMouseEvent(uint32_t aMsg,
uint64_t aTime,
const LayoutDevicePoint& aRefPoint,
nsIWidget* aWidget)
{
MOZ_ASSERT(aMsg == NS_MOUSE_MOVE || aMsg == NS_MOUSE_BUTTON_DOWN ||
aMsg == NS_MOUSE_BUTTON_UP || aMsg == NS_MOUSE_MOZLONGTAP);
WidgetMouseEvent event(true, aMsg, nullptr,
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
event.refPoint = LayoutDeviceIntPoint(aRefPoint.x, aRefPoint.y);
event.time = aTime;
event.button = WidgetMouseEvent::eLeftButton;
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
event.ignoreRootScrollFrame = true;
if (aMsg != NS_MOUSE_MOVE) {
event.clickCount = 1;
}
event.widget = aWidget;
return DispatchWidgetEvent(event);
}
void
APZCCallbackHelper::FireSingleTapEvent(const LayoutDevicePoint& aPoint,
nsIWidget* aWidget)
{
if (aWidget->Destroyed()) {
return;
}
APZCCH_LOG("Dispatching single-tap component events to %s\n",
Stringify(aPoint).c_str());
int time = 0;
DispatchSynthesizedMouseEvent(NS_MOUSE_MOVE, time, aPoint, aWidget);
DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_DOWN, time, aPoint, aWidget);
DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_UP, time, aPoint, aWidget);
}
}
}

View File

@ -7,10 +7,12 @@
#define mozilla_layers_APZCCallbackHelper_h
#include "FrameMetrics.h"
#include "mozilla/EventForwards.h"
#include "nsIDOMWindowUtils.h"
class nsIContent;
class nsIDocument;
class nsIWidget;
template<class T> struct already_AddRefed;
namespace mozilla {
@ -104,6 +106,23 @@ public:
const ScrollableLayerGuid& aGuid,
const CSSToLayoutDeviceScale& aScale,
float aPresShellResolution);
/* Dispatch a widget event via the widget stored in the event, if any.
* In a child process, allows the TabParent event-capture mechanism to
* intercept the event. */
static nsEventStatus DispatchWidgetEvent(WidgetGUIEvent& aEvent);
/* Synthesize a mouse event with the given parameters, and dispatch it
* via the given widget. */
static nsEventStatus DispatchSynthesizedMouseEvent(uint32_t aMsg,
uint64_t aTime,
const LayoutDevicePoint& aRefPoint,
nsIWidget* aWidget);
/* Fire a single-tap event at the given point. The event is dispatched
* via the given widget. */
static void FireSingleTapEvent(const LayoutDevicePoint& aPoint,
nsIWidget* aWidget);
};
}