Bug 907612 part.1 nsNativeKeyBindings for GTK should use nsKeyEvent.mNativeKeyEvent r=karlt
authorMasayuki Nakano <masayuki@d-toybox.com>
Sat, 24 Aug 2013 16:24:32 +0900
changeset 144201 0cd3864c919350d7f0e7c01495cd3a15243c47b4
parent 144200 f37447f59817f08f690c333cc1dda6ac71b0d832
child 144202 0a198e8168be51bcabb72d2af642145771ebe918
push id32906
push usermasayuki@d-toybox.com
push dateSat, 24 Aug 2013 07:24:38 +0000
treeherdermozilla-inbound@4d3e221584a0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs907612
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 907612 part.1 nsNativeKeyBindings for GTK should use nsKeyEvent.mNativeKeyEvent r=karlt
widget/gtk2/nsGtkKeyUtils.cpp
widget/gtk2/nsGtkKeyUtils.h
widget/gtk2/nsNativeKeyBindings.cpp
widget/gtk2/nsNativeKeyBindings.h
--- a/widget/gtk2/nsGtkKeyUtils.cpp
+++ b/widget/gtk2/nsGtkKeyUtils.cpp
@@ -843,98 +843,16 @@ KeymapWrapper::ComputeDOMKeyNameIndex(co
         default:
             break;
     }
 
     uint32_t ch = GetCharCodeFor(aGdkKeyEvent);
     return ch ? KEY_NAME_INDEX_PrintableKey : KEY_NAME_INDEX_Unidentified;
 }
 
-/* static */ guint
-KeymapWrapper::GuessGDKKeyval(uint32_t aDOMKeyCode)
-{
-    // First, try to handle alphanumeric input, not listed in nsKeycodes:
-    // most likely, more letters will be getting typed in than things in
-    // the key list, so we will look through these first.
-
-    if (aDOMKeyCode >= NS_VK_A && aDOMKeyCode <= NS_VK_Z) {
-        // gdk and DOM both use the ASCII codes for these keys.
-        return aDOMKeyCode;
-    }
-
-    // numbers
-    if (aDOMKeyCode >= NS_VK_0 && aDOMKeyCode <= NS_VK_9) {
-        // gdk and DOM both use the ASCII codes for these keys.
-        return aDOMKeyCode - NS_VK_0 + GDK_0;
-    }
-
-    switch (aDOMKeyCode) {
-        // keys in numpad
-        case NS_VK_MULTIPLY:  return GDK_KP_Multiply;
-        case NS_VK_ADD:       return GDK_KP_Add;
-        case NS_VK_SEPARATOR: return GDK_KP_Separator;
-        case NS_VK_SUBTRACT:  return GDK_KP_Subtract;
-        case NS_VK_DECIMAL:   return GDK_KP_Decimal;
-        case NS_VK_DIVIDE:    return GDK_KP_Divide;
-        case NS_VK_NUMPAD0:   return GDK_KP_0;
-        case NS_VK_NUMPAD1:   return GDK_KP_1;
-        case NS_VK_NUMPAD2:   return GDK_KP_2;
-        case NS_VK_NUMPAD3:   return GDK_KP_3;
-        case NS_VK_NUMPAD4:   return GDK_KP_4;
-        case NS_VK_NUMPAD5:   return GDK_KP_5;
-        case NS_VK_NUMPAD6:   return GDK_KP_6;
-        case NS_VK_NUMPAD7:   return GDK_KP_7;
-        case NS_VK_NUMPAD8:   return GDK_KP_8;
-        case NS_VK_NUMPAD9:   return GDK_KP_9;
-        // other prinable keys
-        case NS_VK_SPACE:               return GDK_space;
-        case NS_VK_COLON:               return GDK_colon;
-        case NS_VK_SEMICOLON:           return GDK_semicolon;
-        case NS_VK_LESS_THAN:           return GDK_less;
-        case NS_VK_EQUALS:              return GDK_equal;
-        case NS_VK_GREATER_THAN:        return GDK_greater;
-        case NS_VK_QUESTION_MARK:       return GDK_question;
-        case NS_VK_AT:                  return GDK_at;
-        case NS_VK_CIRCUMFLEX:          return GDK_asciicircum;
-        case NS_VK_EXCLAMATION:         return GDK_exclam;
-        case NS_VK_DOUBLE_QUOTE:        return GDK_quotedbl;
-        case NS_VK_HASH:                return GDK_numbersign;
-        case NS_VK_DOLLAR:              return GDK_dollar;
-        case NS_VK_PERCENT:             return GDK_percent;
-        case NS_VK_AMPERSAND:           return GDK_ampersand;
-        case NS_VK_UNDERSCORE:          return GDK_underscore;
-        case NS_VK_OPEN_PAREN:          return GDK_parenleft;
-        case NS_VK_CLOSE_PAREN:         return GDK_parenright;
-        case NS_VK_ASTERISK:            return GDK_asterisk;
-        case NS_VK_PLUS:                return GDK_plus;
-        case NS_VK_PIPE:                return GDK_bar;
-        case NS_VK_HYPHEN_MINUS:        return GDK_minus;
-        case NS_VK_OPEN_CURLY_BRACKET:  return GDK_braceleft;
-        case NS_VK_CLOSE_CURLY_BRACKET: return GDK_braceright;
-        case NS_VK_TILDE:               return GDK_asciitilde;
-        case NS_VK_COMMA:               return GDK_comma;
-        case NS_VK_PERIOD:              return GDK_period;
-        case NS_VK_SLASH:               return GDK_slash;
-        case NS_VK_BACK_QUOTE:          return GDK_grave;
-        case NS_VK_OPEN_BRACKET:        return GDK_bracketleft;
-        case NS_VK_BACK_SLASH:          return GDK_backslash;
-        case NS_VK_CLOSE_BRACKET:       return GDK_bracketright;
-        case NS_VK_QUOTE:               return GDK_apostrophe;
-    }
-
-    // misc other things
-    for (uint32_t i = 0; i < ArrayLength(kKeyPairs); ++i) {
-        if (kKeyPairs[i].DOMKeyCode == aDOMKeyCode) {
-            return kKeyPairs[i].GDKKeyval;
-        }
-    }
-
-    return 0;
-}
-
 /* static */ void
 KeymapWrapper::InitKeyEvent(nsKeyEvent& aKeyEvent,
                             GdkEventKey* aGdkKeyEvent)
 {
     KeymapWrapper* keymapWrapper = GetInstance();
 
     aKeyEvent.mKeyNameIndex =
         keymapWrapper->ComputeDOMKeyNameIndex(aGdkKeyEvent);
@@ -1052,16 +970,17 @@ KeymapWrapper::InitKeyEvent(nsKeyEvent& 
     }
 
     // The transformations above and in gdk for the keyval are not invertible
     // so link to the GdkEvent (which will vanish soon after return from the
     // event callback) to give plugins access to hardware_keycode and state.
     // (An XEvent would be nice but the GdkEvent is good enough.)
     aKeyEvent.pluginEvent = (void *)aGdkKeyEvent;
     aKeyEvent.time = aGdkKeyEvent->time;
+    aKeyEvent.mNativeKeyEvent = static_cast<void*>(aGdkKeyEvent);
 }
 
 /* static */ uint32_t
 KeymapWrapper::GetCharCodeFor(const GdkEventKey *aGdkKeyEvent)
 {
     // Anything above 0xf000 is considered a non-printable
     // Exception: directly encoded UCS characters
     if (aGdkKeyEvent->keyval > 0xf000 &&
--- a/widget/gtk2/nsGtkKeyUtils.h
+++ b/widget/gtk2/nsGtkKeyUtils.h
@@ -36,23 +36,16 @@ public:
     static uint32_t ComputeDOMKeyCode(const GdkEventKey* aGdkKeyEvent);
 
     /**
      * Compute a DOM key name index from aGdkKeyEvent.
      */
     KeyNameIndex ComputeDOMKeyNameIndex(const GdkEventKey* aGdkKeyEvent);
 
     /**
-     * Returns a GDK keyval which is related to the aDOMKeyCode.  However,
-     * it may not be same as original value since there are some lost
-     * information.
-     */
-    static guint GuessGDKKeyval(uint32_t aDOMKeyCode);
-
-    /**
      * Modifier is list of modifiers which we support in widget level.
      */
     enum Modifier {
         NOT_MODIFIER       = 0x0000,
         CAPS_LOCK          = 0x0001,
         NUM_LOCK           = 0x0002,
         SCROLL_LOCK        = 0x0004,
         SHIFT              = 0x0008,
--- a/widget/gtk2/nsNativeKeyBindings.cpp
+++ b/widget/gtk2/nsNativeKeyBindings.cpp
@@ -241,41 +241,53 @@ nsNativeKeyBindings::KeyDown(const nsNat
 {
   return false;
 }
 
 bool
 nsNativeKeyBindings::KeyPress(const nsNativeKeyEvent& aEvent,
                               DoCommandCallback aCallback, void *aCallbackData)
 {
-  uint32_t keyCode;
+  // If the native key event is set, it must be synthesized for tests.
+  // We just ignore such events because this behavior depends on system
+  // settings.
+  if (!aEvent.mGeckoEvent->mNativeKeyEvent) {
+    // It must be synthesized event or dispatched DOM event from chrome.
+    return false;
+  }
+
+  guint keyval;
 
-  if (aEvent.charCode != 0)
-    keyCode = gdk_unicode_to_keyval(aEvent.charCode);
-  else
-    keyCode = KeymapWrapper::GuessGDKKeyval(aEvent.keyCode);
+  if (aEvent.charCode) {
+    keyval = gdk_unicode_to_keyval(aEvent.charCode);
+  } else {
+    keyval =
+      static_cast<GdkEventKey*>(aEvent.mGeckoEvent->mNativeKeyEvent)->keyval;
+  }
 
-  if (KeyPressInternal(aEvent, aCallback, aCallbackData, keyCode))
+  if (KeyPressInternal(aEvent, aCallback, aCallbackData, keyval)) {
     return true;
+  }
 
   nsKeyEvent *nativeKeyEvent = aEvent.mGeckoEvent;
   if (!nativeKeyEvent ||
       (nativeKeyEvent->eventStructType != NS_KEY_EVENT &&
        nativeKeyEvent->message != NS_KEY_PRESS)) {
     return false;
   }
 
   for (uint32_t i = 0; i < nativeKeyEvent->alternativeCharCodes.Length(); ++i) {
     uint32_t ch = nativeKeyEvent->IsShift() ?
         nativeKeyEvent->alternativeCharCodes[i].mShiftedCharCode :
         nativeKeyEvent->alternativeCharCodes[i].mUnshiftedCharCode;
     if (ch && ch != aEvent.charCode) {
-      keyCode = gdk_unicode_to_keyval(ch);
-      if (KeyPressInternal(aEvent, aCallback, aCallbackData, keyCode))
+      keyval = gdk_unicode_to_keyval(ch);
+      if (KeyPressInternal(aEvent, aCallback, aCallbackData, keyval)) {
         return true;
+      }
     }
   }
 
 /* gtk_bindings_activate_event is preferable, but it has unresolved bug: http://bugzilla.gnome.org/show_bug.cgi?id=162726
 Also gtk_bindings_activate may work with some non-shortcuts operations (todo: check it)
 See bugs 411005 406407
 
   Code, which should be used after fixing http://bugzilla.gnome.org/show_bug.cgi?id=162726:
@@ -289,37 +301,31 @@ See bugs 411005 406407
 
   return false;
 }
 
 bool
 nsNativeKeyBindings::KeyPressInternal(const nsNativeKeyEvent& aEvent,
                                       DoCommandCallback aCallback,
                                       void *aCallbackData,
-                                      uint32_t aKeyCode)
+                                      guint aKeyval)
 {
-  int modifiers = 0;
-  if (aEvent.altKey)
-    modifiers |= GDK_MOD1_MASK;
-  if (aEvent.ctrlKey)
-    modifiers |= GDK_CONTROL_MASK;
-  if (aEvent.shiftKey)
-    modifiers |= GDK_SHIFT_MASK;
-  // we don't support meta
+  guint modifiers =
+    static_cast<GdkEventKey*>(aEvent.mGeckoEvent->mNativeKeyEvent)->state;
 
   gCurrentCallback = aCallback;
   gCurrentCallbackData = aCallbackData;
 
   gHandled = false;
 #if (MOZ_WIDGET_GTK == 2)
   gtk_bindings_activate(GTK_OBJECT(mNativeTarget),
-                        aKeyCode, GdkModifierType(modifiers));
+                        aKeyval, GdkModifierType(modifiers));
 #else
   gtk_bindings_activate(G_OBJECT(mNativeTarget),
-                        aKeyCode, GdkModifierType(modifiers));
+                        aKeyval, GdkModifierType(modifiers));
 #endif
 
   gCurrentCallback = nullptr;
   gCurrentCallbackData = nullptr;
 
   return gHandled;
 }
 
--- a/widget/gtk2/nsNativeKeyBindings.h
+++ b/widget/gtk2/nsNativeKeyBindings.h
@@ -50,14 +50,14 @@ public:
                                    void *aCallbackData);
 
 private:
   ~nsNativeKeyBindings() NS_HIDDEN;
 
   bool KeyPressInternal(const nsNativeKeyEvent& aEvent,
                           DoCommandCallback aCallback,
                           void *aCallbackData,
-                          uint32_t aKeyCode);
+                          guint aKeyval);
 
   GtkWidget *mNativeTarget;
 };
 
 #endif