Bug 1251346 - Fennec should not generate touch events from mouse events. r=kats

This commit is contained in:
Randall Barker 2016-03-11 15:29:50 -08:00
parent 2c98c3b096
commit 9a7d54c34b
8 changed files with 115 additions and 41 deletions

View File

@ -377,7 +377,8 @@ public class DynamicToolbarAnimator {
// we only care about single-finger drags here; any other kind of event
// should reset and cause us to start over.
if (event.getActionMasked() != MotionEvent.ACTION_MOVE ||
if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE ||
event.getActionMasked() != MotionEvent.ACTION_MOVE ||
event.getPointerCount() != 1)
{
if (mTouchStart != null) {

View File

@ -46,9 +46,9 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
float hScroll, float vScroll);
@WrapForJNI
private native boolean handleHoverEvent(
private native boolean handleMouseEvent(
int action, long time, int metaState,
float x, float y);
float x, float y, int buttons);
private boolean handleMotionEvent(MotionEvent event, boolean keepInViewCoordinates) {
if (mDestroyed) {
@ -127,7 +127,7 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
return handleScrollEvent(event.getEventTime(), event.getMetaState(), x, y, hScroll, vScroll);
}
private boolean handleHoverEvent(MotionEvent event) {
private boolean handleMouseEvent(MotionEvent event) {
if (mDestroyed) {
return false;
}
@ -143,7 +143,7 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
final float x = coords.x;
final float y = coords.y;
return handleHoverEvent(event.getActionMasked(), event.getEventTime(), event.getMetaState(), x, y);
return handleMouseEvent(event.getActionMasked(), event.getEventTime(), event.getMetaState(), x, y, event.getButtonState());
}
@ -171,7 +171,11 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
@Override
public boolean onTouchEvent(MotionEvent event) {
return handleMotionEvent(event, /* keepInViewCoordinates */ true);
if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
return handleMouseEvent(event);
} else {
return handleMotionEvent(event, /* keepInViewCoordinates */ true);
}
}
@Override
@ -183,7 +187,7 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
} else if ((action == MotionEvent.ACTION_HOVER_MOVE) ||
(action == MotionEvent.ACTION_HOVER_ENTER) ||
(action == MotionEvent.ACTION_HOVER_EXIT)) {
return handleHoverEvent(event);
return handleMouseEvent(event);
} else {
return false;
}

View File

@ -103,15 +103,18 @@ MouseInput::ToWidgetMouseEvent(nsIWidget* aWidget) const
"Can only convert To WidgetTouchEvent on main thread");
EventMessage msg = eVoidEvent;
uint32_t clickCount = 0;
switch (mType) {
case MOUSE_MOVE:
msg = eMouseMove;
break;
case MOUSE_UP:
msg = eMouseUp;
clickCount = 1;
break;
case MOUSE_DOWN:
msg = eMouseDown;
clickCount = 1;
break;
case MOUSE_DRAG_START:
msg = eDragStart;
@ -158,6 +161,9 @@ MouseInput::ToWidgetMouseEvent(nsIWidget* aWidget) const
event.refPoint =
RoundedToInt(ViewAs<LayoutDevicePixel>(mOrigin,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
event.clickCount = clickCount;
event.inputSource = mInputSource;
event.ignoreRootScrollFrame = true;
return event;
}

View File

@ -272,11 +272,12 @@ public:
NONE
};
MouseInput(MouseType aType, ButtonType aButtonType, int16_t aButtons, const ScreenPoint& aPoint,
MouseInput(MouseType aType, ButtonType aButtonType, uint16_t aInputSource, int16_t aButtons, const ScreenPoint& aPoint,
uint32_t aTime, TimeStamp aTimeStamp, Modifiers aModifiers)
: InputData(MOUSE_INPUT, aTime, aTimeStamp, aModifiers)
, mType(aType)
, mButtonType(aButtonType)
, mInputSource(aInputSource)
, mButtons(aButtons)
, mOrigin(aPoint)
{}
@ -285,6 +286,7 @@ public:
: InputData(MOUSE_INPUT)
, mType(MOUSE_NONE)
, mButtonType(NONE)
, mInputSource(0)
, mButtons(0)
{}
@ -297,6 +299,7 @@ public:
MouseType mType;
ButtonType mButtonType;
uint16_t mInputSource;
int16_t mButtons;
ScreenPoint mOrigin;
ParentLayerPoint mLocalOrigin;

View File

@ -294,14 +294,14 @@ public:
mozilla::jni::NativeStub<NativePanZoomController::DisposeNative_t, Impl>
::template Wrap<&Impl::DisposeNative>),
mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleHoverEvent_t>(
mozilla::jni::NativeStub<NativePanZoomController::HandleHoverEvent_t, Impl>
::template Wrap<&Impl::HandleHoverEvent>),
mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleMotionEvent_t>(
mozilla::jni::NativeStub<NativePanZoomController::HandleMotionEvent_t, Impl>
::template Wrap<&Impl::HandleMotionEvent>),
mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleMouseEvent_t>(
mozilla::jni::NativeStub<NativePanZoomController::HandleMouseEvent_t, Impl>
::template Wrap<&Impl::HandleMouseEvent>),
mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleScrollEvent_t>(
mozilla::jni::NativeStub<NativePanZoomController::HandleScrollEvent_t, Impl>
::template Wrap<&Impl::HandleScrollEvent>),

View File

@ -1538,12 +1538,12 @@ auto NativePanZoomController::Destroy() const -> void
constexpr char NativePanZoomController::DisposeNative_t::name[];
constexpr char NativePanZoomController::DisposeNative_t::signature[];
constexpr char NativePanZoomController::HandleHoverEvent_t::name[];
constexpr char NativePanZoomController::HandleHoverEvent_t::signature[];
constexpr char NativePanZoomController::HandleMotionEvent_t::name[];
constexpr char NativePanZoomController::HandleMotionEvent_t::signature[];
constexpr char NativePanZoomController::HandleMouseEvent_t::name[];
constexpr char NativePanZoomController::HandleMouseEvent_t::signature[];
constexpr char NativePanZoomController::HandleScrollEvent_t::name[];
constexpr char NativePanZoomController::HandleScrollEvent_t::signature[];

View File

@ -3625,24 +3625,6 @@ public:
mozilla::jni::ExceptionMode::ABORT;
};
struct HandleHoverEvent_t {
typedef NativePanZoomController Owner;
typedef bool ReturnType;
typedef bool SetterType;
typedef mozilla::jni::Args<
int32_t,
int64_t,
int32_t,
float,
float> Args;
static constexpr char name[] = "handleHoverEvent";
static constexpr char signature[] =
"(IJIFF)Z";
static const bool isStatic = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
struct HandleMotionEvent_t {
typedef NativePanZoomController Owner;
typedef bool ReturnType;
@ -3667,6 +3649,25 @@ public:
mozilla::jni::ExceptionMode::ABORT;
};
struct HandleMouseEvent_t {
typedef NativePanZoomController Owner;
typedef bool ReturnType;
typedef bool SetterType;
typedef mozilla::jni::Args<
int32_t,
int64_t,
int32_t,
float,
float,
int32_t> Args;
static constexpr char name[] = "handleMouseEvent";
static constexpr char signature[] =
"(IJIFFI)Z";
static const bool isStatic = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
struct HandleScrollEvent_t {
typedef NativePanZoomController Owner;
typedef bool ReturnType;

View File

@ -383,6 +383,7 @@ class nsWindow::NPZCSupport final
// Lock for keeping mWindow alive when accessed off of the Gecko thread.
Mutex mWindowLock;
NativePanZoomController::GlobalRef mNPZC;
int mPreviousButtons;
public:
typedef NativePanZoomController::Natives<NPZCSupport> Base;
@ -392,6 +393,7 @@ public:
: mWindow(aWindow)
, mWindowLock("NPZCSupport")
, mNPZC(aNPZC)
, mPreviousButtons(0)
{
if (mWindow->mNPZCSupport) {
mWindow->mNPZCSupport->DetachFromWindow();
@ -580,8 +582,51 @@ public:
return true;
}
bool HandleHoverEvent(int32_t aAction, int64_t aTime, int32_t aMetaState,
float aX, float aY)
static MouseInput::ButtonType GetButtonType(int button)
{
MouseInput::ButtonType result = MouseInput::NONE;
switch (button) {
case widget::sdk::MotionEvent::BUTTON_PRIMARY:
result = MouseInput::LEFT_BUTTON;
break;
case widget::sdk::MotionEvent::BUTTON_SECONDARY:
result = MouseInput::RIGHT_BUTTON;
break;
case widget::sdk::MotionEvent::BUTTON_TERTIARY:
result = MouseInput::MIDDLE_BUTTON;
break;
default:
break;
}
return result;
}
static int16_t ConvertButtons(int buttons) {
int16_t result = 0;
if (buttons & widget::sdk::MotionEvent::BUTTON_PRIMARY) {
result |= WidgetMouseEventBase::eLeftButtonFlag;
}
if (buttons & widget::sdk::MotionEvent::BUTTON_SECONDARY) {
result |= WidgetMouseEventBase::eRightButtonFlag;
}
if (buttons & widget::sdk::MotionEvent::BUTTON_TERTIARY) {
result |= WidgetMouseEventBase::eMiddleButtonFlag;
}
if (buttons & widget::sdk::MotionEvent::BUTTON_BACK) {
result |= WidgetMouseEventBase::e4thButtonFlag;
}
if (buttons & widget::sdk::MotionEvent::BUTTON_FORWARD) {
result |= WidgetMouseEventBase::e5thButtonFlag;
}
return result;
}
bool HandleMouseEvent(int32_t aAction, int64_t aTime, int32_t aMetaState,
float aX, float aY, int buttons)
{
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
@ -596,28 +641,42 @@ public:
return false;
}
MouseInput::MouseType type = MouseInput::MOUSE_NONE;
MouseInput::MouseType mouseType = MouseInput::MOUSE_NONE;
MouseInput::ButtonType buttonType = MouseInput::NONE;
switch (aAction) {
case AndroidMotionEvent::ACTION_DOWN:
mouseType = MouseInput::MOUSE_DOWN;
buttonType = GetButtonType(buttons ^ mPreviousButtons);
mPreviousButtons = buttons;
break;
case AndroidMotionEvent::ACTION_UP:
mouseType = MouseInput::MOUSE_UP;
buttonType = GetButtonType(buttons ^ mPreviousButtons);
mPreviousButtons = buttons;
break;
case AndroidMotionEvent::ACTION_MOVE:
mouseType = MouseInput::MOUSE_MOVE;
break;
case AndroidMotionEvent::ACTION_HOVER_MOVE:
type = MouseInput::MOUSE_MOVE;
mouseType = MouseInput::MOUSE_MOVE;
break;
case AndroidMotionEvent::ACTION_HOVER_ENTER:
type = MouseInput::MOUSE_WIDGET_ENTER;
mouseType = MouseInput::MOUSE_WIDGET_ENTER;
break;
case AndroidMotionEvent::ACTION_HOVER_EXIT:
type = MouseInput::MOUSE_WIDGET_EXIT;
mouseType = MouseInput::MOUSE_WIDGET_EXIT;
break;
default:
break;
}
if (type == MouseInput::MOUSE_NONE) {
if (mouseType == MouseInput::MOUSE_NONE) {
return false;
}
ScreenPoint origin = ScreenPoint(aX, aY);
MouseInput input(type, MouseInput::NONE, 0, origin, aTime, TimeStamp(), GetModifiers(aMetaState));
MouseInput input(mouseType, buttonType, nsIDOMMouseEvent::MOZ_SOURCE_MOUSE, ConvertButtons(buttons), origin, aTime, TimeStamp(), GetModifiers(aMetaState));
ScrollableLayerGuid guid;
uint64_t blockId;