Bug 1309587 - PreventDefault() on suppressed/delayed key events that are sent back to parent. r=smaug, a=jcristau
authorJessica Jong <jjong>
Wed, 18 Jan 2017 01:08:00 -0500
changeset 353667 42c962cf86b582e3a4e5c66da278fa295289aa51
parent 353666 ece7cd2998707bed4c4489a253afcc5f1a31b49e
child 353668 0693440a205976a1530843fce55160bd2118e254
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, jcristau
bugs1309587
milestone52.0a2
Bug 1309587 - PreventDefault() on suppressed/delayed key events that are sent back to parent. r=smaug, a=jcristau
dom/ipc/TabChild.cpp
layout/base/nsPresShell.cpp
widget/BasicEvents.h
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1896,16 +1896,20 @@ TabChild::RecvRealKeyEvent(const WidgetK
   WidgetKeyboardEvent localEvent(event);
   localEvent.mWidget = mPuppetWidget;
   nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
 
   if (event.mMessage == eKeyDown) {
     mIgnoreKeyPressEvent = status == nsEventStatus_eConsumeNoDefault;
   }
 
+  if (localEvent.mFlags.mIsSuppressedOrDelayed) {
+    localEvent.PreventDefault();
+  }
+
   // If a response is desired from the content process, resend the key event.
   // If mAccessKeyForwardedToChild is set, then don't resend the key event yet
   // as RecvHandleAccessKey will do this.
   if (localEvent.mFlags.mWantReplyFromContentProcess) {
     SendReplyKeyEvent(localEvent);
   }
 
   if (localEvent.mAccessKeyForwardedToChild) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -7452,16 +7452,17 @@ PresShell::HandleEvent(nsIFrame* aFrame,
     if (aEvent->mMessage == eKeyDown) {
       mNoDelayedKeyEvents = true;
     } else if (!mNoDelayedKeyEvents) {
       DelayedEvent* event = new DelayedKeyEvent(aEvent->AsKeyboardEvent());
       if (!mDelayedEvents.AppendElement(event)) {
         delete event;
       }
     }
+    aEvent->mFlags.mIsSuppressedOrDelayed = true;
     return NS_OK;
   }
 
   nsIFrame* frame = aFrame;
 
   if (aEvent->IsUsingCoordinates()) {
     ReleasePointerCaptureCaller releasePointerCaptureCaller;
     if (mDocument) {
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -127,16 +127,20 @@ public:
   // was registered as a passive listener.
   bool mInPassiveListener: 1;
   // If mComposed is true, the event fired by nodes in shadow DOM can cross the
   // boundary of shadow DOM and light DOM.
   bool mComposed : 1;
   // Similar to mComposed. Set it to true to allow events cross the boundary
   // between native non-anonymous content and native anonymouse content
   bool mComposedInNativeAnonymousContent : 1;
+  // True if the event is suppressed or delayed. This is used when parent side
+  // process the key event after content side, parent side may drop the key
+  // event if it was suppressed or delayed in content side.
+  bool mIsSuppressedOrDelayed : 1;
 
   // If the event is being handled in target phase, returns true.
   inline bool InTargetPhase() const
   {
     return (mInBubblingPhase && mInCapturePhase);
   }
 
   /**