Bug 528440 - Should skip windows that are closed but not yet destroyed when using nsIWindowMediator. r=zeniko
authorDão Gottwald <dao@mozilla.com>
Fri, 13 Nov 2009 18:06:44 +0100
changeset 34827 e39e777f86bb75af028b386ee588160ff9a1a58e
parent 34826 fe353a1044d0c1de4b004132373089b931108ebe
child 34828 3dcf63a4435c419c9c397b4a123cecb2915b1973
push idunknown
push userunknown
push dateunknown
reviewerszeniko
bugs528440
milestone1.9.3a1pre
Bug 528440 - Should skip windows that are closed but not yet destroyed when using nsIWindowMediator. r=zeniko
browser/components/sessionstore/src/nsSessionStore.js
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -105,16 +105,20 @@ eg: browser.docShell["allow" + aCapabili
 XXX keep these in sync with all the attributes starting
     with "allow" in /docshell/base/nsIDocShell.idl
 */
 const CAPABILITIES = [
   "Subframes", "Plugins", "Javascript", "MetaRedirects", "Images",
   "DNSPrefetch", "Auth"
 ];
 
+#ifndef XP_WIN
+#define BROKEN_WM_Z_ORDER
+#endif
+
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 function debug(aMsg) {
   aMsg = ("SessionStore: " + aMsg).replace(/\S{80}/g, "$&\n");
   Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
                                      .logStringMessage(aMsg);
 }
 
@@ -2593,30 +2597,55 @@ SessionStoreService.prototype = {
    */
   _forEachBrowserWindow: function sss_forEachBrowserWindow(aFunc) {
     var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
                          getService(Ci.nsIWindowMediator);
     var windowsEnum = windowMediator.getEnumerator("navigator:browser");
     
     while (windowsEnum.hasMoreElements()) {
       var window = windowsEnum.getNext();
-      if (window.__SSi) {
+      if (window.__SSi && !window.closed) {
         aFunc.call(this, window);
       }
     }
   },
 
   /**
    * Returns most recent window
    * @returns Window reference
    */
   _getMostRecentBrowserWindow: function sss_getMostRecentBrowserWindow() {
-    var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
-                         getService(Ci.nsIWindowMediator);
-    return windowMediator.getMostRecentWindow("navigator:browser");
+    var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+             getService(Ci.nsIWindowMediator);
+
+    var win = wm.getMostRecentWindow("navigator:browser");
+    if (!win)
+      return null;
+    if (!win.closed)
+      return win;
+
+#ifdef BROKEN_WM_Z_ORDER
+    win = null;
+    var windowsEnum = wm.getEnumerator("navigator:browser");
+    // this is oldest to newest, so this gets a bit ugly
+    while (windowsEnum.hasMoreElements()) {
+      let nextWin = windowsEnum.getNext();
+      if (!nextWin.closed)
+        win = nextWin;
+    }
+    return win;
+#else
+    var windowsEnum = wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
+    while (windowsEnum.hasMoreElements()) {
+      win = windowsEnum.getNext();
+      if (!win.closed)
+        return win;
+    }
+    return null;
+#endif
   },
 
   /**
    * open a new browser window for a given session state
    * called when restoring a multi-window session
    * @param aState
    *        Object containing session data
    */