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);
/**
* 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.
*/

View File

@ -888,6 +888,19 @@ TabChild::RecvHandleDoubleTap(const nsIntPoint& aPoint)
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
TabChild::RecvActivate()
{
@ -936,61 +949,67 @@ TabChild::RecvMouseWheelEvent(const WheelEvent& event)
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
TabChild::RecvRealTouchEvent(const nsTouchEvent& aEvent)
{
nsTouchEvent localEvent(aEvent);
nsEventStatus status = DispatchWidgetEvent(localEvent);
nsTouchEvent localEvent(aEvent);
nsEventStatus status = DispatchWidgetEvent(localEvent);
if (IsAsyncPanZoomEnabled()) {
nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(mWebNav);
nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow();
if (innerWindow && innerWindow->HasTouchEventListeners()) {
SendContentReceivedTouch(nsIPresShell::gPreventMouseEvents);
}
} else if (status != nsEventStatus_eConsumeNoDefault) {
DispatchSynthesizedMouseEvent(aEvent);
}
if (status == nsEventStatus_eConsumeNoDefault) {
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;
return true;
}
bool
TabChild::RecvRealTouchMoveEvent(const nsTouchEvent& aEvent)
{
return RecvRealTouchEvent(aEvent);
return RecvRealTouchEvent(aEvent);
}
bool

View File

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

View File

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

View File

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

View File

@ -524,7 +524,15 @@ nsEventStatus AsyncPanZoomController::OnLongPress(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;
}
@ -989,6 +997,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
// we get a larger displayport. This is very bad because we're wasting a
// paint and not initializating the displayport correctly.
RequestContentRepaint();
mState = NOTHING;
} else if (!mFrameMetrics.mCSSContentRect.IsEqualEdges(aViewportFrame.mCSSContentRect)) {
mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect;
SetPageRect(mFrameMetrics.mCSSContentRect);

View File

@ -31,6 +31,13 @@ public:
*/
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() {}
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; }
private: