diff --git a/mobile/android/base/GeckoEvent.java b/mobile/android/base/GeckoEvent.java index 07a5cbd58da5..1aefd11582ff 100644 --- a/mobile/android/base/GeckoEvent.java +++ b/mobile/android/base/GeckoEvent.java @@ -68,6 +68,17 @@ public class GeckoEvent { private static final int COMPOSITOR_RESUME = 29; private static final int PAINT_LISTEN_START_EVENT = 30; + /** + * These DOM_KEY_LOCATION constants mirror the DOM KeyboardEvent's constants. + * @see https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent#Key_location_constants + */ + private static final int DOM_KEY_LOCATION_STANDARD = 0; + private static final int DOM_KEY_LOCATION_LEFT = 1; + private static final int DOM_KEY_LOCATION_RIGHT = 2; + private static final int DOM_KEY_LOCATION_NUMPAD = 3; + private static final int DOM_KEY_LOCATION_MOBILE = 4; + private static final int DOM_KEY_LOCATION_JOYSTICK = 5; + public static final int IME_COMPOSITION_END = 0; public static final int IME_COMPOSITION_BEGIN = 1; public static final int IME_SET_TEXT = 2; @@ -108,6 +119,7 @@ public class GeckoEvent { public int mRangeForeColor, mRangeBackColor; public Location mLocation; public Address mAddress; + public int mDomKeyLocation; public double mBandwidth; public boolean mCanBeMetered; @@ -177,6 +189,75 @@ public class GeckoEvent { mUnicodeChar = k.getUnicodeChar(); mRepeatCount = k.getRepeatCount(); mCharacters = k.getCharacters(); + mDomKeyLocation = isJoystickButton(mKeyCode) ? DOM_KEY_LOCATION_JOYSTICK : DOM_KEY_LOCATION_MOBILE; + } + + /** + * This method tests if a key is one of the described in: + * https://bugzilla.mozilla.org/show_bug.cgi?id=756504#c0 + * @param keyCode int with the key code (Android key constant from KeyEvent) + * @return true if the key is one of the listed above, false otherwise. + */ + private static boolean isJoystickButton(int keyCode) { + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_CENTER: + case KeyEvent.KEYCODE_DPAD_LEFT: + case KeyEvent.KEYCODE_DPAD_RIGHT: + case KeyEvent.KEYCODE_DPAD_DOWN: + case KeyEvent.KEYCODE_DPAD_UP: + return true; + default: + if (Build.VERSION.SDK_INT >= 12) { + return KeyEvent.isGamepadButton(keyCode); + } + return GeckoEvent.isGamepadButton(keyCode); + } + } + + /** + * This method is a replacement for the the KeyEvent.isGamepadButton method to be + * compatible with Build.VERSION.SDK_INT < 12. This is an implementantion of the + * same method isGamepadButton available after SDK 12. + * @param keyCode int with the key code (Android key constant from KeyEvent). + * @return True if the keycode is a gamepad button, such as {@link #KEYCODE_BUTTON_A}. + */ + private static boolean isGamepadButton(int keyCode) { + switch (keyCode) { + case KeyEvent.KEYCODE_BUTTON_A: + case KeyEvent.KEYCODE_BUTTON_B: + case KeyEvent.KEYCODE_BUTTON_C: + case KeyEvent.KEYCODE_BUTTON_X: + case KeyEvent.KEYCODE_BUTTON_Y: + case KeyEvent.KEYCODE_BUTTON_Z: + case KeyEvent.KEYCODE_BUTTON_L1: + case KeyEvent.KEYCODE_BUTTON_R1: + case KeyEvent.KEYCODE_BUTTON_L2: + case KeyEvent.KEYCODE_BUTTON_R2: + case KeyEvent.KEYCODE_BUTTON_THUMBL: + case KeyEvent.KEYCODE_BUTTON_THUMBR: + case KeyEvent.KEYCODE_BUTTON_START: + case KeyEvent.KEYCODE_BUTTON_SELECT: + case KeyEvent.KEYCODE_BUTTON_MODE: + case KeyEvent.KEYCODE_BUTTON_1: + case KeyEvent.KEYCODE_BUTTON_2: + case KeyEvent.KEYCODE_BUTTON_3: + case KeyEvent.KEYCODE_BUTTON_4: + case KeyEvent.KEYCODE_BUTTON_5: + case KeyEvent.KEYCODE_BUTTON_6: + case KeyEvent.KEYCODE_BUTTON_7: + case KeyEvent.KEYCODE_BUTTON_8: + case KeyEvent.KEYCODE_BUTTON_9: + case KeyEvent.KEYCODE_BUTTON_10: + case KeyEvent.KEYCODE_BUTTON_11: + case KeyEvent.KEYCODE_BUTTON_12: + case KeyEvent.KEYCODE_BUTTON_13: + case KeyEvent.KEYCODE_BUTTON_14: + case KeyEvent.KEYCODE_BUTTON_15: + case KeyEvent.KEYCODE_BUTTON_16: + return true; + default: + return false; + } } public static GeckoEvent createMotionEvent(MotionEvent m) { diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index 84af92347491..6c7895a39c2d 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -28,6 +28,7 @@ jfieldID AndroidGeckoEvent::jCharactersField = 0; jfieldID AndroidGeckoEvent::jCharactersExtraField = 0; jfieldID AndroidGeckoEvent::jKeyCodeField = 0; jfieldID AndroidGeckoEvent::jMetaStateField = 0; +jfieldID AndroidGeckoEvent::jDomKeyLocationField = 0; jfieldID AndroidGeckoEvent::jFlagsField = 0; jfieldID AndroidGeckoEvent::jUnicodeCharField = 0; jfieldID AndroidGeckoEvent::jRepeatCountField = 0; @@ -198,6 +199,7 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv) jCharactersExtraField = getField("mCharactersExtra", "Ljava/lang/String;"); jKeyCodeField = getField("mKeyCode", "I"); jMetaStateField = getField("mMetaState", "I"); + jDomKeyLocationField = getField("mDomKeyLocation", "I"); jFlagsField = getField("mFlags", "I"); jUnicodeCharField = getField("mUnicodeChar", "I"); jRepeatCountField = getField("mRepeatCount", "I"); @@ -465,6 +467,7 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj) case KEY_EVENT: mTime = jenv->GetLongField(jobj, jTimeField); mMetaState = jenv->GetIntField(jobj, jMetaStateField); + mDomKeyLocation = jenv->GetIntField(jobj, jDomKeyLocationField); mFlags = jenv->GetIntField(jobj, jFlagsField); mKeyCode = jenv->GetIntField(jobj, jKeyCodeField); mUnicodeChar = jenv->GetIntField(jobj, jUnicodeCharField); diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h index 99e779ddb6ba..fdf69d56fdbc 100644 --- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -584,6 +584,7 @@ public: nsAString& CharactersExtra() { return mCharactersExtra; } int KeyCode() { return mKeyCode; } int MetaState() { return mMetaState; } + int DomKeyLocation() { return mDomKeyLocation; } bool IsAltPressed() const { return (mMetaState & AndroidKeyEvent::META_ALT_MASK) != 0; } bool IsShiftPressed() const { return (mMetaState & AndroidKeyEvent::META_SHIFT_MASK) != 0; } int Flags() { return mFlags; } @@ -613,6 +614,7 @@ protected: nsTArray mPressures; nsIntRect mRect; int mFlags, mMetaState; + int mDomKeyLocation; int mKeyCode, mUnicodeChar; int mRepeatCount; int mOffset, mCount; @@ -663,6 +665,7 @@ protected: static jfieldID jCharactersExtraField; static jfieldID jKeyCodeField; static jfieldID jMetaStateField; + static jfieldID jDomKeyLocationField; static jfieldID jFlagsField; static jfieldID jOffsetField; static jfieldID jCountField; diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index b17313e92a4e..1523c7d0d914 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -1714,7 +1714,7 @@ nsWindow::InitKeyEvent(nsKeyEvent& event, AndroidGeckoEvent& key, key.IsAltPressed(), key.IsShiftPressed(), false); - event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE; + event.location = key.DomKeyLocation(); event.time = key.Time(); if (gMenu)