Bug 552982, Part 4: change nsXULPopupManager::GetVisiblePopups to also return noautohide panels, r=mats
authorNeil Deakin <neil@mozilla.com>
Tue, 27 Jul 2010 09:38:03 -0400
changeset 48255 de7562be22b601018523ef366be2d0e2093760ce
parent 48254 d8057f320d56b15669dc7ce5d4109e8c48cc09f0
child 48256 057b802ec2693a2a576c226cd9dd8e230cb41bc2
push idunknown
push userunknown
push dateunknown
reviewersmats
bugs552982
milestone2.0b3pre
Bug 552982, Part 4: change nsXULPopupManager::GetVisiblePopups to also return noautohide panels, r=mats
dom/base/nsDOMWindowUtils.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresShell.cpp
layout/xul/base/src/nsXULPopupManager.cpp
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1069,16 +1069,28 @@ nsDOMWindowUtils::SendQueryContentEvent(
                                         nsIQueryContentEventResult **aResult)
 {
   *aResult = nsnull;
 
   if (!IsUniversalXPConnectCapable()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
+  NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
+
+  nsIDocShell *docShell = mWindow->GetDocShell();
+  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
+
+  nsCOMPtr<nsIPresShell> presShell;
+  docShell->GetPresShell(getter_AddRefs(presShell));
+  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
+
+  nsPresContext* presContext = presShell->GetPresContext();
+  NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
+
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
 
   if (aType != NS_QUERY_SELECTED_TEXT &&
       aType != NS_QUERY_TEXT_CONTENT &&
@@ -1092,17 +1104,17 @@ nsDOMWindowUtils::SendQueryContentEvent(
   nsCOMPtr<nsIWidget> targetWidget = widget;
   nsIntPoint pt(aX, aY);
 
   if (aType == QUERY_CHARACTER_AT_POINT) {
     // Looking for the widget at the point.
     nsQueryContentEvent dummyEvent(PR_TRUE, NS_QUERY_CONTENT_STATE, widget);
     InitEvent(dummyEvent, &pt);
     nsIFrame* popupFrame =
-      nsLayoutUtils::GetPopupFrameForEventCoordinates(&dummyEvent);
+      nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
 
     nsIntRect widgetBounds;
     nsresult rv = widget->GetClientBounds(widgetBounds);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // There is no popup frame at the point and the point isn't in our widget,
     // we cannot process this request.
     NS_ENSURE_TRUE(popupFrame || widgetBounds.Contains(pt),
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -814,29 +814,31 @@ nsLayoutUtils::GetEventCoordinatesRelati
 
   /* Otherwise, all coordinate systems are translations of one another,
    * so we can just subtract out the different.
    */
   return widgetToView - aFrame->GetOffsetToCrossDoc(rootFrame);
 }
 
 nsIFrame*
-nsLayoutUtils::GetPopupFrameForEventCoordinates(const nsEvent* aEvent)
+nsLayoutUtils::GetPopupFrameForEventCoordinates(nsPresContext* aPresContext,
+                                                const nsEvent* aEvent)
 {
 #ifdef MOZ_XUL
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (!pm) {
     return nsnull;
   }
   nsTArray<nsIFrame*> popups = pm->GetVisiblePopups();
   PRUint32 i;
   // Search from top to bottom
   for (i = 0; i < popups.Length(); i++) {
     nsIFrame* popup = popups[i];
-    if (popup->GetOverflowRect().Contains(
+    if (popup->PresContext()->GetRootPresContext() == aPresContext &&
+        popup->GetOverflowRect().Contains(
           GetEventCoordinatesRelativeTo(aEvent, popup))) {
       return popup;
     }
   }
 #endif
   return nsnull;
 }
 
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -401,21 +401,23 @@ public:
    * for some reason the coordinates for the mouse are not known (e.g.,
    * the event is not a GUI event).
    */
   static nsPoint GetEventCoordinatesRelativeTo(const nsEvent* aEvent,
                                                nsIFrame* aFrame);
 
   /**
    * Get the popup frame of a given native mouse event.
+   * @param aPresContext only check popups within aPresContext or a descendant
    * @param aEvent  the event.
    * @return        Null, if there is no popup frame at the point, otherwise,
    *                returns top-most popup frame at the point.
    */
-  static nsIFrame* GetPopupFrameForEventCoordinates(const nsEvent* aEvent);
+  static nsIFrame* GetPopupFrameForEventCoordinates(nsPresContext* aPresContext,
+                                                    const nsEvent* aEvent);
 
 /**
    * Translate from widget coordinates to the view's coordinates
    * @param aPresContext the PresContext for the view
    * @param aWidget the widget
    * @param aPt the point relative to the widget
    * @param aView  view to which returned coordinates are relative
    * @return the point in the view's coordinates
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6279,17 +6279,17 @@ PresShell::HandleEvent(nsIView         *
     NS_ASSERTION(rootPresContext == mPresContext->GetRootPresContext(),
                  "How did we end up outside the connected prescontext/viewmanager hierarchy?"); 
     // If we aren't starting our event dispatch from the root frame of the root prescontext,
     // then someone must be capturing the mouse. In that case we don't want to search the popup
     // list.
     if (framePresContext == rootPresContext &&
         frame == FrameManager()->GetRootFrame()) {
       nsIFrame* popupFrame =
-        nsLayoutUtils::GetPopupFrameForEventCoordinates(aEvent);
+        nsLayoutUtils::GetPopupFrameForEventCoordinates(rootPresContext, aEvent);
       // If the popupFrame is an ancestor of the 'frame', the frame should
       // handle the event, otherwise, the popup should handle it.
       if (popupFrame &&
           !nsContentUtils::ContentIsCrossDocDescendantOf(
              framePresContext->GetPresShell()->GetDocument(),
              popupFrame->GetContent())) {
         frame = popupFrame;
       }
--- a/layout/xul/base/src/nsXULPopupManager.cpp
+++ b/layout/xul/base/src/nsXULPopupManager.cpp
@@ -1267,16 +1267,23 @@ nsXULPopupManager::GetVisiblePopups()
 
   nsMenuChainItem* item = mPopups;
   while (item) {
     if (item->Frame()->PopupState() == ePopupOpenAndVisible)
       popups.AppendElement(static_cast<nsIFrame*>(item->Frame()));
     item = item->GetParent();
   }
 
+  item = mNoHidePanels;
+  while (item) {
+    if (item->Frame()->PopupState() == ePopupOpenAndVisible)
+      popups.AppendElement(static_cast<nsIFrame*>(item->Frame()));
+    item = item->GetParent();
+  }
+
   return popups;
 }
 
 PRBool
 nsXULPopupManager::MayShowPopup(nsMenuPopupFrame* aPopup)
 {
   // if a popup's IsOpen method returns true, then the popup must always be in
   // the popup chain scanned in IsPopupOpen.