Bug 613748 - Keyboard inputs do not work when tab-modal alerts are open in another tab. r=smaug, a=drivers for API change
authorNeil Deakin <enndeakin@gmail.com>
Wed, 24 Nov 2010 17:44:46 -0800
changeset 58209 34447b39697a5452ea6d15f186d1f79d207fa7c2
parent 58208 b890963a137e17289bad18cf5c532996d9a3205d
child 58210 dde5e4be82c1becb378e8813678d59a7a324d16b
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewerssmaug, drivers
bugs613748
milestone2.0b8pre
Bug 613748 - Keyboard inputs do not work when tab-modal alerts are open in another tab. r=smaug, a=drivers for API change
dom/base/nsDOMWindowUtils.cpp
layout/base/nsPresShell.cpp
view/public/nsIViewObserver.h
view/src/nsViewManager.cpp
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -398,17 +398,17 @@ nsDOMWindowUtils::SendMouseEventCommon(c
     if (!viewManager)
       return NS_ERROR_FAILURE;
     nsIView* view = nsnull;
     rv = viewManager->GetRootView(view);
     if (NS_FAILED(rv) || !view)
       return NS_ERROR_FAILURE;
 
     status = nsEventStatus_eIgnore;
-    rv = vo->HandleEvent(view, &event, &status);
+    rv = vo->HandleEvent(view, &event, PR_FALSE, &status);
   } else {
     rv = widget->DispatchEvent(&event, status);
   }
   return rv;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendMouseScrollEvent(const nsAString& aType,
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -847,16 +847,17 @@ public:
                    nsIView* aViewToPaint,
                    nsIWidget* aWidget,
                    const nsRegion& aDirtyRegion,
                    const nsIntRegion& aIntDirtyRegion,
                    PRBool aPaintDefaultBackground,
                    PRBool aWillSendDidPaint);
   NS_IMETHOD HandleEvent(nsIView*        aView,
                          nsGUIEvent*     aEvent,
+                         PRBool          aDontRetargetEvents,
                          nsEventStatus*  aEventStatus);
   virtual NS_HIDDEN_(nsresult) HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                                         nsEvent* aEvent,
                                                         nsEventStatus* aStatus);
   virtual NS_HIDDEN_(nsresult) HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                                         nsIDOMEvent* aEvent,
                                                         nsEventStatus* aStatus);
   NS_IMETHOD ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight);
@@ -1294,20 +1295,16 @@ protected:
   PRBool ScheduleReflowOffTimer();
   
 #ifdef MOZ_REFLOW_PERF
   ReflowCountMgr * mReflowCountMgr;
 #endif
 
   static PRBool sDisableNonTestMouseEvents;
 
-  // false if a check should be done for key/ime events that should be
-  // retargeted to the currently focused presshell
-  static PRBool sDontRetargetEvents;
-
 private:
 
   PRBool InZombieDocument(nsIContent *aContent);
   already_AddRefed<nsIPresShell> GetParentPresShell();
   nsresult RetargetEventToParent(nsGUIEvent* aEvent,
                                  nsEventStatus*  aEventStatus);
 
   //helper funcs for event handling
@@ -1460,17 +1457,16 @@ public:
       }
     }
   }
 
   nsRefPtr<PresShell> mPresShell;
 };
 
 PRBool PresShell::sDisableNonTestMouseEvents = PR_FALSE;
-PRBool PresShell::sDontRetargetEvents = PR_FALSE;
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* PresShell::gLog;
 #endif
 
 #ifdef NS_DEBUG
 static void
 VerifyStyleTree(nsPresContext* aPresContext, nsFrameManager* aFrameManager)
@@ -6288,20 +6284,17 @@ PresShell::RetargetEventToParent(nsGUIEv
   if (!parentViewObserver) {
     return NS_ERROR_FAILURE;
   }
 
   // Fake the event as though it'ss from the parent pres shell's root view.
   nsIView *parentRootView;
   parentPresShell->GetViewManager()->GetRootView(parentRootView);
   
-  sDontRetargetEvents = PR_TRUE;
-  nsresult rv = parentViewObserver->HandleEvent(parentRootView, aEvent, aEventStatus);
-  sDontRetargetEvents = PR_FALSE;
-  return rv;
+  return parentViewObserver->HandleEvent(parentRootView, aEvent, PR_TRUE, aEventStatus);
 }
 
 void
 PresShell::DisableNonTestMouseEvents(PRBool aDisable)
 {
   sDisableNonTestMouseEvents = aDisable;
 }
 
@@ -6313,16 +6306,17 @@ PresShell::GetFocusedDOMWindowInOurWindo
   nsPIDOMWindow* focusedWindow;
   nsFocusManager::GetFocusedDescendant(rootWindow, PR_TRUE, &focusedWindow);
   return focusedWindow;
 }
 
 NS_IMETHODIMP
 PresShell::HandleEvent(nsIView         *aView,
                        nsGUIEvent*     aEvent,
+                       PRBool          aDontRetargetEvents,
                        nsEventStatus*  aEventStatus)
 {
   NS_ASSERTION(aView, "null view");
 
   if (mIsDestroying ||
       (sDisableNonTestMouseEvents && NS_IS_MOUSE_EVENT(aEvent) &&
        !(aEvent->flags & NS_EVENT_FLAG_SYNTHETIC_TEST_EVENT))) {
     return NS_OK;
@@ -6342,17 +6336,17 @@ PresShell::HandleEvent(nsIView         *
     return NS_OK;
 
   NS_TIME_FUNCTION_MIN(1.0);
 
   nsIContent* capturingContent =
     NS_IS_MOUSE_EVENT(aEvent) ? GetCapturingContent() : nsnull;
 
   nsCOMPtr<nsIDocument> retargetEventDoc;
-  if (!sDontRetargetEvents) {
+  if (!aDontRetargetEvents) {
     // key and IME related events should not cross top level window boundary.
     // Basically, such input events should be fired only on focused widget.
     // However, some IMEs might need to clean up composition after focused
     // window is deactivated.  And also some tests on MozMill want to test key
     // handling on deactivated window because MozMill window can be activated
     // during tests.  So, there is no merit the events should be redirected to
     // active window.  So, the events should be handled on the last focused
     // content in the last focused DOM window in same top level window.
@@ -6381,19 +6375,17 @@ PresShell::HandleEvent(nsIView         *
 
       if (presShell != this) {
         nsCOMPtr<nsIViewObserver> viewObserver = do_QueryInterface(presShell);
         if (!viewObserver)
           return NS_ERROR_FAILURE;
 
         nsIView *view;
         presShell->GetViewManager()->GetRootView(view);
-        sDontRetargetEvents = PR_TRUE;
-        nsresult rv = viewObserver->HandleEvent(view, aEvent, aEventStatus);
-        sDontRetargetEvents = PR_FALSE;
+        nsresult rv = viewObserver->HandleEvent(view, aEvent, PR_TRUE, aEventStatus);
         return rv;
       }
     }
   }
 
   // Check for a theme change up front, since the frame type is irrelevant
   if (aEvent->message == NS_THEMECHANGED && mPresContext) {
     mPresContext->ThemeChanged();
--- a/view/public/nsIViewObserver.h
+++ b/view/public/nsIViewObserver.h
@@ -42,18 +42,18 @@
 #include "nsEvent.h"
 #include "nsColor.h"
 #include "nsRect.h"
 
 class nsIRenderingContext;
 class nsGUIEvent;
 
 #define NS_IVIEWOBSERVER_IID  \
-  { 0x4d467c73, 0xb6a9, 0x462a, \
-    { 0x90, 0x25, 0x80, 0xd9, 0x42, 0xbc, 0xcc, 0xb5 } }
+  { 0xc8ba5804, 0x2459, 0x4b62, \
+    { 0xa4, 0x15, 0x02, 0x84, 0x1a, 0xd7, 0x93, 0xa7 } }
 
 class nsIViewObserver : public nsISupports
 {
 public:
   
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IVIEWOBSERVER_IID)
 
   /* called when the observer needs to paint. This paints the entire
@@ -92,16 +92,17 @@ public:
    * @param aEventStatus - out parameter for event handling
    *                       status
    * @param aHandled - whether the correct frame was found to
    *                   handle the event
    * @return error status
    */
   NS_IMETHOD HandleEvent(nsIView*       aView,
                          nsGUIEvent*    aEvent,
+                         PRBool         aDontRetargetEvents,
                          nsEventStatus* aEventStatus) = 0;
 
   /* called when the view has been resized and the
    * content within the view needs to be reflowed.
    * @param aWidth - new width of view
    * @param aHeight - new height of view
    * @return error status
    */
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -975,17 +975,17 @@ NS_IMETHODIMP nsViewManager::DispatchEve
 
     case NS_SYSCOLORCHANGED:
       {
         // Hold a refcount to the observer. The continued existence of the observer will
         // delay deletion of this view hierarchy should the event want to cause its
         // destruction in, say, some JavaScript event handler.
         nsCOMPtr<nsIViewObserver> obs = GetViewObserver();
         if (obs) {
-          obs->HandleEvent(aView, aEvent, aStatus);
+          obs->HandleEvent(aView, aEvent, PR_FALSE, aStatus);
         }
       }
       break; 
 
     default:
       {
         if ((NS_IS_MOUSE_EVENT(aEvent) &&
              // Ignore mouse events that we synthesize.
@@ -1084,17 +1084,17 @@ nsEventStatus nsViewManager::HandleEvent
          event->message, event->point.x, event->point.y);
 #endif
   // Hold a refcount to the observer. The continued existence of the observer will
   // delay deletion of this view hierarchy should the event want to cause its
   // destruction in, say, some JavaScript event handler.
   nsCOMPtr<nsIViewObserver> obs = aView->GetViewManager()->GetViewObserver();
   nsEventStatus status = nsEventStatus_eIgnore;
   if (obs) {
-     obs->HandleEvent(aView, aEvent, &status);
+     obs->HandleEvent(aView, aEvent, PR_FALSE, &status);
   }
 
   return status;
 }
 
 // Recursively reparent widgets if necessary 
 
 void nsViewManager::ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget)