Bug 787549 - B2G: Stop simulating mouse events unless there's a tap. r=cjones

This commit is contained in:
Doug Sherk 2012-09-14 21:16:32 -04:00
parent b1b683efed
commit 2d4610aea1
8 changed files with 111 additions and 41 deletions

View File

@ -292,6 +292,13 @@ child:
*/ */
HandleDoubleTap(nsIntPoint point); HandleDoubleTap(nsIntPoint point);
/**
* Requests handling of a single tap. |point| is in CSS pixels, relative to
* the scroll offset. This message is expected to send a "mousedown" and
* "mouseup" series of events at this point.
*/
HandleSingleTap(nsIntPoint point);
/** /**
* Sending an activate message moves focus to the child. * Sending an activate message moves focus to the child.
*/ */

View File

@ -888,6 +888,19 @@ TabChild::RecvHandleDoubleTap(const nsIntPoint& aPoint)
return true; return true;
} }
bool
TabChild::RecvHandleSingleTap(const nsIntPoint& aPoint)
{
if (!mCx || !mTabChildGlobal) {
return true;
}
RecvMouseEvent(NS_LITERAL_STRING("mousedown"), aPoint.x, aPoint.y, 0, 1, 0, false);
RecvMouseEvent(NS_LITERAL_STRING("mouseup"), aPoint.x, aPoint.y, 0, 1, 0, false);
return true;
}
bool bool
TabChild::RecvActivate() TabChild::RecvActivate()
{ {
@ -936,61 +949,67 @@ TabChild::RecvMouseWheelEvent(const WheelEvent& event)
return true; return true;
} }
void
TabChild::DispatchSynthesizedMouseEvent(const nsTouchEvent& aEvent)
{
// Synthesize a phony mouse event.
uint32_t msg;
switch (aEvent.message) {
case NS_TOUCH_START:
msg = NS_MOUSE_BUTTON_DOWN;
break;
case NS_TOUCH_MOVE:
msg = NS_MOUSE_MOVE;
break;
case NS_TOUCH_END:
case NS_TOUCH_CANCEL:
msg = NS_MOUSE_BUTTON_UP;
break;
default:
MOZ_NOT_REACHED("Unknown touch event message");
}
nsIntPoint refPoint(0, 0);
if (aEvent.touches.Length()) {
refPoint = aEvent.touches[0]->mRefPoint;
}
nsMouseEvent event(true, msg, NULL,
nsMouseEvent::eReal, nsMouseEvent::eNormal);
event.refPoint = refPoint;
event.time = aEvent.time;
event.button = nsMouseEvent::eLeftButton;
if (msg != NS_MOUSE_MOVE) {
event.clickCount = 1;
}
DispatchWidgetEvent(event);
}
bool bool
TabChild::RecvRealTouchEvent(const nsTouchEvent& aEvent) TabChild::RecvRealTouchEvent(const nsTouchEvent& aEvent)
{ {
nsTouchEvent localEvent(aEvent); nsTouchEvent localEvent(aEvent);
nsEventStatus status = DispatchWidgetEvent(localEvent); nsEventStatus status = DispatchWidgetEvent(localEvent);
if (IsAsyncPanZoomEnabled()) {
nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(mWebNav); nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(mWebNav);
nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow(); nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow();
if (innerWindow && innerWindow->HasTouchEventListeners()) { if (innerWindow && innerWindow->HasTouchEventListeners()) {
SendContentReceivedTouch(nsIPresShell::gPreventMouseEvents); SendContentReceivedTouch(nsIPresShell::gPreventMouseEvents);
} }
} else if (status != nsEventStatus_eConsumeNoDefault) {
DispatchSynthesizedMouseEvent(aEvent);
}
if (status == nsEventStatus_eConsumeNoDefault) { return true;
return true;
}
// Synthesize a phony mouse event.
uint32_t msg;
switch (aEvent.message) {
case NS_TOUCH_START:
msg = NS_MOUSE_BUTTON_DOWN;
break;
case NS_TOUCH_MOVE:
msg = NS_MOUSE_MOVE;
break;
case NS_TOUCH_END:
case NS_TOUCH_CANCEL:
msg = NS_MOUSE_BUTTON_UP;
break;
default:
MOZ_NOT_REACHED("Unknown touch event message");
}
nsIntPoint refPoint(0, 0);
if (aEvent.touches.Length()) {
refPoint = aEvent.touches[0]->mRefPoint;
}
nsMouseEvent event(true, msg, NULL,
nsMouseEvent::eReal, nsMouseEvent::eNormal);
event.refPoint = refPoint;
event.time = aEvent.time;
event.button = nsMouseEvent::eLeftButton;
if (msg != NS_MOUSE_MOVE) {
event.clickCount = 1;
}
DispatchWidgetEvent(event);
return true;
} }
bool bool
TabChild::RecvRealTouchMoveEvent(const nsTouchEvent& aEvent) TabChild::RecvRealTouchMoveEvent(const nsTouchEvent& aEvent)
{ {
return RecvRealTouchEvent(aEvent); return RecvRealTouchEvent(aEvent);
} }
bool bool

View File

@ -183,6 +183,7 @@ public:
virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size); virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size);
virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics); virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
virtual bool RecvHandleDoubleTap(const nsIntPoint& aPoint); virtual bool RecvHandleDoubleTap(const nsIntPoint& aPoint);
virtual bool RecvHandleSingleTap(const nsIntPoint& aPoint);
virtual bool RecvActivate(); virtual bool RecvActivate();
virtual bool RecvDeactivate(); virtual bool RecvDeactivate();
virtual bool RecvMouseEvent(const nsString& aType, virtual bool RecvMouseEvent(const nsString& aType,
@ -323,6 +324,9 @@ private:
void DispatchMessageManagerMessage(const nsAString& aMessageName, void DispatchMessageManagerMessage(const nsAString& aMessageName,
const nsACString& aJSONData); const nsACString& aJSONData);
// Sends a simulated mouse event from a touch event for compatibility.
void DispatchSynthesizedMouseEvent(const nsTouchEvent& aEvent);
nsresult nsresult
BrowserFrameProvideWindow(nsIDOMWindow* aOpener, BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
nsIURI* aURI, nsIURI* aURI,

View File

@ -252,6 +252,11 @@ void TabParent::HandleDoubleTap(const nsIntPoint& aPoint)
unused << SendHandleDoubleTap(aPoint); unused << SendHandleDoubleTap(aPoint);
} }
void TabParent::HandleSingleTap(const nsIntPoint& aPoint)
{
unused << SendHandleSingleTap(aPoint);
}
void void
TabParent::Activate() TabParent::Activate()
{ {

View File

@ -152,6 +152,7 @@ public:
void UpdateDimensions(const nsRect& rect, const nsIntSize& size); void UpdateDimensions(const nsRect& rect, const nsIntSize& size);
void UpdateFrame(const layers::FrameMetrics& aFrameMetrics); void UpdateFrame(const layers::FrameMetrics& aFrameMetrics);
void HandleDoubleTap(const nsIntPoint& aPoint); void HandleDoubleTap(const nsIntPoint& aPoint);
void HandleSingleTap(const nsIntPoint& aPoint);
void Activate(); void Activate();
void Deactivate(); void Deactivate();

View File

@ -524,7 +524,15 @@ nsEventStatus AsyncPanZoomController::OnLongPress(const TapGestureInput& aEvent)
} }
nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) { nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) {
// XXX: Implement this. if (mGeckoContentController) {
MonitorAutoLock monitor(mMonitor);
gfx::Point point = WidgetSpaceToCompensatedViewportSpace(
gfx::Point(aEvent.mPoint.x, aEvent.mPoint.y),
mFrameMetrics.mResolution.width);
mGeckoContentController->HandleSingleTap(nsIntPoint(NS_lround(point.x), NS_lround(point.y)));
return nsEventStatus_eConsumeNoDefault;
}
return nsEventStatus_eIgnore; return nsEventStatus_eIgnore;
} }
@ -989,6 +997,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
// we get a larger displayport. This is very bad because we're wasting a // we get a larger displayport. This is very bad because we're wasting a
// paint and not initializating the displayport correctly. // paint and not initializating the displayport correctly.
RequestContentRepaint(); RequestContentRepaint();
mState = NOTHING;
} else if (!mFrameMetrics.mCSSContentRect.IsEqualEdges(aViewportFrame.mCSSContentRect)) { } else if (!mFrameMetrics.mCSSContentRect.IsEqualEdges(aViewportFrame.mCSSContentRect)) {
mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect; mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect;
SetPageRect(mFrameMetrics.mCSSContentRect); SetPageRect(mFrameMetrics.mCSSContentRect);

View File

@ -31,6 +31,13 @@ public:
*/ */
virtual void HandleDoubleTap(const nsIntPoint& aPoint) = 0; virtual void HandleDoubleTap(const nsIntPoint& aPoint) = 0;
/**
* Requests handling a single tap. |aPoint| is in CSS pixels, relative to the
* current scroll offset. This should simulate and send to content a mouse
* button down, then mouse button up at |aPoint|.
*/
virtual void HandleSingleTap(const nsIntPoint& aPoint) = 0;
GeckoContentController() {} GeckoContentController() {}
virtual ~GeckoContentController() {} virtual ~GeckoContentController() {}
}; };

View File

@ -511,6 +511,23 @@ public:
} }
} }
virtual void HandleSingleTap(const nsIntPoint& aPoint) MOZ_OVERRIDE
{
if (MessageLoop::current() != mUILoop) {
// We have to send this message from the "UI thread" (main
// thread).
mUILoop->PostTask(
FROM_HERE,
NewRunnableMethod(this, &RemoteContentController::HandleSingleTap,
aPoint));
return;
}
if (mRenderFrame) {
TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
browser->HandleSingleTap(aPoint);
}
}
void ClearRenderFrame() { mRenderFrame = nullptr; } void ClearRenderFrame() { mRenderFrame = nullptr; }
private: private: