Bug 465993. When opening a dependent window with an invisible non-chrome parent, throw. r=jst,ere, sr=jst
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 13 Jan 2009 14:32:30 -0500
changeset 23621 8dae102faa15b6ae4182428c012156dbcceeeb50
parent 23620 f0a8064d5a8e08bb9d80acf3608165fb47e5fb28
child 23622 c91a6563377db5c6bd2702398967f9dedf78a194
push id4642
push userbzbarsky@mozilla.com
push dateTue, 13 Jan 2009 19:32:56 +0000
treeherdermozilla-central@e40649461b57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst, ere, jst
bugs465993
milestone1.9.2a1pre
Bug 465993. When opening a dependent window with an invisible non-chrome parent, throw. r=jst,ere, sr=jst
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -641,16 +641,34 @@ nsWindowWatcher::OpenWindowJSInternal(ns
 
     if (weAreModal) {
       windowIsModal = PR_TRUE;
       // in case we added this because weAreModal
       chromeFlags |= nsIWebBrowserChrome::CHROME_MODAL |
         nsIWebBrowserChrome::CHROME_DEPENDENT;
     }
 
+    // Make sure to not create dependent windows if our parent is invisible and
+    // isn't a chrome window.  Otherwise we can end up in a bizarre situation
+    // where we can't shut down because an invisible window is open.  If
+    // someone tries to do this, throw.
+    if (!chromeParent &&
+        (chromeFlags & nsIWebBrowserChrome::CHROME_DEPENDENT)) {
+      PRBool parentVisible = PR_TRUE;
+      nsCOMPtr<nsIBaseWindow> parentWindow(do_GetInterface(parentTreeOwner));
+      nsCOMPtr<nsIWidget> parentWidget;
+      if (parentWindow)
+        parentWindow->GetMainWidget(getter_AddRefs(parentWidget));
+      if (parentWidget)
+        parentWidget->IsVisible(parentVisible);
+      if (!parentVisible) {
+        return NS_ERROR_NOT_AVAILABLE;
+      }
+    }
+
     NS_ASSERTION(mWindowCreator,
                  "attempted to open a new window with no WindowCreator");
     rv = NS_ERROR_FAILURE;
     if (mWindowCreator) {
       nsCOMPtr<nsIWebBrowserChrome> newChrome;
 
       /* If the window creator is an nsIWindowCreator2, we can give it
          some hints. The only hint at this time is whether the opening window
@@ -672,31 +690,21 @@ nsWindowWatcher::OpenWindowJSInternal(ns
         // chrome is always allowed, so clear the flag if the opener is chrome
         if (popupConditions) {
           popupConditions = !isCallerChrome;
         }
 
         if (popupConditions)
           contextFlags |= nsIWindowCreator2::PARENT_IS_LOADING_OR_RUNNING_TIMEOUT;
 
-        PRBool parentVisible = PR_TRUE;
-        if (parentChrome)
-        {
-          nsCOMPtr<nsIBaseWindow> parentWindow(do_GetInterface(parentTreeOwner));
-          nsCOMPtr<nsIWidget> parentWidget;
-          if (parentWindow)
-            parentWindow->GetMainWidget(getter_AddRefs(parentWidget));
-          if (parentWidget)
-            parentWidget->IsVisible(parentVisible);            
-        }
         PRBool cancel = PR_FALSE;
-        rv = windowCreator2->CreateChromeWindow2(
-               parentVisible ? parentChrome.get() : nsnull,
-               chromeFlags, contextFlags, uriToLoad, &cancel,
-               getter_AddRefs(newChrome));
+        rv = windowCreator2->CreateChromeWindow2(parentChrome, chromeFlags,
+                                                 contextFlags, uriToLoad,
+                                                 &cancel,
+                                                 getter_AddRefs(newChrome));
         if (NS_SUCCEEDED(rv) && cancel) {
           newChrome = 0; // just in case
           rv = NS_ERROR_ABORT;
         }
       }
       else
         rv = mWindowCreator->CreateChromeWindow(parentChrome, chromeFlags,
                                                 getter_AddRefs(newChrome));
@@ -939,16 +947,17 @@ nsWindowWatcher::OpenWindowJSInternal(ns
         NS_ConvertUTF16toUTF8(piStorage->Domain()),
         storage);
     }
   }
 
   if (isNewToplevelWindow)
     SizeOpenedDocShellItem(newDocShellItem, aParent, sizeSpec);
 
+  // XXXbz isn't windowIsModal always true when windowIsModalContentDialog?
   if (windowIsModal || windowIsModalContentDialog) {
     nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
     newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
     nsCOMPtr<nsIWebBrowserChrome> newChrome(do_GetInterface(newTreeOwner));
 
     // Throw an exception here if no web browser chrome is available,
     // we need that to show a modal window.
     NS_ENSURE_TRUE(newChrome, NS_ERROR_NOT_AVAILABLE);