Bug 1369072 - part2: PresShell::HandleEvent() should retarget KeyboardEvent if focused document is invisible r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 05 Sep 2017 19:39:33 +0900
changeset 379692 1c3ac6cb53ea9c76c89d8e5d1cb1ee19703e1180
parent 379691 19f8a5d3da39cc4f2313f2dac2c4dbb04a6329e8
child 379693 ef1641e40903ff5e6cff94f2a1d1a3188598e563
push id32461
push userkwierso@gmail.com
push dateFri, 08 Sep 2017 20:15:32 +0000
treeherdermozilla-central@dd3736e98e4e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1369072
milestone57.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 1369072 - part2: PresShell::HandleEvent() should retarget KeyboardEvent if focused document is invisible r=smaug When focused document is invisible, PresShell::HandleEvent() won't dispatch any events. However, if it's KeyboardEvent, user cannot do anything only with keyboard. So, in this case, PresShell should retarget keyboard events to first visible ancestor. MozReview-Commit-ID: CvCBcYwvfbe
layout/base/PresShell.cpp
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -7316,18 +7316,31 @@ PresShell::HandleEvent(nsIFrame* aFrame,
                (aEvent->mClass == eMouseEventClass) ||
                (aEvent->mClass == eWheelEventClass)) {
       retargetEventDoc = GetPrimaryContentDocument();
 #endif
     }
 
     if (retargetEventDoc) {
       nsCOMPtr<nsIPresShell> presShell = retargetEventDoc->GetShell();
-      if (!presShell)
-        return NS_OK;
+      // Even if the document doesn't have PresShell, i.e., it's invisible, we
+      // need to dispatch only KeyboardEvent in its nearest visible document
+      // because key focus shouldn't be caught by invisible document.
+      if (!presShell) {
+        if (!aEvent->HasKeyEventMessage()) {
+          return NS_OK;
+        }
+        while (!presShell) {
+          retargetEventDoc = retargetEventDoc->GetParentDocument();
+          if (!retargetEventDoc) {
+            return NS_OK;
+          }
+          presShell = retargetEventDoc->GetShell();
+        }
+      }
 
       if (presShell != this) {
         nsIFrame* frame = presShell->GetRootFrame();
         if (!frame) {
           if (aEvent->mMessage == eQueryTextContent ||
               aEvent->IsContentCommandEvent()) {
             return NS_OK;
           }