Bug 1473705 - Make nsPluginInstanceOwner listen to keypress event also in the system event group r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 06 Jul 2018 17:20:43 +0900
changeset 815183 dc6f1d3e6a11bcd394feb7f260a47d43d2413e3f
parent 815182 64734ec3245dfe5f8313d79f98ca5c8f74bbd942
child 815184 fc0d9d4bf1bf539107e72f5b9f99314e181c6989
push id115462
push userbmo:mreschenberg@berkeley.edu
push dateFri, 06 Jul 2018 22:06:52 +0000
reviewerssmaug
bugs1473705
milestone63.0a1
Bug 1473705 - Make nsPluginInstanceOwner listen to keypress event also in the system event group r=smaug nsPluginInstanceOwner currently listens to keypress event only in the default event group. However, in strict keypress event dispatching mode, keypress events are not fired in the default event group if the key combination is not printable. So, nsPluginInstanceOwner should listen to keypress event also in the system event group and should handle each keypress event only once. I.e., if printable keypress event is received in the system event group, it should be ignored since it should've already been handled in the default event group. MozReview-Commit-ID: LWTPpz2W5mz
dom/plugins/base/nsPluginInstanceOwner.cpp
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1466,16 +1466,29 @@ nsresult nsPluginInstanceOwner::Dispatch
     }
   }
 
   return NS_OK;
 }
 
 nsresult nsPluginInstanceOwner::ProcessKeyPress(Event* aKeyEvent)
 {
+  // ProcessKeyPress() may be called twice with same eKeyPress event.  One is
+  // by the event listener in the default event group and the other is by the
+  // event listener in the system event group.  When this is called in the
+  // latter case and the event must be fired in the default event group too,
+  // we don't need to do nothing anymore.
+  // XXX Do we need to check whether the document is in chrome?  In strictly
+  //     speaking, it must be yes.  However, our UI must not use plugin in
+  //     chrome.
+  if (!aKeyEvent->WidgetEventPtr()->mFlags.mOnlySystemGroupDispatchInContent &&
+      aKeyEvent->WidgetEventPtr()->mFlags.mInSystemGroup) {
+    return NS_OK;
+  }
+
 #ifdef XP_MACOSX
   return DispatchKeyToPlugin(aKeyEvent);
 #else
   if (SendNativeEvents())
     DispatchKeyToPlugin(aKeyEvent);
 
   if (mInstance) {
     // If this event is going to the plugin, we want to kill it.
@@ -2543,16 +2556,17 @@ nsPluginInstanceOwner::Destroy()
   content->RemoveEventListener(NS_LITERAL_STRING("mouseup"), this, false);
   content->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, false);
   content->RemoveEventListener(NS_LITERAL_STRING("mousemove"), this, false);
   content->RemoveEventListener(NS_LITERAL_STRING("click"), this, false);
   content->RemoveEventListener(NS_LITERAL_STRING("dblclick"), this, false);
   content->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, false);
   content->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, false);
   content->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, true);
+  content->RemoveSystemEventListener(NS_LITERAL_STRING("keypress"), this, true);
   content->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, true);
   content->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true);
   content->RemoveEventListener(NS_LITERAL_STRING("drop"), this, true);
   content->RemoveEventListener(NS_LITERAL_STRING("drag"), this, true);
   content->RemoveEventListener(NS_LITERAL_STRING("dragenter"), this, true);
   content->RemoveEventListener(NS_LITERAL_STRING("dragover"), this, true);
   content->RemoveEventListener(NS_LITERAL_STRING("dragleave"), this, true);
   content->RemoveEventListener(NS_LITERAL_STRING("dragexit"), this, true);
@@ -2870,17 +2884,21 @@ nsresult nsPluginInstanceOwner::Init(nsI
   aContent->AddEventListener(NS_LITERAL_STRING("click"), this, false,
                              false);
   aContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, false,
                              false);
   aContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, false,
                              false);
   aContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, false,
                              false);
+  // "keypress" event should be handled when it's in the default event group
+  // if the event is fired in content.  Otherwise, it should be handled when
+  // it's in the system event group.
   aContent->AddEventListener(NS_LITERAL_STRING("keypress"), this, true);
+  aContent->AddSystemEventListener(NS_LITERAL_STRING("keypress"), this, true);
   aContent->AddEventListener(NS_LITERAL_STRING("keydown"), this, true);
   aContent->AddEventListener(NS_LITERAL_STRING("keyup"), this, true);
   aContent->AddEventListener(NS_LITERAL_STRING("drop"), this, true);
   aContent->AddEventListener(NS_LITERAL_STRING("drag"), this, true);
   aContent->AddEventListener(NS_LITERAL_STRING("dragenter"), this, true);
   aContent->AddEventListener(NS_LITERAL_STRING("dragover"), this, true);
   aContent->AddEventListener(NS_LITERAL_STRING("dragleave"), this, true);
   aContent->AddEventListener(NS_LITERAL_STRING("dragexit"), this, true);