LCOV - code coverage report
Current view: directory - xpfe/appshell/src - nsXULWindow.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 1011 0 0.0 %
Date: 2012-06-02 Functions: 80 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* vim:set ts=2 sw=2 sts=2 ci et: */
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is the Mozilla browser.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Netscape Communications, Inc.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 1999
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Travis Bogard <travis@netscape.com>
      25                 :  *   Dan Rosen <dr@netscape.com>
      26                 :  *   Ben Goodger <ben@netscape.com>
      27                 :  *
      28                 :  * Alternatively, the contents of this file may be used under the terms of
      29                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      30                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      31                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      32                 :  * of those above. If you wish to allow use of your version of this file only
      33                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      34                 :  * use your version of this file under the terms of the MPL, indicate your
      35                 :  * decision by deleting the provisions above and replace them with the notice
      36                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      37                 :  * the provisions above, a recipient may use your version of this file under
      38                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      39                 :  *
      40                 :  * ***** END LICENSE BLOCK ***** */
      41                 : 
      42                 : // Local includes
      43                 : #include "nsXULWindow.h"
      44                 : 
      45                 : // Helper classes
      46                 : #include "nsString.h"
      47                 : #include "nsWidgetsCID.h"
      48                 : #include "prprf.h"
      49                 : #include "nsCRT.h"
      50                 : #include "nsThreadUtils.h"
      51                 : #include "nsNetCID.h"
      52                 : 
      53                 : //Interfaces needed to be included
      54                 : #include "nsIAppShell.h"
      55                 : #include "nsIAppShellService.h"
      56                 : #include "nsIServiceManager.h"
      57                 : #include "nsIContentViewer.h"
      58                 : #include "nsIDocument.h"
      59                 : #include "nsIDOMBarProp.h"
      60                 : #include "nsIDOMDocument.h"
      61                 : #include "nsIDOMXULDocument.h"
      62                 : #include "nsIDOMElement.h"
      63                 : #include "nsIPrivateDOMEvent.h"
      64                 : #include "nsIDOMEventTarget.h"
      65                 : #include "nsIDOMXULElement.h"
      66                 : #include "nsPIDOMWindow.h"
      67                 : #include "nsIDOMScreen.h"
      68                 : #include "nsIEmbeddingSiteWindow.h"
      69                 : #include "nsIEmbeddingSiteWindow2.h"
      70                 : #include "nsIInterfaceRequestor.h"
      71                 : #include "nsIInterfaceRequestorUtils.h"
      72                 : #include "nsIIOService.h"
      73                 : #include "nsIJSContextStack.h"
      74                 : #include "nsIMarkupDocumentViewer.h"
      75                 : #include "nsIObserverService.h"
      76                 : #include "nsIWindowMediator.h"
      77                 : #include "nsIScreenManager.h"
      78                 : #include "nsIScreen.h"
      79                 : #include "nsIScrollable.h"
      80                 : #include "nsIScriptSecurityManager.h"
      81                 : #include "nsIWindowWatcher.h"
      82                 : #include "nsIURI.h"
      83                 : #include "nsIDOMCSSStyleDeclaration.h"
      84                 : #include "nsAppShellCID.h"
      85                 : #include "nsReadableUtils.h"
      86                 : #include "nsStyleConsts.h"
      87                 : #include "nsPresContext.h"
      88                 : #include "nsContentUtils.h"
      89                 : #include "nsWebShellWindow.h" // get rid of this one, too...
      90                 : 
      91                 : #include "prenv.h"
      92                 : #include "mozilla/Preferences.h"
      93                 : 
      94                 : using namespace mozilla;
      95                 : 
      96                 : #define SIZEMODE_NORMAL     NS_LITERAL_STRING("normal")
      97                 : #define SIZEMODE_MAXIMIZED  NS_LITERAL_STRING("maximized")
      98                 : #define SIZEMODE_MINIMIZED  NS_LITERAL_STRING("minimized")
      99                 : #define SIZEMODE_FULLSCREEN NS_LITERAL_STRING("fullscreen")
     100                 : 
     101                 : #define WINDOWTYPE_ATTRIBUTE NS_LITERAL_STRING("windowtype")
     102                 : 
     103                 : #define PERSIST_ATTRIBUTE  NS_LITERAL_STRING("persist")
     104                 : #define SCREENX_ATTRIBUTE  NS_LITERAL_STRING("screenX")
     105                 : #define SCREENY_ATTRIBUTE  NS_LITERAL_STRING("screenY")
     106                 : #define WIDTH_ATTRIBUTE    NS_LITERAL_STRING("width")
     107                 : #define HEIGHT_ATTRIBUTE   NS_LITERAL_STRING("height")
     108                 : #define MODE_ATTRIBUTE     NS_LITERAL_STRING("sizemode")
     109                 : #define ZLEVEL_ATTRIBUTE   NS_LITERAL_STRING("zlevel")
     110                 : 
     111                 : // Unit conversion helpers
     112                 : static PRInt32
     113               0 : CSSToDevPixels(PRInt32 aPixels, PRInt32 aAppPerDev)
     114                 : {
     115                 :   return NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aPixels),
     116               0 :                                aAppPerDev);
     117                 : }
     118                 : 
     119                 : static PRInt32
     120               0 : DevToCSSPixels(PRInt32 aPixels, PRInt32 aAppPerDev)
     121                 : {
     122                 :   return nsPresContext::AppUnitsToIntCSSPixels(
     123               0 :     NSIntPixelsToAppUnits(aPixels, aAppPerDev));
     124                 : }
     125                 : 
     126                 : 
     127                 : //*****************************************************************************
     128                 : //***    nsXULWindow: Object Management
     129                 : //*****************************************************************************
     130                 : 
     131               0 : nsXULWindow::nsXULWindow(PRUint32 aChromeFlags)
     132                 :   : mChromeTreeOwner(nsnull), 
     133                 :     mContentTreeOwner(nsnull),
     134                 :     mPrimaryContentTreeOwner(nsnull),
     135                 :     mModalStatus(NS_OK),
     136                 :     mContinueModalLoop(false),
     137                 :     mDebuting(false),
     138                 :     mChromeLoaded(false), 
     139                 :     mShowAfterLoad(false),
     140                 :     mIntrinsicallySized(false),
     141                 :     mCenterAfterLoad(false),
     142                 :     mIsHiddenWindow(false),
     143                 :     mLockedUntilChromeLoad(false),
     144                 :     mIgnoreXULSize(false),
     145                 :     mIgnoreXULPosition(false),
     146                 :     mChromeFlagsFrozen(false),
     147                 :     mIgnoreXULSizeMode(false),
     148                 :     mContextFlags(0),
     149                 :     mPersistentAttributesDirty(0),
     150                 :     mPersistentAttributesMask(0),
     151                 :     mChromeFlags(aChromeFlags),
     152                 :     // best guess till we have a widget
     153               0 :     mAppPerDev(nsPresContext::AppUnitsPerCSSPixel())
     154                 : {
     155               0 : }
     156                 : 
     157               0 : nsXULWindow::~nsXULWindow()
     158                 : {
     159               0 :   Destroy();
     160               0 : }
     161                 : 
     162                 : //*****************************************************************************
     163                 : // nsXULWindow::nsISupports
     164                 : //*****************************************************************************
     165                 : 
     166               0 : NS_IMPL_THREADSAFE_ADDREF(nsXULWindow)
     167               0 : NS_IMPL_THREADSAFE_RELEASE(nsXULWindow)
     168                 : 
     169               0 : NS_INTERFACE_MAP_BEGIN(nsXULWindow)
     170               0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULWindow)
     171               0 :   NS_INTERFACE_MAP_ENTRY(nsIXULWindow)
     172               0 :   NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
     173               0 :   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
     174               0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     175               0 :   if (aIID.Equals(NS_GET_IID(nsXULWindow)))
     176               0 :     foundInterface = reinterpret_cast<nsISupports*>(this);
     177                 :   else
     178               0 : NS_INTERFACE_MAP_END
     179                 : 
     180                 : //*****************************************************************************
     181                 : // nsXULWindow::nsIIntefaceRequestor
     182                 : //*****************************************************************************   
     183                 : 
     184               0 : NS_IMETHODIMP nsXULWindow::GetInterface(const nsIID& aIID, void** aSink)
     185                 : {
     186                 :   nsresult rv;
     187                 : 
     188               0 :   NS_ENSURE_ARG_POINTER(aSink);
     189                 : 
     190               0 :   if (aIID.Equals(NS_GET_IID(nsIPrompt))) {
     191               0 :     rv = EnsurePrompter();
     192               0 :     if (NS_FAILED(rv)) return rv;
     193               0 :     return mPrompter->QueryInterface(aIID, aSink);
     194                 :   }   
     195               0 :   if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
     196               0 :     rv = EnsureAuthPrompter();
     197               0 :     if (NS_FAILED(rv)) return rv;
     198               0 :     return mAuthPrompter->QueryInterface(aIID, aSink);
     199                 :   }
     200               0 :   if (aIID.Equals(NS_GET_IID(nsIDOMWindow))) {
     201               0 :     return GetWindowDOMWindow(reinterpret_cast<nsIDOMWindow**>(aSink));
     202                 :   }
     203               0 :   if (aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) {
     204               0 :     nsIDOMWindow* domWindow = nsnull;
     205               0 :     rv = GetWindowDOMWindow(&domWindow);
     206                 :     nsIDOMWindowInternal* domWindowInternal =
     207               0 :       static_cast<nsIDOMWindowInternal*>(domWindow);
     208               0 :     *aSink = domWindowInternal;
     209               0 :     return rv;
     210                 :   }
     211               0 :   if (aIID.Equals(NS_GET_IID(nsIWebBrowserChrome)) && 
     212               0 :     NS_SUCCEEDED(EnsureContentTreeOwner()) &&
     213               0 :     NS_SUCCEEDED(mContentTreeOwner->QueryInterface(aIID, aSink)))
     214               0 :     return NS_OK;
     215                 : 
     216               0 :   if (aIID.Equals(NS_GET_IID(nsIEmbeddingSiteWindow)) && 
     217               0 :     NS_SUCCEEDED(EnsureContentTreeOwner()) &&
     218               0 :     NS_SUCCEEDED(mContentTreeOwner->QueryInterface(aIID, aSink)))
     219               0 :     return NS_OK;
     220               0 :   if (aIID.Equals(NS_GET_IID(nsIEmbeddingSiteWindow2)) && 
     221               0 :     NS_SUCCEEDED(EnsureContentTreeOwner()) &&
     222               0 :     NS_SUCCEEDED(mContentTreeOwner->QueryInterface(aIID, aSink)))
     223               0 :     return NS_OK;
     224                 : 
     225               0 :   return QueryInterface(aIID, aSink);
     226                 : }
     227                 : 
     228                 : //*****************************************************************************
     229                 : // nsXULWindow::nsIXULWindow
     230                 : //*****************************************************************************   
     231                 : 
     232               0 : NS_IMETHODIMP nsXULWindow::GetDocShell(nsIDocShell** aDocShell)
     233                 : {
     234               0 :   NS_ENSURE_ARG_POINTER(aDocShell);
     235                 : 
     236               0 :   *aDocShell = mDocShell;
     237               0 :   NS_IF_ADDREF(*aDocShell);
     238               0 :   return NS_OK;
     239                 : }
     240                 : 
     241               0 : NS_IMETHODIMP nsXULWindow::GetZLevel(PRUint32 *outLevel)
     242                 : {
     243               0 :   nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
     244               0 :   if (mediator)
     245               0 :     mediator->GetZLevel(this, outLevel);
     246                 :   else
     247               0 :     *outLevel = normalZ;
     248               0 :   return NS_OK;
     249                 : }
     250                 : 
     251               0 : NS_IMETHODIMP nsXULWindow::SetZLevel(PRUint32 aLevel)
     252                 : {
     253               0 :   nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
     254               0 :   if (!mediator)
     255               0 :     return NS_ERROR_FAILURE;
     256                 : 
     257                 :   PRUint32 zLevel;
     258               0 :   mediator->GetZLevel(this, &zLevel);
     259               0 :   if (zLevel == aLevel)
     260               0 :     return NS_OK;
     261                 : 
     262                 :   /* refuse to raise a maximized window above the normal browser level,
     263                 :      for fear it could hide newly opened browser windows */
     264               0 :   if (aLevel > nsIXULWindow::normalZ) {
     265                 :     PRInt32 sizeMode;
     266               0 :     if (mWindow) {
     267               0 :       mWindow->GetSizeMode(&sizeMode);
     268               0 :       if (sizeMode == nsSizeMode_Maximized || sizeMode == nsSizeMode_Fullscreen)
     269               0 :         return NS_ERROR_FAILURE;
     270                 :     }
     271                 :   }
     272                 : 
     273                 :   // do it
     274               0 :   mediator->SetZLevel(this, aLevel);
     275               0 :   PersistentAttributesDirty(PAD_MISC);
     276               0 :   SavePersistentAttributes();
     277                 : 
     278               0 :   nsCOMPtr<nsIContentViewer> cv;
     279               0 :   mDocShell->GetContentViewer(getter_AddRefs(cv));
     280               0 :   if (cv) {
     281               0 :     nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(cv->GetDocument());
     282               0 :     if (domDoc) {
     283               0 :       nsCOMPtr<nsIDOMEvent> event;
     284               0 :       domDoc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
     285               0 :       if (event) {
     286               0 :         event->InitEvent(NS_LITERAL_STRING("windowZLevel"), true, false);
     287                 : 
     288               0 :         nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
     289               0 :         privateEvent->SetTrusted(true);
     290                 : 
     291               0 :         nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(domDoc);
     292               0 :         if (targ) {
     293                 :           bool defaultActionEnabled;
     294               0 :           targ->DispatchEvent(event, &defaultActionEnabled);
     295                 :         }
     296                 :       }
     297                 :     }
     298                 :   }
     299               0 :   return NS_OK;
     300                 : }
     301                 : 
     302               0 : NS_IMETHODIMP nsXULWindow::GetContextFlags(PRUint32 *aContextFlags)
     303                 : {
     304               0 :   NS_ENSURE_ARG_POINTER(aContextFlags);
     305               0 :   *aContextFlags = mContextFlags;
     306               0 :   return NS_OK;
     307                 : }
     308                 : 
     309               0 : NS_IMETHODIMP nsXULWindow::SetContextFlags(PRUint32 aContextFlags)
     310                 : {
     311               0 :   mContextFlags = aContextFlags;
     312               0 :   return NS_OK;
     313                 : }
     314                 : 
     315               0 : NS_IMETHODIMP nsXULWindow::GetChromeFlags(PRUint32 *aChromeFlags)
     316                 : {
     317               0 :   NS_ENSURE_ARG_POINTER(aChromeFlags);
     318               0 :   *aChromeFlags = mChromeFlags;
     319                 :   /* mChromeFlags is kept up to date, except for scrollbar visibility.
     320                 :      That can be changed directly by the content DOM window, which
     321                 :      doesn't know to update the chrome window. So that we must check
     322                 :      separately. */
     323                 : 
     324                 :   // however, it's pointless to ask if the window isn't set up yet
     325               0 :   if (!mChromeLoaded)
     326               0 :     return NS_OK;
     327                 : 
     328               0 :   if (GetContentScrollbarVisibility())
     329               0 :     *aChromeFlags |= nsIWebBrowserChrome::CHROME_SCROLLBARS;
     330                 :   else
     331               0 :     *aChromeFlags &= ~nsIWebBrowserChrome::CHROME_SCROLLBARS;
     332                 : 
     333               0 :   return NS_OK;
     334                 : }
     335                 : 
     336               0 : NS_IMETHODIMP nsXULWindow::SetChromeFlags(PRUint32 aChromeFlags)
     337                 : {
     338               0 :   NS_ASSERTION(!mChromeFlagsFrozen,
     339                 :                "SetChromeFlags() after AssumeChromeFlagsAreFrozen()!");
     340                 : 
     341               0 :   mChromeFlags = aChromeFlags;
     342               0 :   if (mChromeLoaded)
     343               0 :     NS_ENSURE_SUCCESS(ApplyChromeFlags(), NS_ERROR_FAILURE);
     344               0 :   return NS_OK;
     345                 : }
     346                 : 
     347               0 : NS_IMETHODIMP nsXULWindow::AssumeChromeFlagsAreFrozen()
     348                 : {
     349               0 :   mChromeFlagsFrozen = true;
     350               0 :   return NS_OK;
     351                 : }
     352                 : 
     353               0 : NS_IMETHODIMP nsXULWindow::SetIntrinsicallySized(bool aIntrinsicallySized)
     354                 : {
     355               0 :   mIntrinsicallySized = aIntrinsicallySized;
     356               0 :   return NS_OK;
     357                 : }
     358                 : 
     359               0 : NS_IMETHODIMP nsXULWindow::GetIntrinsicallySized(bool* aIntrinsicallySized)
     360                 : {
     361               0 :   NS_ENSURE_ARG_POINTER(aIntrinsicallySized);
     362                 : 
     363               0 :   *aIntrinsicallySized = mIntrinsicallySized;
     364               0 :   return NS_OK;
     365                 : }
     366                 : 
     367               0 : NS_IMETHODIMP nsXULWindow::GetPrimaryContentShell(nsIDocShellTreeItem** 
     368                 :    aDocShellTreeItem)
     369                 : {
     370               0 :   NS_ENSURE_ARG_POINTER(aDocShellTreeItem);
     371               0 :   NS_IF_ADDREF(*aDocShellTreeItem = mPrimaryContentShell);
     372               0 :   return NS_OK;
     373                 : }
     374                 : 
     375               0 : NS_IMETHODIMP nsXULWindow::GetContentShellById(const PRUnichar* aID, 
     376                 :    nsIDocShellTreeItem** aDocShellTreeItem)
     377                 : {
     378               0 :   NS_ENSURE_ARG_POINTER(aDocShellTreeItem);
     379               0 :   *aDocShellTreeItem = nsnull;
     380                 : 
     381               0 :   PRUint32 count = mContentShells.Length();
     382               0 :   for (PRUint32 i = 0; i < count; i++) {
     383               0 :     nsContentShellInfo* shellInfo = mContentShells.ElementAt(i);
     384               0 :     if (shellInfo->id.Equals(aID)) {
     385               0 :       *aDocShellTreeItem = nsnull;
     386               0 :       if (shellInfo->child)
     387               0 :         CallQueryReferent(shellInfo->child.get(), aDocShellTreeItem);
     388               0 :       return NS_OK;
     389                 :     }
     390                 :   }
     391               0 :   return NS_ERROR_FAILURE;
     392                 : }
     393                 : 
     394               0 : NS_IMETHODIMP nsXULWindow::AddChildWindow(nsIXULWindow *aChild)
     395                 : {
     396                 :   // we're not really keeping track of this right now
     397               0 :   return NS_OK;
     398                 : }
     399                 : 
     400               0 : NS_IMETHODIMP nsXULWindow::RemoveChildWindow(nsIXULWindow *aChild)
     401                 : {
     402                 :   // we're not really keeping track of this right now
     403               0 :   return NS_OK;
     404                 : }
     405                 : 
     406               0 : NS_IMETHODIMP nsXULWindow::ShowModal()
     407                 : {
     408                 :   // Store locally so it doesn't die on us
     409               0 :   nsCOMPtr<nsIWidget> window = mWindow;
     410               0 :   nsCOMPtr<nsIXULWindow> tempRef = this;  
     411                 : 
     412               0 :   window->SetModal(true);
     413               0 :   mContinueModalLoop = true;
     414               0 :   EnableParent(false);
     415                 : 
     416               0 :   nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1"));
     417               0 :   if (stack && NS_SUCCEEDED(stack->Push(nsnull))) {
     418               0 :     nsIThread *thread = NS_GetCurrentThread();
     419               0 :     while (mContinueModalLoop) {
     420               0 :       if (!NS_ProcessNextEvent(thread))
     421               0 :         break;
     422                 :     }
     423                 :     JSContext* cx;
     424               0 :     stack->Pop(&cx);
     425               0 :     NS_ASSERTION(cx == nsnull, "JSContextStack mismatch");
     426                 :   }
     427                 : 
     428               0 :   mContinueModalLoop = false;
     429               0 :   window->SetModal(false);
     430                 :   /*   Note there's no EnableParent(true) here to match the false one
     431                 :      above. That's done in ExitModalLoop. It's important that the parent
     432                 :      be re-enabled before this window is made invisible; to do otherwise
     433                 :      causes bizarre z-ordering problems. At this point, the window is
     434                 :      already invisible.
     435                 :        No known current implementation of Enable would have a problem with
     436                 :      re-enabling the parent twice, so we could do it again here without
     437                 :      breaking any current implementation. But that's unnecessary if the
     438                 :      modal loop is always exited using ExitModalLoop (the other way would be
     439                 :      to change the protected member variable directly.)
     440                 :   */
     441                 : 
     442               0 :   return mModalStatus;
     443                 : }
     444                 : 
     445                 : //*****************************************************************************
     446                 : // nsXULWindow::nsIBaseWindow
     447                 : //*****************************************************************************   
     448                 : 
     449               0 : NS_IMETHODIMP nsXULWindow::InitWindow(nativeWindow aParentNativeWindow,
     450                 :    nsIWidget* parentWidget, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy)   
     451                 : {
     452                 :   //XXX First Check In
     453               0 :   NS_ASSERTION(false, "Not Yet Implemented");
     454               0 :   return NS_OK;
     455                 : }
     456                 : 
     457               0 : NS_IMETHODIMP nsXULWindow::Create()
     458                 : {
     459                 :   //XXX First Check In
     460               0 :   NS_ASSERTION(false, "Not Yet Implemented");
     461               0 :   return NS_OK;
     462                 : }
     463                 : 
     464               0 : NS_IMETHODIMP nsXULWindow::Destroy()
     465                 : {
     466               0 :   if (!mWindow)
     467               0 :      return NS_OK;
     468                 : 
     469               0 :   nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
     470               0 :   NS_ASSERTION(appShell, "Couldn't get appShell... xpcom shutdown?");
     471               0 :   if (appShell)
     472               0 :     appShell->UnregisterTopLevelWindow(static_cast<nsIXULWindow*>(this));
     473                 : 
     474               0 :   nsCOMPtr<nsIXULWindow> parentWindow(do_QueryReferent(mParentWindow));
     475               0 :   if (parentWindow)
     476               0 :     parentWindow->RemoveChildWindow(this);
     477                 : 
     478                 :   // let's make sure the window doesn't get deleted out from under us
     479                 :   // while we are trying to close....this can happen if the docshell
     480                 :   // we close ends up being the last owning reference to this xulwindow
     481                 : 
     482                 :   // XXXTAB This shouldn't be an issue anymore because the ownership model
     483                 :   // only goes in one direction.  When webshell container is fully removed
     484                 :   // try removing this...
     485                 : 
     486               0 :   nsCOMPtr<nsIXULWindow> placeHolder = this;
     487                 : 
     488                 :   // Remove modality (if any) and hide while destroying. More than
     489                 :   // a convenience, the hide prevents user interaction with the partially
     490                 :   // destroyed window. This is especially necessary when the eldest window
     491                 :   // in a stack of modal windows is destroyed first. It happens.
     492               0 :   ExitModalLoop(NS_OK);
     493               0 :   if (mWindow)
     494               0 :     mWindow->Show(false);
     495                 : 
     496                 : #if defined(XP_WIN) || defined(XP_OS2)
     497                 :   // We need to explicitly set the focus on Windows, but 
     498                 :   // only if the parent is visible.
     499                 :   nsCOMPtr<nsIBaseWindow> parent(do_QueryReferent(mParentWindow));
     500                 :   if (parent) {
     501                 :     bool parentVisible = true;
     502                 :     nsCOMPtr<nsIWidget> parentWidget;
     503                 :     parent->GetMainWidget(getter_AddRefs(parentWidget));
     504                 :     if (parentWidget)
     505                 :       parentWidget->IsVisible(parentVisible);
     506                 :     if (parentVisible) {
     507                 :       nsCOMPtr<nsIBaseWindow> baseHiddenWindow;
     508                 :       if (appShell) {
     509                 :         nsCOMPtr<nsIXULWindow> hiddenWindow;
     510                 :         appShell->GetHiddenWindow(getter_AddRefs(hiddenWindow));
     511                 :         if (hiddenWindow)
     512                 :           baseHiddenWindow = do_GetInterface(hiddenWindow);
     513                 :       }
     514                 :       // somebody screwed up somewhere. hiddenwindow shouldn't be anybody's
     515                 :       // parent. still, when it happens, skip activating it.
     516                 :       if (baseHiddenWindow != parent) {
     517                 :         nsCOMPtr<nsIWidget> parentWidget;
     518                 :         parent->GetMainWidget(getter_AddRefs(parentWidget));
     519                 :         if (parentWidget)
     520                 :           parentWidget->PlaceBehind(eZPlacementTop, 0, true);
     521                 :       }
     522                 :     }
     523                 :   }
     524                 : #endif
     525                 :    
     526               0 :   mDOMWindow = nsnull;
     527               0 :   if (mDocShell) {
     528               0 :     nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(mDocShell));
     529               0 :     shellAsWin->Destroy();
     530               0 :     mDocShell = nsnull; // this can cause reentrancy of this function
     531                 :   }
     532                 : 
     533                 :   // Remove our ref on the content shells
     534               0 :   PRUint32 count = mContentShells.Length();
     535               0 :   for (PRUint32 i = 0; i < count; i++) {
     536               0 :     nsContentShellInfo* shellInfo = mContentShells.ElementAt(i);
     537               0 :     delete shellInfo;
     538                 :   }
     539               0 :   mContentShells.Clear();
     540               0 :   mPrimaryContentShell = nsnull;
     541                 : 
     542               0 :   if (mContentTreeOwner) {
     543               0 :     mContentTreeOwner->XULWindow(nsnull);
     544               0 :     NS_RELEASE(mContentTreeOwner);
     545                 :   }
     546               0 :   if (mPrimaryContentTreeOwner) {
     547               0 :     mPrimaryContentTreeOwner->XULWindow(nsnull);
     548               0 :     NS_RELEASE(mPrimaryContentTreeOwner);
     549                 :   }
     550               0 :   if (mChromeTreeOwner) {
     551               0 :     mChromeTreeOwner->XULWindow(nsnull);
     552               0 :     NS_RELEASE(mChromeTreeOwner);
     553                 :   }
     554               0 :   if (mWindow) {
     555               0 :     mWindow->SetClientData(0); // nsWebShellWindow hackery
     556               0 :     mWindow->Destroy();
     557               0 :     mWindow = nsnull;
     558                 :   }
     559                 : 
     560               0 :   if (!mIsHiddenWindow) {
     561                 :     /* Inform appstartup we've destroyed this window and it could
     562                 :        quit now if it wanted. This must happen at least after mDocShell
     563                 :        is destroyed, because onunload handlers fire then, and those being
     564                 :        script, anything could happen. A new window could open, even.
     565                 :        See bug 130719. */
     566                 :     nsCOMPtr<nsIObserverService> obssvc =
     567               0 :         do_GetService("@mozilla.org/observer-service;1");
     568               0 :     NS_ASSERTION(obssvc, "Couldn't get observer service?");
     569                 : 
     570               0 :     if (obssvc)
     571               0 :       obssvc->NotifyObservers(nsnull, "xul-window-destroyed", nsnull);
     572                 :   }
     573                 : 
     574               0 :   return NS_OK;
     575                 : }
     576                 : 
     577               0 : NS_IMETHODIMP nsXULWindow::SetPosition(PRInt32 aX, PRInt32 aY)
     578                 : {
     579                 :   // Don't reset the window's size mode here - platforms that don't want to move
     580                 :   // maximized windows should reset it in their respective Move implementation.
     581               0 :   NS_ENSURE_SUCCESS(mWindow->Move(aX, aY), NS_ERROR_FAILURE);
     582               0 :   if (!mChromeLoaded) {
     583                 :     // If we're called before the chrome is loaded someone obviously wants this
     584                 :     // window at this position. We don't persist this one-time position.
     585               0 :     mIgnoreXULPosition = true;
     586               0 :     return NS_OK;
     587                 :   }
     588               0 :   PersistentAttributesDirty(PAD_POSITION);
     589               0 :   SavePersistentAttributes();
     590               0 :   return NS_OK;
     591                 : }
     592                 : 
     593               0 : NS_IMETHODIMP nsXULWindow::GetPosition(PRInt32* aX, PRInt32* aY)
     594                 : {
     595               0 :   return GetPositionAndSize(aX, aY, nsnull, nsnull);
     596                 : }
     597                 : 
     598               0 : NS_IMETHODIMP nsXULWindow::SetSize(PRInt32 aCX, PRInt32 aCY, bool aRepaint)
     599                 : {
     600                 :   /* any attempt to set the window's size or position overrides the window's
     601                 :      zoom state. this is important when these two states are competing while
     602                 :      the window is being opened. but it should probably just always be so. */
     603               0 :   mWindow->SetSizeMode(nsSizeMode_Normal);
     604                 : 
     605               0 :   mIntrinsicallySized = false;
     606                 : 
     607               0 :   NS_ENSURE_SUCCESS(mWindow->Resize(aCX, aCY, aRepaint), NS_ERROR_FAILURE);
     608               0 :   if (!mChromeLoaded) {
     609                 :     // If we're called before the chrome is loaded someone obviously wants this
     610                 :     // window at this size & in the normal size mode (since it is the only mode
     611                 :     // in which setting dimensions makes sense). We don't persist this one-time
     612                 :     // size.
     613               0 :     mIgnoreXULSize = true;
     614               0 :     mIgnoreXULSizeMode = true;
     615               0 :     return NS_OK;
     616                 :   }
     617               0 :   PersistentAttributesDirty(PAD_SIZE);
     618               0 :   SavePersistentAttributes();
     619               0 :   return NS_OK;
     620                 : }
     621                 : 
     622               0 : NS_IMETHODIMP nsXULWindow::GetSize(PRInt32* aCX, PRInt32* aCY)
     623                 : {
     624               0 :   return GetPositionAndSize(nsnull, nsnull, aCX, aCY);
     625                 : }
     626                 : 
     627               0 : NS_IMETHODIMP nsXULWindow::SetPositionAndSize(PRInt32 aX, PRInt32 aY, 
     628                 :    PRInt32 aCX, PRInt32 aCY, bool aRepaint)
     629                 : {
     630                 :   /* any attempt to set the window's size or position overrides the window's
     631                 :      zoom state. this is important when these two states are competing while
     632                 :      the window is being opened. but it should probably just always be so. */
     633               0 :   mWindow->SetSizeMode(nsSizeMode_Normal);
     634                 : 
     635               0 :   mIntrinsicallySized = false;
     636                 : 
     637               0 :   NS_ENSURE_SUCCESS(mWindow->Resize(aX, aY, aCX, aCY, aRepaint), NS_ERROR_FAILURE);
     638               0 :   if (!mChromeLoaded) {
     639                 :     // If we're called before the chrome is loaded someone obviously wants this
     640                 :     // window at this size and position. We don't persist this one-time setting.
     641               0 :     mIgnoreXULPosition = true;
     642               0 :     mIgnoreXULSize = true;
     643               0 :     mIgnoreXULSizeMode = true;
     644               0 :     return NS_OK;
     645                 :   }
     646               0 :   PersistentAttributesDirty(PAD_POSITION | PAD_SIZE);
     647               0 :   SavePersistentAttributes();
     648               0 :   return NS_OK;
     649                 : }
     650                 : 
     651               0 : NS_IMETHODIMP nsXULWindow::GetPositionAndSize(PRInt32* x, PRInt32* y, PRInt32* cx,
     652                 :    PRInt32* cy)
     653                 : {
     654               0 :   nsIntRect rect;
     655                 : 
     656               0 :   if (!mWindow)
     657               0 :     return NS_ERROR_FAILURE;
     658                 : 
     659               0 :   mWindow->GetScreenBounds(rect);
     660                 : 
     661               0 :   if (x)
     662               0 :     *x = rect.x;
     663               0 :   if (y)
     664               0 :     *y = rect.y;
     665               0 :   if (cx)
     666               0 :     *cx = rect.width;
     667               0 :   if (cy)
     668               0 :     *cy = rect.height;
     669                 : 
     670               0 :   return NS_OK;
     671                 : }
     672                 : 
     673               0 : NS_IMETHODIMP nsXULWindow::Center(nsIXULWindow *aRelative, bool aScreen, bool aAlert)
     674                 : {
     675                 :   PRInt32  left, top, width, height,
     676                 :            ourWidth, ourHeight;
     677               0 :   bool     screenCoordinates =  false,
     678               0 :            windowCoordinates =  false;
     679                 :   nsresult result;
     680                 : 
     681               0 :   if (!mChromeLoaded) {
     682                 :     // note we lose the parameters. at time of writing, this isn't a problem.
     683               0 :     mCenterAfterLoad = true;
     684               0 :     return NS_OK;
     685                 :   }
     686                 : 
     687               0 :   if (!aScreen && !aRelative)
     688               0 :     return NS_ERROR_INVALID_ARG;
     689                 : 
     690               0 :   nsCOMPtr<nsIScreenManager> screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1", &result);
     691               0 :   if (NS_FAILED(result))
     692               0 :     return result;
     693                 : 
     694               0 :   nsCOMPtr<nsIScreen> screen;
     695                 : 
     696               0 :   if (aRelative) {
     697               0 :     nsCOMPtr<nsIBaseWindow> base(do_QueryInterface(aRelative, &result));
     698               0 :     if (base) {
     699                 :       // get window rect
     700               0 :       result = base->GetPositionAndSize(&left, &top, &width, &height);
     701               0 :       if (NS_SUCCEEDED(result)) {
     702                 :         // if centering on screen, convert that to the corresponding screen
     703               0 :         if (aScreen)
     704               0 :           screenmgr->ScreenForRect(left, top, width, height, getter_AddRefs(screen));
     705                 :         else
     706               0 :           windowCoordinates = true;
     707                 :       } else {
     708                 :         // something's wrong with the reference window.
     709                 :         // fall back to the primary screen
     710               0 :         aRelative = 0;
     711               0 :         aScreen = true;
     712                 :       }
     713                 :     }
     714                 :   }
     715               0 :   if (!aRelative) {
     716               0 :     if (!mOpenerScreenRect.IsEmpty()) {
     717               0 :       screenmgr->ScreenForRect(mOpenerScreenRect.x, mOpenerScreenRect.y,
     718                 :                                mOpenerScreenRect.width, mOpenerScreenRect.height,
     719               0 :                                getter_AddRefs(screen));
     720                 :     } else {
     721               0 :       screenmgr->GetPrimaryScreen(getter_AddRefs(screen));
     722                 :     }
     723                 :   }
     724                 : 
     725               0 :   if (aScreen && screen) {
     726               0 :     screen->GetAvailRect(&left, &top, &width, &height);
     727               0 :     screenCoordinates = true;
     728                 :   }
     729                 : 
     730               0 :   if (screenCoordinates || windowCoordinates) {
     731               0 :     GetSize(&ourWidth, &ourHeight);
     732               0 :     left += (width - ourWidth) / 2;
     733               0 :     top += (height - ourHeight) / (aAlert ? 3 : 2);
     734               0 :     if (windowCoordinates)
     735               0 :       mWindow->ConstrainPosition(false, &left, &top);
     736               0 :     SetPosition(left, top);
     737               0 :     return NS_OK;
     738                 :   }
     739               0 :   return NS_ERROR_FAILURE;
     740                 : }
     741                 : 
     742               0 : NS_IMETHODIMP nsXULWindow::Repaint(bool aForce)
     743                 : {
     744                 :   //XXX First Check In
     745               0 :   NS_ASSERTION(false, "Not Yet Implemented");
     746               0 :   return NS_OK;
     747                 : }
     748                 : 
     749               0 : NS_IMETHODIMP nsXULWindow::GetParentWidget(nsIWidget** aParentWidget)
     750                 : {
     751               0 :   NS_ENSURE_ARG_POINTER(aParentWidget);
     752               0 :   NS_ENSURE_STATE(mWindow);
     753                 : 
     754               0 :   NS_IF_ADDREF(*aParentWidget = mWindow->GetParent());
     755               0 :   return NS_OK;
     756                 : }
     757                 : 
     758               0 : NS_IMETHODIMP nsXULWindow::SetParentWidget(nsIWidget* aParentWidget)
     759                 : {
     760                 :   //XXX First Check In
     761               0 :   NS_ASSERTION(false, "Not Yet Implemented");
     762               0 :   return NS_OK;
     763                 : }
     764                 : 
     765               0 : NS_IMETHODIMP nsXULWindow::GetParentNativeWindow(nativeWindow* aParentNativeWindow)
     766                 : {
     767               0 :   NS_ENSURE_ARG_POINTER(aParentNativeWindow);
     768                 : 
     769               0 :   nsCOMPtr<nsIWidget> parentWidget;
     770               0 :   NS_ENSURE_SUCCESS(GetParentWidget(getter_AddRefs(parentWidget)), NS_ERROR_FAILURE);
     771                 : 
     772               0 :   if (parentWidget) {
     773               0 :     *aParentNativeWindow = parentWidget->GetNativeData(NS_NATIVE_WIDGET);
     774                 :   }
     775                 : 
     776               0 :   return NS_OK;
     777                 : }
     778                 : 
     779               0 : NS_IMETHODIMP nsXULWindow::SetParentNativeWindow(nativeWindow aParentNativeWindow)
     780                 : {
     781                 :   //XXX First Check In
     782               0 :   NS_ASSERTION(false, "Not Yet Implemented");
     783               0 :   return NS_OK;
     784                 : }
     785                 : 
     786               0 : NS_IMETHODIMP nsXULWindow::GetVisibility(bool* aVisibility)
     787                 : {
     788               0 :   NS_ENSURE_ARG_POINTER(aVisibility);
     789                 : 
     790                 :   // Always claim to be visible for now. See bug
     791                 :   // https://bugzilla.mozilla.org/show_bug.cgi?id=306245.
     792                 : 
     793               0 :   *aVisibility = true;
     794                 : 
     795               0 :   return NS_OK;
     796                 : }
     797                 : 
     798               0 : NS_IMETHODIMP nsXULWindow::SetVisibility(bool aVisibility)
     799                 : {
     800               0 :   if (!mChromeLoaded) {
     801               0 :     mShowAfterLoad = aVisibility;
     802               0 :     return NS_OK;
     803                 :   }
     804                 : 
     805               0 :   if (mDebuting) {
     806               0 :     return NS_OK;
     807                 :   }
     808               0 :   mDebuting = true;  // (Show / Focus is recursive)
     809                 : 
     810                 :   //XXXTAB Do we really need to show docshell and the window?  Isn't 
     811                 :   // the window good enough?
     812               0 :   nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(mDocShell));
     813               0 :   shellAsWin->SetVisibility(aVisibility);
     814                 :   // Store locally so it doesn't die on us. 'Show' can result in the window
     815                 :   // being closed with nsXULWindow::Destroy being called. That would set
     816                 :   // mWindow to null and posibly destroy the nsIWidget while its Show method
     817                 :   // is on the stack. We need to keep it alive until Show finishes.
     818               0 :   nsCOMPtr<nsIWidget> window = mWindow;
     819               0 :   window->Show(aVisibility);
     820                 : 
     821               0 :   nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
     822               0 :   if (windowMediator)
     823               0 :      windowMediator->UpdateWindowTimeStamp(static_cast<nsIXULWindow*>(this));
     824                 : 
     825                 :   // notify observers so that we can hide the splash screen if possible
     826                 :   nsCOMPtr<nsIObserverService> obssvc
     827               0 :     (do_GetService("@mozilla.org/observer-service;1"));
     828               0 :   NS_ASSERTION(obssvc, "Couldn't get observer service.");
     829               0 :   if (obssvc) {
     830               0 :     obssvc->NotifyObservers(nsnull, "xul-window-visible", nsnull); 
     831                 :   }
     832                 : 
     833               0 :   mDebuting = false;
     834               0 :   return NS_OK;
     835                 : }
     836                 : 
     837               0 : NS_IMETHODIMP nsXULWindow::GetEnabled(bool *aEnabled)
     838                 : {
     839               0 :   NS_ENSURE_ARG_POINTER(aEnabled);
     840               0 :   if (mWindow)
     841               0 :     return mWindow->IsEnabled(aEnabled);
     842                 : 
     843               0 :   *aEnabled = true; // better guess than most
     844               0 :   return NS_ERROR_FAILURE;
     845                 : }
     846                 : 
     847               0 : NS_IMETHODIMP nsXULWindow::SetEnabled(bool aEnable)
     848                 : {
     849               0 :   if (mWindow) {
     850               0 :     mWindow->Enable(aEnable);
     851               0 :     return NS_OK;
     852                 :   }
     853               0 :   return NS_ERROR_FAILURE;
     854                 : }
     855                 : 
     856               0 : NS_IMETHODIMP nsXULWindow::GetMainWidget(nsIWidget** aMainWidget)
     857                 : {
     858               0 :   NS_ENSURE_ARG_POINTER(aMainWidget);
     859                 :    
     860               0 :   *aMainWidget = mWindow;
     861               0 :   NS_IF_ADDREF(*aMainWidget);
     862               0 :   return NS_OK;
     863                 : }
     864                 : 
     865               0 : NS_IMETHODIMP nsXULWindow::SetFocus()
     866                 : {
     867                 :   //XXX First Check In
     868               0 :   NS_ASSERTION(false, "Not Yet Implemented");
     869               0 :   return NS_OK;
     870                 : }
     871                 : 
     872               0 : NS_IMETHODIMP nsXULWindow::GetTitle(PRUnichar** aTitle)
     873                 : {
     874               0 :   NS_ENSURE_ARG_POINTER(aTitle);
     875                 : 
     876               0 :   *aTitle = ToNewUnicode(mTitle);
     877               0 :   if (!*aTitle)
     878               0 :     return NS_ERROR_OUT_OF_MEMORY;
     879               0 :   return NS_OK;
     880                 : }
     881                 : 
     882               0 : NS_IMETHODIMP nsXULWindow::SetTitle(const PRUnichar* aTitle)
     883                 : {
     884               0 :   NS_ENSURE_STATE(mWindow);
     885               0 :   mTitle.Assign(aTitle);
     886               0 :   mTitle.StripChars("\n\r");
     887               0 :   NS_ENSURE_SUCCESS(mWindow->SetTitle(mTitle), NS_ERROR_FAILURE);
     888                 : 
     889                 :   // Tell the window mediator that a title has changed
     890               0 :   nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
     891               0 :   if (!windowMediator)
     892               0 :     return NS_OK;
     893                 : 
     894               0 :   windowMediator->UpdateWindowTitle(static_cast<nsIXULWindow*>(this), aTitle);
     895                 : 
     896               0 :   return NS_OK;
     897                 : }
     898                 : 
     899                 : 
     900                 : //*****************************************************************************
     901                 : // nsXULWindow: Helpers
     902                 : //*****************************************************************************   
     903                 : 
     904               0 : NS_IMETHODIMP nsXULWindow::EnsureChromeTreeOwner()
     905                 : {
     906               0 :   if (mChromeTreeOwner)
     907               0 :     return NS_OK;
     908                 : 
     909               0 :   mChromeTreeOwner = new nsChromeTreeOwner();
     910               0 :   NS_ENSURE_TRUE(mChromeTreeOwner, NS_ERROR_OUT_OF_MEMORY);
     911                 : 
     912               0 :   NS_ADDREF(mChromeTreeOwner);
     913               0 :   mChromeTreeOwner->XULWindow(this);
     914                 : 
     915               0 :   return NS_OK;
     916                 : }
     917                 : 
     918               0 : NS_IMETHODIMP nsXULWindow::EnsureContentTreeOwner()
     919                 : {
     920               0 :   if (mContentTreeOwner)
     921               0 :     return NS_OK;
     922                 : 
     923               0 :   mContentTreeOwner = new nsContentTreeOwner(false);
     924               0 :   NS_ENSURE_TRUE(mContentTreeOwner, NS_ERROR_FAILURE);
     925                 : 
     926               0 :   NS_ADDREF(mContentTreeOwner);
     927               0 :   mContentTreeOwner->XULWindow(this);
     928                 :    
     929               0 :   return NS_OK;
     930                 : }
     931                 : 
     932               0 : NS_IMETHODIMP nsXULWindow::EnsurePrimaryContentTreeOwner()
     933                 : {
     934               0 :   if (mPrimaryContentTreeOwner)
     935               0 :     return NS_OK;
     936                 : 
     937               0 :   mPrimaryContentTreeOwner = new nsContentTreeOwner(true);
     938               0 :   NS_ENSURE_TRUE(mPrimaryContentTreeOwner, NS_ERROR_FAILURE);
     939                 : 
     940               0 :   NS_ADDREF(mPrimaryContentTreeOwner);
     941               0 :   mPrimaryContentTreeOwner->XULWindow(this);
     942                 : 
     943               0 :   return NS_OK;
     944                 : }
     945                 : 
     946               0 : NS_IMETHODIMP nsXULWindow::EnsurePrompter()
     947                 : {
     948               0 :   if (mPrompter)
     949               0 :     return NS_OK;
     950                 :    
     951               0 :   nsCOMPtr<nsIDOMWindow> ourWindow;
     952               0 :   nsresult rv = GetWindowDOMWindow(getter_AddRefs(ourWindow));
     953               0 :   if (NS_SUCCEEDED(rv)) {
     954                 :     nsCOMPtr<nsIWindowWatcher> wwatch = 
     955               0 :         do_GetService(NS_WINDOWWATCHER_CONTRACTID);
     956               0 :     if (wwatch)
     957               0 :       wwatch->GetNewPrompter(ourWindow, getter_AddRefs(mPrompter));
     958                 :   }
     959               0 :   return mPrompter ? NS_OK : NS_ERROR_FAILURE;
     960                 : }
     961                 : 
     962               0 : NS_IMETHODIMP nsXULWindow::EnsureAuthPrompter()
     963                 : {
     964               0 :   if (mAuthPrompter)
     965               0 :     return NS_OK;
     966                 :       
     967               0 :   nsCOMPtr<nsIDOMWindow> ourWindow;
     968               0 :   nsresult rv = GetWindowDOMWindow(getter_AddRefs(ourWindow));
     969               0 :   if (NS_SUCCEEDED(rv)) {
     970               0 :     nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
     971               0 :     if (wwatch)
     972               0 :       wwatch->GetNewAuthPrompter(ourWindow, getter_AddRefs(mAuthPrompter));
     973                 :   }
     974               0 :   return mAuthPrompter ? NS_OK : NS_ERROR_FAILURE;
     975                 : }
     976                 :  
     977               0 : void nsXULWindow::OnChromeLoaded()
     978                 : {
     979               0 :   nsresult rv = EnsureContentTreeOwner();
     980                 : 
     981               0 :   if (NS_SUCCEEDED(rv)) {
     982               0 :     mChromeLoaded = true;
     983               0 :     ApplyChromeFlags();
     984               0 :     SyncAttributesToWidget();
     985               0 :     if (!mIgnoreXULSize)
     986               0 :       LoadSizeFromXUL();
     987               0 :     if (mIntrinsicallySized) {
     988                 :       // (if LoadSizeFromXUL set the size, mIntrinsicallySized will be false)
     989               0 :       nsCOMPtr<nsIContentViewer> cv;
     990               0 :       mDocShell->GetContentViewer(getter_AddRefs(cv));
     991               0 :       nsCOMPtr<nsIMarkupDocumentViewer> markupViewer(do_QueryInterface(cv));
     992               0 :       if (markupViewer)
     993               0 :         markupViewer->SizeToContent();
     994                 :     }
     995                 : 
     996               0 :     bool positionSet = !mIgnoreXULPosition;
     997               0 :     nsCOMPtr<nsIXULWindow> parentWindow(do_QueryReferent(mParentWindow));
     998                 : #if defined(XP_UNIX) && !defined(XP_MACOSX)
     999                 :     // don't override WM placement on unix for independent, top-level windows
    1000                 :     // (however, we think the benefits of intelligent dependent window placement
    1001                 :     // trump that override.)
    1002               0 :     if (!parentWindow)
    1003               0 :       positionSet = false;
    1004                 : #endif
    1005               0 :     if (positionSet)
    1006               0 :       positionSet = LoadPositionFromXUL();
    1007               0 :     LoadMiscPersistentAttributesFromXUL();
    1008                 : 
    1009               0 :     if (mCenterAfterLoad && !positionSet)
    1010               0 :       Center(parentWindow, parentWindow ? false : true, false);
    1011                 : 
    1012               0 :     if (mShowAfterLoad) {
    1013               0 :       SetVisibility(true);
    1014                 :       // At this point the window may have been closed during Show(), so
    1015                 :       // nsXULWindow::Destroy may already have been called. Take care!
    1016                 :     }
    1017                 :   }
    1018               0 :   mPersistentAttributesMask |= PAD_POSITION | PAD_SIZE | PAD_MISC;
    1019               0 : }
    1020                 : 
    1021               0 : bool nsXULWindow::LoadPositionFromXUL()
    1022                 : {
    1023                 :   nsresult rv;
    1024               0 :   bool     gotPosition = false;
    1025                 :   
    1026                 :   // if we're the hidden window, don't try to validate our size/position. We're
    1027                 :   // special.
    1028               0 :   if (mIsHiddenWindow)
    1029               0 :     return false;
    1030                 : 
    1031               0 :   nsCOMPtr<nsIDOMElement> windowElement;
    1032               0 :   GetWindowDOMElement(getter_AddRefs(windowElement));
    1033               0 :   NS_ASSERTION(windowElement, "no xul:window");
    1034               0 :   if (!windowElement)
    1035               0 :     return false;
    1036                 : 
    1037               0 :   PRInt32 currX = 0;
    1038               0 :   PRInt32 currY = 0;
    1039               0 :   PRInt32 currWidth = 0;
    1040               0 :   PRInt32 currHeight = 0;
    1041                 :   PRInt32 errorCode;
    1042                 :   PRInt32 temp;
    1043                 : 
    1044               0 :   GetPositionAndSize(&currX, &currY, &currWidth, &currHeight);
    1045                 : 
    1046                 :   // Obtain the position information from the <xul:window> element.
    1047               0 :   PRInt32 specX = currX;
    1048               0 :   PRInt32 specY = currY;
    1049               0 :   nsAutoString posString;
    1050               0 :   PRInt32 appPerDev = AppUnitsPerDevPixel();
    1051                 : 
    1052               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("screenX"), posString);
    1053               0 :   if (NS_SUCCEEDED(rv)) {
    1054               0 :     temp = posString.ToInteger(&errorCode);
    1055               0 :     if (NS_SUCCEEDED(errorCode)) {
    1056               0 :       specX = CSSToDevPixels(temp, appPerDev);
    1057               0 :       gotPosition = true;
    1058                 :     }
    1059                 :   }
    1060               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("screenY"), posString);
    1061               0 :   if (NS_SUCCEEDED(rv)) {
    1062               0 :     temp = posString.ToInteger(&errorCode);
    1063               0 :     if (NS_SUCCEEDED(errorCode)) {
    1064               0 :       specY = CSSToDevPixels(temp, appPerDev);
    1065               0 :       gotPosition = true;
    1066                 :     }
    1067                 :   }
    1068                 :     
    1069               0 :   if (gotPosition) {
    1070                 :     // our position will be relative to our parent, if any
    1071               0 :     nsCOMPtr<nsIBaseWindow> parent(do_QueryReferent(mParentWindow));
    1072               0 :     if (parent) {
    1073                 :       PRInt32 parentX, parentY;
    1074               0 :       if (NS_SUCCEEDED(parent->GetPosition(&parentX, &parentY))) {
    1075               0 :         specX += parentX;
    1076               0 :         specY += parentY;
    1077                 :       }
    1078                 :     }
    1079                 :     else {
    1080               0 :       StaggerPosition(specX, specY, currWidth, currHeight);
    1081                 :     }
    1082                 :   }
    1083               0 :   mWindow->ConstrainPosition(false, &specX, &specY);
    1084               0 :   if (specX != currX || specY != currY)
    1085               0 :     SetPosition(specX, specY);
    1086                 : 
    1087               0 :   return gotPosition;
    1088                 : }
    1089                 : 
    1090               0 : bool nsXULWindow::LoadSizeFromXUL()
    1091                 : {
    1092                 :   nsresult rv;
    1093               0 :   bool     gotSize = false;
    1094                 :   
    1095                 :   // if we're the hidden window, don't try to validate our size/position. We're
    1096                 :   // special.
    1097               0 :   if (mIsHiddenWindow)
    1098               0 :     return false;
    1099                 : 
    1100               0 :   nsCOMPtr<nsIDOMElement> windowElement;
    1101               0 :   GetWindowDOMElement(getter_AddRefs(windowElement));
    1102               0 :   NS_ASSERTION(windowElement, "no xul:window");
    1103               0 :   if (!windowElement)
    1104               0 :     return false;
    1105                 : 
    1106               0 :   PRInt32 currWidth = 0;
    1107               0 :   PRInt32 currHeight = 0;
    1108                 :   PRInt32 errorCode;
    1109                 :   PRInt32 temp;
    1110                 : 
    1111               0 :   GetSize(&currWidth, &currHeight);
    1112                 : 
    1113                 :   // Obtain the position and sizing information from the <xul:window> element.
    1114               0 :   PRInt32 specWidth = currWidth;
    1115               0 :   PRInt32 specHeight = currHeight;
    1116               0 :   nsAutoString sizeString;
    1117               0 :   PRInt32 appPerDev = AppUnitsPerDevPixel();
    1118                 : 
    1119               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("width"), sizeString);
    1120               0 :   if (NS_SUCCEEDED(rv)) {
    1121               0 :     temp = sizeString.ToInteger(&errorCode);
    1122               0 :     if (NS_SUCCEEDED(errorCode) && temp > 0) {
    1123               0 :       specWidth = CSSToDevPixels(NS_MAX(temp, 100), appPerDev);
    1124               0 :       gotSize = true;
    1125                 :     }
    1126                 :   }
    1127               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("height"), sizeString);
    1128               0 :   if (NS_SUCCEEDED(rv)) {
    1129               0 :     temp = sizeString.ToInteger(&errorCode);
    1130               0 :     if (NS_SUCCEEDED(errorCode) && temp > 0) {
    1131               0 :       specHeight = CSSToDevPixels(NS_MAX(temp, 100), appPerDev);
    1132               0 :       gotSize = true;
    1133                 :     }
    1134                 :   }
    1135                 : 
    1136               0 :   if (gotSize) {
    1137                 :     // constrain to screen size
    1138               0 :     nsCOMPtr<nsIDOMWindow> domWindow;
    1139               0 :     GetWindowDOMWindow(getter_AddRefs(domWindow));
    1140               0 :     if (domWindow) {
    1141               0 :       nsCOMPtr<nsIDOMScreen> screen;
    1142               0 :       domWindow->GetScreen(getter_AddRefs(screen));
    1143               0 :       if (screen) {
    1144                 :         PRInt32 screenWidth;
    1145                 :         PRInt32 screenHeight;
    1146               0 :         screen->GetAvailWidth(&screenWidth);
    1147               0 :         screen->GetAvailHeight(&screenHeight);
    1148               0 :         screenWidth = CSSToDevPixels(screenWidth, appPerDev);
    1149               0 :         screenHeight = CSSToDevPixels(screenHeight, appPerDev);
    1150               0 :         if (specWidth > screenWidth)
    1151               0 :           specWidth = screenWidth;
    1152               0 :         if (specHeight > screenHeight)
    1153               0 :           specHeight = screenHeight;
    1154                 :       }
    1155                 :     }
    1156                 : 
    1157               0 :     mIntrinsicallySized = false;
    1158               0 :     if (specWidth != currWidth || specHeight != currHeight)
    1159               0 :       SetSize(specWidth, specHeight, false);
    1160                 :   }
    1161                 : 
    1162               0 :   return gotSize;
    1163                 : }
    1164                 : 
    1165                 : /* Miscellaneous persistent attributes are attributes named in the
    1166                 :    |persist| attribute, other than size and position. Those are special
    1167                 :    because it's important to load those before one of the misc
    1168                 :    attributes (sizemode) and they require extra processing. */
    1169               0 : bool nsXULWindow::LoadMiscPersistentAttributesFromXUL()
    1170                 : {
    1171                 :   nsresult rv;
    1172               0 :   bool     gotState = false;
    1173                 :   
    1174                 :   /* There are no misc attributes of interest to the hidden window.
    1175                 :      It's especially important not to try to validate that window's
    1176                 :      size or position, because some platforms (Mac OS X) need to
    1177                 :      make it visible and offscreen. */
    1178               0 :   if (mIsHiddenWindow)
    1179               0 :     return false;
    1180                 : 
    1181               0 :   nsCOMPtr<nsIDOMElement> windowElement;
    1182               0 :   GetWindowDOMElement(getter_AddRefs(windowElement));
    1183               0 :   NS_ASSERTION(windowElement, "no xul:window");
    1184               0 :   if (!windowElement)
    1185               0 :     return false;
    1186                 : 
    1187               0 :   nsAutoString stateString;
    1188                 : 
    1189                 :   // sizemode
    1190               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("sizemode"), stateString);
    1191               0 :   if (NS_SUCCEEDED(rv)) {
    1192               0 :     PRInt32 sizeMode = nsSizeMode_Normal;
    1193                 :     /* ignore request to minimize, to not confuse novices
    1194                 :     if (stateString.Equals(SIZEMODE_MINIMIZED))
    1195                 :       sizeMode = nsSizeMode_Minimized;
    1196                 :     */
    1197               0 :     if (!mIgnoreXULSizeMode &&
    1198               0 :         (stateString.Equals(SIZEMODE_MAXIMIZED) || stateString.Equals(SIZEMODE_FULLSCREEN))) {
    1199                 :       /* Honor request to maximize only if the window is sizable.
    1200                 :          An unsizable, unmaximizable, yet maximized window confuses
    1201                 :          Windows OS and is something of a travesty, anyway. */
    1202               0 :       if (mChromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) {
    1203               0 :         mIntrinsicallySized = false;
    1204                 :         
    1205               0 :         if (stateString.Equals(SIZEMODE_MAXIMIZED))
    1206               0 :           sizeMode = nsSizeMode_Maximized;
    1207                 :         else
    1208               0 :           sizeMode = nsSizeMode_Fullscreen;
    1209                 :       }
    1210                 :     }
    1211                 : 
    1212                 :     // If we are told to ignore the size mode attribute update the
    1213                 :     // document so the attribute and window are in sync.
    1214               0 :     if (mIgnoreXULSizeMode) {
    1215               0 :       nsAutoString sizeString;
    1216               0 :       if (sizeMode == nsSizeMode_Maximized)
    1217               0 :         sizeString.Assign(SIZEMODE_MAXIMIZED);
    1218               0 :       else if (sizeMode == nsSizeMode_Fullscreen)
    1219               0 :         sizeString.Assign(SIZEMODE_FULLSCREEN);
    1220               0 :       else if (sizeMode == nsSizeMode_Normal)
    1221               0 :         sizeString.Assign(SIZEMODE_NORMAL);
    1222               0 :       if (!sizeString.IsEmpty()) {
    1223               0 :         windowElement->SetAttribute(MODE_ATTRIBUTE, sizeString);
    1224                 :       }
    1225                 :     }
    1226                 : 
    1227               0 :     if (sizeMode == nsSizeMode_Fullscreen) {
    1228               0 :       nsCOMPtr<nsIDOMWindow> ourWindow;
    1229               0 :       GetWindowDOMWindow(getter_AddRefs(ourWindow));
    1230               0 :       ourWindow->SetFullScreen(true);
    1231                 :     } else {
    1232               0 :       mWindow->SetSizeMode(sizeMode);
    1233                 :     }
    1234               0 :     gotState = true;
    1235                 :   }
    1236                 : 
    1237                 :   // zlevel
    1238               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("zlevel"), stateString);
    1239               0 :   if (NS_SUCCEEDED(rv) && stateString.Length() > 0) {
    1240                 :     PRInt32  errorCode;
    1241               0 :     PRUint32 zLevel = stateString.ToInteger(&errorCode);
    1242               0 :     if (NS_SUCCEEDED(errorCode) && zLevel >= lowestZ && zLevel <= highestZ)
    1243               0 :       SetZLevel(zLevel);
    1244                 :   }
    1245                 : 
    1246               0 :   return gotState;
    1247                 : }
    1248                 : 
    1249                 : /* Stagger windows of the same type so they don't appear on top of each other.
    1250                 :    This code does have a scary double loop -- it'll keep passing through
    1251                 :    the entire list of open windows until it finds a non-collision. Doesn't
    1252                 :    seem to be a problem, but it deserves watching.
    1253                 : */
    1254               0 : void nsXULWindow::StaggerPosition(PRInt32 &aRequestedX, PRInt32 &aRequestedY,
    1255                 :                                   PRInt32 aSpecWidth, PRInt32 aSpecHeight)
    1256                 : {
    1257               0 :   const PRInt32 kOffset = 22;
    1258               0 :   const PRInt32 kSlop = 4;
    1259                 :   nsresult rv;
    1260                 :   bool     keepTrying;
    1261               0 :   int      bouncedX = 0, // bounced off vertical edge of screen
    1262               0 :            bouncedY = 0; // bounced off horizontal edge
    1263                 : 
    1264                 :   // look for any other windows of this type
    1265               0 :   nsCOMPtr<nsIWindowMediator> wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
    1266               0 :   if (!wm)
    1267                 :     return;
    1268                 : 
    1269               0 :   nsCOMPtr<nsIDOMElement> windowElement;
    1270               0 :   GetWindowDOMElement(getter_AddRefs(windowElement));
    1271               0 :   nsCOMPtr<nsIXULWindow> ourXULWindow(this);
    1272                 : 
    1273               0 :   nsAutoString windowType;
    1274               0 :   rv = windowElement->GetAttribute(WINDOWTYPE_ATTRIBUTE, windowType);
    1275               0 :   if (NS_FAILED(rv))
    1276                 :     return;
    1277                 : 
    1278               0 :   PRInt32 screenTop = 0,    // it's pointless to initialize these ...
    1279               0 :           screenRight = 0,  // ... but to prevent oversalubrious and ...
    1280               0 :           screenBottom = 0, // ... underbright compilers from ...
    1281               0 :           screenLeft = 0;   // ... issuing warnings.
    1282               0 :   bool    gotScreen = false;
    1283                 : 
    1284                 :   { // fetch screen coordinates
    1285                 :     nsCOMPtr<nsIScreenManager> screenMgr(do_GetService(
    1286               0 :                                          "@mozilla.org/gfx/screenmanager;1"));
    1287               0 :     if (screenMgr) {
    1288               0 :       nsCOMPtr<nsIScreen> ourScreen;
    1289               0 :       screenMgr->ScreenForRect(aRequestedX, aRequestedY,
    1290                 :                                aSpecWidth, aSpecHeight,
    1291               0 :                                getter_AddRefs(ourScreen));
    1292               0 :       if (ourScreen) {
    1293                 :         PRInt32 screenWidth, screenHeight;
    1294               0 :         ourScreen->GetAvailRect(&screenLeft, &screenTop,
    1295               0 :                                 &screenWidth, &screenHeight);
    1296               0 :         screenBottom = screenTop + screenHeight;
    1297               0 :         screenRight = screenLeft + screenWidth;
    1298               0 :         gotScreen = true;
    1299                 :       }
    1300                 :     }
    1301                 :   }
    1302                 : 
    1303                 :   // One full pass through all windows of this type, repeat until no collisions.
    1304               0 :   do {
    1305               0 :     keepTrying = false;
    1306               0 :     nsCOMPtr<nsISimpleEnumerator> windowList;
    1307               0 :     wm->GetXULWindowEnumerator(windowType.get(), getter_AddRefs(windowList));
    1308                 : 
    1309               0 :     if (!windowList)
    1310                 :       break;
    1311                 : 
    1312                 :     // One full pass through all windows of this type, offset and stop on collision.
    1313               0 :     do {
    1314                 :       bool more;
    1315               0 :       windowList->HasMoreElements(&more);
    1316               0 :       if (!more)
    1317               0 :         break;
    1318                 : 
    1319               0 :       nsCOMPtr<nsISupports> supportsWindow;
    1320               0 :       windowList->GetNext(getter_AddRefs(supportsWindow));
    1321                 : 
    1322               0 :       nsCOMPtr<nsIXULWindow> listXULWindow(do_QueryInterface(supportsWindow));
    1323               0 :       if (listXULWindow != ourXULWindow) {
    1324                 :         PRInt32 listX, listY;
    1325               0 :         nsCOMPtr<nsIBaseWindow> listBaseWindow(do_QueryInterface(supportsWindow));
    1326               0 :         listBaseWindow->GetPosition(&listX, &listY);
    1327                 : 
    1328               0 :         if (NS_ABS(listX - aRequestedX) <= kSlop &&
    1329               0 :             NS_ABS(listY - aRequestedY) <= kSlop) {
    1330                 :           // collision! offset and start over
    1331               0 :           if (bouncedX & 0x1)
    1332               0 :             aRequestedX -= kOffset;
    1333                 :           else
    1334               0 :             aRequestedX += kOffset;
    1335               0 :           aRequestedY += kOffset;
    1336                 : 
    1337               0 :           if (gotScreen) {
    1338                 :             // if we're moving to the right and we need to bounce...
    1339               0 :             if (!(bouncedX & 0x1) && ((aRequestedX + aSpecWidth) > screenRight)) {
    1340               0 :               aRequestedX = screenRight - aSpecWidth;
    1341               0 :               ++bouncedX;
    1342                 :             }
    1343                 : 
    1344                 :             // if we're moving to the left and we need to bounce...
    1345               0 :             if ((bouncedX & 0x1) && aRequestedX < screenLeft) {
    1346               0 :               aRequestedX = screenLeft;
    1347               0 :               ++bouncedX;
    1348                 :             }
    1349                 : 
    1350                 :             // if we hit the bottom then bounce to the top
    1351               0 :             if (aRequestedY + aSpecHeight > screenBottom) {
    1352               0 :               aRequestedY = screenTop;
    1353               0 :               ++bouncedY;
    1354                 :             }
    1355                 :           }
    1356                 : 
    1357                 :           /* loop around again,
    1358                 :              but it's time to give up once we've covered the screen.
    1359                 :              there's a potential infinite loop with lots of windows. */
    1360               0 :           keepTrying = bouncedX < 2 || bouncedY == 0;
    1361                 :           break;
    1362                 :         }
    1363                 :       }
    1364                 :     } while(1);
    1365                 :   } while (keepTrying);
    1366                 : }
    1367                 : 
    1368               0 : void nsXULWindow::SyncAttributesToWidget()
    1369                 : {
    1370               0 :   nsCOMPtr<nsIDOMElement> windowElement;
    1371               0 :   GetWindowDOMElement(getter_AddRefs(windowElement));
    1372               0 :   if (!windowElement)
    1373                 :     return;
    1374                 : 
    1375               0 :   nsAutoString attr;
    1376                 : 
    1377                 :   // "hidechrome" attribute
    1378               0 :   nsresult rv = windowElement->GetAttribute(NS_LITERAL_STRING("hidechrome"), attr);
    1379               0 :   if (NS_SUCCEEDED(rv) && attr.EqualsLiteral("true")) {
    1380               0 :     mWindow->HideWindowChrome(true);
    1381                 :   }
    1382                 : 
    1383                 :   // "chromemargin" attribute
    1384               0 :   nsIntMargin margins;
    1385               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("chromemargin"), attr);
    1386               0 :   if (NS_SUCCEEDED(rv) && nsContentUtils::ParseIntMarginValue(attr, margins)) {
    1387               0 :     mWindow->SetNonClientMargins(margins);
    1388                 :   }
    1389                 : 
    1390                 :   // "accelerated" attribute
    1391                 :   bool isAccelerated;
    1392               0 :   rv = windowElement->HasAttribute(NS_LITERAL_STRING("accelerated"), &isAccelerated);
    1393               0 :   if (NS_SUCCEEDED(rv)) {
    1394               0 :     mWindow->SetAcceleratedRendering(isAccelerated);
    1395                 :   }
    1396                 : 
    1397                 :   // "windowtype" attribute
    1398               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("windowtype"), attr);
    1399               0 :   if (NS_SUCCEEDED(rv) && !attr.IsEmpty()) {
    1400               0 :     mWindow->SetWindowClass(attr);
    1401                 :   }
    1402                 : 
    1403                 :   // "id" attribute for icon
    1404               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("id"), attr);
    1405               0 :   if (NS_FAILED(rv) || attr.IsEmpty()) {
    1406               0 :     attr.AssignLiteral("default");
    1407                 :   }
    1408               0 :   mWindow->SetIcon(attr);
    1409                 : 
    1410                 :   // "toggletoolbar" attribute
    1411               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("toggletoolbar"), attr);
    1412               0 :   if (NS_SUCCEEDED(rv)) {
    1413               0 :     mWindow->SetShowsToolbarButton(attr.LowerCaseEqualsLiteral("true"));
    1414                 :   }
    1415                 : 
    1416                 :   // "macanimationtype" attribute
    1417               0 :   rv = windowElement->GetAttribute(NS_LITERAL_STRING("macanimationtype"), attr);
    1418               0 :   if (NS_SUCCEEDED(rv) && attr.EqualsLiteral("document")) {
    1419               0 :     mWindow->SetWindowAnimationType(nsIWidget::eDocumentWindowAnimation);
    1420                 :   }
    1421                 : }
    1422                 : 
    1423               0 : NS_IMETHODIMP nsXULWindow::SavePersistentAttributes()
    1424                 : {
    1425                 :   // can happen when the persistence timer fires at an inopportune time
    1426                 :   // during window shutdown
    1427               0 :   if (!mDocShell)
    1428               0 :     return NS_ERROR_FAILURE;
    1429                 : 
    1430               0 :   nsCOMPtr<nsIDOMElement> docShellElement;
    1431               0 :   GetWindowDOMElement(getter_AddRefs(docShellElement));
    1432               0 :   if (!docShellElement)
    1433               0 :     return NS_ERROR_FAILURE;
    1434                 : 
    1435               0 :   nsAutoString   persistString;
    1436               0 :   docShellElement->GetAttribute(PERSIST_ATTRIBUTE, persistString);
    1437               0 :   if (persistString.IsEmpty()) { // quick check which sometimes helps
    1438               0 :     mPersistentAttributesDirty = 0;
    1439               0 :     return NS_OK;
    1440                 :   }
    1441                 : 
    1442                 :   PRInt32 x, y, cx, cy;
    1443                 :   PRInt32 sizeMode;
    1444                 : 
    1445                 :   // get our size, position and mode to persist
    1446               0 :   NS_ENSURE_SUCCESS(GetPositionAndSize(&x, &y, &cx, &cy), NS_ERROR_FAILURE);
    1447               0 :   mWindow->GetSizeMode(&sizeMode);
    1448                 : 
    1449                 :   // make our position relative to our parent, if any
    1450               0 :   nsCOMPtr<nsIBaseWindow> parent(do_QueryReferent(mParentWindow));
    1451               0 :   if (parent) {
    1452                 :     PRInt32 parentX, parentY;
    1453               0 :     if (NS_SUCCEEDED(parent->GetPosition(&parentX, &parentY))) {
    1454               0 :       x -= parentX;
    1455               0 :       y -= parentY;
    1456                 :     }
    1457                 :   }
    1458                 : 
    1459                 :   char                        sizeBuf[10];
    1460               0 :   nsAutoString                sizeString;
    1461               0 :   nsAutoString                windowElementId;
    1462               0 :   nsCOMPtr<nsIDOMXULDocument> ownerXULDoc;
    1463               0 :   PRInt32 appPerDev = AppUnitsPerDevPixel();
    1464                 : 
    1465                 :   { // fetch docShellElement's ID and XUL owner document
    1466               0 :     nsCOMPtr<nsIDOMDocument> ownerDoc;
    1467               0 :     docShellElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
    1468               0 :     ownerXULDoc = do_QueryInterface(ownerDoc);
    1469               0 :     nsCOMPtr<nsIDOMXULElement> XULElement(do_QueryInterface(docShellElement));
    1470               0 :     if (XULElement)
    1471               0 :       XULElement->GetId(windowElementId);
    1472                 :   }
    1473                 : 
    1474                 :   // (only for size elements which are persisted)
    1475               0 :   if ((mPersistentAttributesDirty & PAD_POSITION) &&
    1476                 :       sizeMode == nsSizeMode_Normal) {
    1477               0 :     if (persistString.Find("screenX") >= 0) {
    1478                 :       PR_snprintf(sizeBuf, sizeof(sizeBuf), "%ld",
    1479               0 :                   (long)DevToCSSPixels(x, appPerDev));
    1480               0 :       sizeString.AssignWithConversion(sizeBuf);
    1481               0 :       docShellElement->SetAttribute(SCREENX_ATTRIBUTE, sizeString);
    1482               0 :       if (ownerXULDoc) // force persistence in case the value didn't change
    1483               0 :         ownerXULDoc->Persist(windowElementId, SCREENX_ATTRIBUTE);
    1484                 :     }
    1485               0 :     if (persistString.Find("screenY") >= 0) {
    1486                 :       PR_snprintf(sizeBuf, sizeof(sizeBuf), "%ld",
    1487               0 :                   (long)DevToCSSPixels(y, appPerDev));
    1488               0 :       sizeString.AssignWithConversion(sizeBuf);
    1489               0 :       docShellElement->SetAttribute(SCREENY_ATTRIBUTE, sizeString);
    1490               0 :       if (ownerXULDoc)
    1491               0 :         ownerXULDoc->Persist(windowElementId, SCREENY_ATTRIBUTE);
    1492                 :     }
    1493                 :   }
    1494                 : 
    1495               0 :   if ((mPersistentAttributesDirty & PAD_SIZE) &&
    1496                 :       sizeMode == nsSizeMode_Normal) {
    1497               0 :     if (persistString.Find("width") >= 0) {
    1498                 :       PR_snprintf(sizeBuf, sizeof(sizeBuf), "%ld",
    1499               0 :                   (long)DevToCSSPixels(cx, appPerDev));
    1500               0 :       sizeString.AssignWithConversion(sizeBuf);
    1501               0 :       docShellElement->SetAttribute(WIDTH_ATTRIBUTE, sizeString);
    1502               0 :       if (ownerXULDoc)
    1503               0 :         ownerXULDoc->Persist(windowElementId, WIDTH_ATTRIBUTE);
    1504                 :     }
    1505               0 :     if (persistString.Find("height") >= 0) {
    1506                 :       PR_snprintf(sizeBuf, sizeof(sizeBuf), "%ld",
    1507               0 :                   (long)DevToCSSPixels(cy, appPerDev));
    1508               0 :       sizeString.AssignWithConversion(sizeBuf);
    1509               0 :       docShellElement->SetAttribute(HEIGHT_ATTRIBUTE, sizeString);
    1510               0 :       if (ownerXULDoc)
    1511               0 :         ownerXULDoc->Persist(windowElementId, HEIGHT_ATTRIBUTE);
    1512                 :     }
    1513                 :   }
    1514                 : 
    1515               0 :   if (mPersistentAttributesDirty & PAD_MISC) {
    1516               0 :     if (sizeMode != nsSizeMode_Minimized) {
    1517               0 :       if (sizeMode == nsSizeMode_Maximized)
    1518               0 :         sizeString.Assign(SIZEMODE_MAXIMIZED);
    1519               0 :       else if (sizeMode == nsSizeMode_Fullscreen)
    1520               0 :         sizeString.Assign(SIZEMODE_FULLSCREEN);
    1521                 :       else
    1522               0 :         sizeString.Assign(SIZEMODE_NORMAL);
    1523               0 :       docShellElement->SetAttribute(MODE_ATTRIBUTE, sizeString);
    1524               0 :       if (ownerXULDoc && persistString.Find("sizemode") >= 0)
    1525               0 :         ownerXULDoc->Persist(windowElementId, MODE_ATTRIBUTE);
    1526                 :     }
    1527               0 :     if (persistString.Find("zlevel") >= 0) {
    1528                 :       PRUint32 zLevel;
    1529               0 :       nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
    1530               0 :       if (mediator) {
    1531               0 :         mediator->GetZLevel(this, &zLevel);
    1532               0 :         PR_snprintf(sizeBuf, sizeof(sizeBuf), "%lu", (unsigned long)zLevel);
    1533               0 :         sizeString.AssignWithConversion(sizeBuf);
    1534               0 :         docShellElement->SetAttribute(ZLEVEL_ATTRIBUTE, sizeString);
    1535               0 :         ownerXULDoc->Persist(windowElementId, ZLEVEL_ATTRIBUTE);
    1536                 :       }
    1537                 :     }
    1538                 :   }
    1539                 : 
    1540               0 :   mPersistentAttributesDirty = 0;
    1541               0 :   return NS_OK;
    1542                 : }
    1543                 : 
    1544               0 : NS_IMETHODIMP nsXULWindow::GetWindowDOMWindow(nsIDOMWindow** aDOMWindow)
    1545                 : {
    1546               0 :   NS_ENSURE_STATE(mDocShell);
    1547                 : 
    1548               0 :   if (!mDOMWindow)
    1549               0 :     mDOMWindow = do_GetInterface(mDocShell);
    1550               0 :   NS_ENSURE_TRUE(mDOMWindow, NS_ERROR_FAILURE);
    1551                 : 
    1552               0 :   *aDOMWindow = mDOMWindow;
    1553               0 :   NS_ADDREF(*aDOMWindow);
    1554               0 :   return NS_OK;
    1555                 : }
    1556                 : 
    1557               0 : NS_IMETHODIMP nsXULWindow::GetWindowDOMElement(nsIDOMElement** aDOMElement)
    1558                 : {
    1559               0 :   NS_ENSURE_STATE(mDocShell);
    1560               0 :   NS_ENSURE_ARG_POINTER(aDOMElement);
    1561                 : 
    1562               0 :   *aDOMElement = nsnull;
    1563                 : 
    1564               0 :   nsCOMPtr<nsIContentViewer> cv;
    1565                 : 
    1566               0 :   mDocShell->GetContentViewer(getter_AddRefs(cv));
    1567               0 :   NS_ENSURE_TRUE(cv, NS_ERROR_FAILURE);
    1568                 : 
    1569               0 :   nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(cv->GetDocument()));
    1570               0 :   NS_ENSURE_TRUE(domdoc, NS_ERROR_FAILURE);
    1571                 : 
    1572               0 :   domdoc->GetDocumentElement(aDOMElement);
    1573               0 :   NS_ENSURE_TRUE(*aDOMElement, NS_ERROR_FAILURE);
    1574                 : 
    1575               0 :   return NS_OK;
    1576                 : }
    1577                 : 
    1578               0 : nsresult nsXULWindow::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
    1579                 :    bool aPrimary, bool aTargetable, const nsAString& aID)
    1580                 : {
    1581               0 :   nsContentShellInfo* shellInfo = nsnull;
    1582                 : 
    1583               0 :   PRUint32 i, count = mContentShells.Length();
    1584               0 :   nsWeakPtr contentShellWeak = do_GetWeakReference(aContentShell);
    1585               0 :   for (i = 0; i < count; i++) {
    1586               0 :     nsContentShellInfo* info = mContentShells.ElementAt(i);
    1587               0 :     if (info->id.Equals(aID)) {
    1588                 :       // We already exist. Do a replace.
    1589               0 :       info->child = contentShellWeak;
    1590               0 :       shellInfo = info;
    1591                 :     }
    1592               0 :     else if (info->child == contentShellWeak)
    1593               0 :       info->child = nsnull;
    1594                 :   }
    1595                 : 
    1596               0 :   if (!shellInfo) {
    1597               0 :     shellInfo = new nsContentShellInfo(aID, contentShellWeak);
    1598               0 :     mContentShells.AppendElement(shellInfo);
    1599                 :   }
    1600                 :     
    1601                 :   // Set the default content tree owner
    1602               0 :   if (aPrimary) {
    1603               0 :     NS_ENSURE_SUCCESS(EnsurePrimaryContentTreeOwner(), NS_ERROR_FAILURE);
    1604               0 :     aContentShell->SetTreeOwner(mPrimaryContentTreeOwner);
    1605               0 :     mPrimaryContentShell = aContentShell;
    1606                 :   }
    1607                 :   else {
    1608               0 :     NS_ENSURE_SUCCESS(EnsureContentTreeOwner(), NS_ERROR_FAILURE);
    1609               0 :     aContentShell->SetTreeOwner(mContentTreeOwner);
    1610               0 :     if (mPrimaryContentShell == aContentShell)
    1611               0 :       mPrimaryContentShell = nsnull;
    1612                 :   }
    1613                 : 
    1614               0 :   if (aTargetable) {
    1615                 : #ifdef DEBUG
    1616               0 :     PRInt32 debugCount = mTargetableShells.Count();
    1617                 :     PRInt32 debugCounter;
    1618               0 :     for (debugCounter = debugCount - 1; debugCounter >= 0; --debugCounter) {
    1619                 :       nsCOMPtr<nsIDocShellTreeItem> curItem =
    1620               0 :         do_QueryReferent(mTargetableShells[debugCounter]);
    1621               0 :       NS_ASSERTION(!SameCOMIdentity(curItem, aContentShell),
    1622                 :                    "Adding already existing item to mTargetableShells");
    1623                 :     }
    1624                 : #endif
    1625                 :     
    1626                 :     // put the new shell at the start of the targetable shells list if either
    1627                 :     // it's the new primary shell or there is no existing primary shell (which
    1628                 :     // means that chances are this one just stopped being primary).  If we
    1629                 :     // really cared, we could keep track of the "last no longer primary shell"
    1630                 :     // explicitly, but it probably doesn't matter enough: the difference would
    1631                 :     // only be felt in a situation where all shells were non-primary, which
    1632                 :     // doesn't happen much.  In a situation where there is one and only one
    1633                 :     // primary shell, and in which shells get unmarked as primary before some
    1634                 :     // other shell gets marked as primary, this effectively stores the list of
    1635                 :     // targetable shells in "most recently primary first" order.
    1636                 :     bool inserted;
    1637               0 :     if (aPrimary || !mPrimaryContentShell) {
    1638               0 :       inserted = mTargetableShells.InsertObjectAt(contentShellWeak, 0);
    1639                 :     } else {
    1640               0 :       inserted = mTargetableShells.AppendObject(contentShellWeak);
    1641                 :     }
    1642               0 :     NS_ENSURE_TRUE(inserted, NS_ERROR_OUT_OF_MEMORY);
    1643                 :   }
    1644                 : 
    1645               0 :   return NS_OK;
    1646                 : }
    1647                 : 
    1648               0 : nsresult nsXULWindow::ContentShellRemoved(nsIDocShellTreeItem* aContentShell)
    1649                 : {
    1650               0 :   if (mPrimaryContentShell == aContentShell) {
    1651               0 :     mPrimaryContentShell = nsnull;
    1652                 :   }
    1653                 : 
    1654               0 :   PRInt32 i, count = mContentShells.Length();
    1655               0 :   for (i = count - 1; i >= 0; --i) {
    1656               0 :     nsContentShellInfo* info = mContentShells.ElementAt(i);
    1657               0 :     nsCOMPtr<nsIDocShellTreeItem> curItem = do_QueryReferent(info->child);
    1658               0 :     if (!curItem || SameCOMIdentity(curItem, aContentShell)) {
    1659               0 :       mContentShells.RemoveElementAt(i);
    1660               0 :       delete info;
    1661                 :     }
    1662                 :   }
    1663                 : 
    1664               0 :   count = mTargetableShells.Count();
    1665               0 :   for (i = count - 1; i >= 0; --i) {
    1666                 :     nsCOMPtr<nsIDocShellTreeItem> curItem =
    1667               0 :       do_QueryReferent(mTargetableShells[i]);
    1668               0 :     if (!curItem || SameCOMIdentity(curItem, aContentShell)) {
    1669               0 :       mTargetableShells.RemoveObjectAt(i);
    1670                 :     }
    1671                 :   }
    1672                 :   
    1673               0 :   return NS_OK;
    1674                 : }
    1675                 : 
    1676               0 : NS_IMETHODIMP nsXULWindow::SizeShellTo(nsIDocShellTreeItem* aShellItem,
    1677                 :    PRInt32 aCX, PRInt32 aCY)
    1678                 : {
    1679                 :   // XXXTAB This is wrong, we should actually reflow based on the passed in
    1680                 :   // shell.  For now we are hacking and doing delta sizing.  This is bad
    1681                 :   // because it assumes all size we add will go to the shell which probably
    1682                 :   // won't happen.
    1683                 : 
    1684               0 :   nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(aShellItem));
    1685               0 :   NS_ENSURE_TRUE(shellAsWin, NS_ERROR_FAILURE);
    1686                 : 
    1687               0 :   PRInt32 width = 0;
    1688               0 :   PRInt32 height = 0;
    1689               0 :   shellAsWin->GetSize(&width, &height);
    1690                 : 
    1691               0 :   PRInt32 widthDelta = aCX - width;
    1692               0 :   PRInt32 heightDelta = aCY - height;
    1693                 : 
    1694               0 :   if (widthDelta || heightDelta) {
    1695               0 :     PRInt32 winCX = 0;
    1696               0 :     PRInt32 winCY = 0;
    1697                 : 
    1698               0 :     GetSize(&winCX, &winCY);
    1699                 :     // There's no point in trying to make the window smaller than the
    1700                 :     // desired docshell size --- that's not likely to work. This whole
    1701                 :     // function assumes that the outer docshell is adding some constant
    1702                 :     // "border" chrome to aShellItem.
    1703               0 :     winCX = NS_MAX(winCX + widthDelta, aCX);
    1704               0 :     winCY = NS_MAX(winCY + heightDelta, aCY);
    1705               0 :     SetSize(winCX, winCY, true);
    1706                 :   }
    1707                 : 
    1708               0 :   return NS_OK;
    1709                 : }
    1710                 : 
    1711               0 : NS_IMETHODIMP nsXULWindow::ExitModalLoop(nsresult aStatus)
    1712                 : {
    1713               0 :   if (mContinueModalLoop)
    1714               0 :     EnableParent(true);
    1715               0 :   mContinueModalLoop = false;
    1716               0 :   mModalStatus = aStatus;
    1717               0 :   return NS_OK;
    1718                 : }
    1719                 : 
    1720                 : // top-level function to create a new window
    1721               0 : NS_IMETHODIMP nsXULWindow::CreateNewWindow(PRInt32 aChromeFlags,
    1722                 :                              nsIXULWindow **_retval)
    1723                 : {
    1724               0 :   NS_ENSURE_ARG_POINTER(_retval);
    1725                 : 
    1726               0 :   if (aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)
    1727               0 :     return CreateNewChromeWindow(aChromeFlags, _retval);
    1728               0 :   return CreateNewContentWindow(aChromeFlags, _retval);
    1729                 : }
    1730                 : 
    1731               0 : NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(PRInt32 aChromeFlags,
    1732                 :                                                  nsIXULWindow **_retval)
    1733                 : {
    1734               0 :   nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
    1735               0 :   NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE);
    1736                 : 
    1737                 :   // Just do a normal create of a window and return.
    1738                 : 
    1739               0 :   nsCOMPtr<nsIXULWindow> newWindow;
    1740               0 :   appShell->CreateTopLevelWindow(this, nsnull, aChromeFlags,
    1741                 :                                  nsIAppShellService::SIZE_TO_CONTENT,
    1742                 :                                  nsIAppShellService::SIZE_TO_CONTENT,
    1743               0 :                                  getter_AddRefs(newWindow));
    1744                 : 
    1745               0 :   NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
    1746                 : 
    1747               0 :   *_retval = newWindow;
    1748               0 :   NS_ADDREF(*_retval);
    1749                 : 
    1750               0 :   return NS_OK;
    1751                 : }
    1752                 : 
    1753               0 : NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(PRInt32 aChromeFlags,
    1754                 :                                                   nsIXULWindow **_retval)
    1755                 : {
    1756               0 :   nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
    1757               0 :   NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE);
    1758                 : 
    1759                 :   // We need to create a new top level window and then enter a nested
    1760                 :   // loop. Eventually the new window will be told that it has loaded,
    1761                 :   // at which time we know it is safe to spin out of the nested loop
    1762                 :   // and allow the opening code to proceed.
    1763                 : 
    1764               0 :   nsCOMPtr<nsIURI> uri;
    1765                 : 
    1766               0 :   nsAdoptingCString urlStr = Preferences::GetCString("browser.chromeURL");
    1767               0 :   if (urlStr.IsEmpty()) {
    1768               0 :     urlStr.AssignLiteral("chrome://navigator/content/navigator.xul");
    1769                 :   }
    1770                 : 
    1771               0 :   nsCOMPtr<nsIIOService> service(do_GetService(NS_IOSERVICE_CONTRACTID));
    1772               0 :   if (service) {
    1773               0 :     service->NewURI(urlStr, nsnull, nsnull, getter_AddRefs(uri));
    1774                 :   }
    1775               0 :   NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
    1776                 : 
    1777               0 :   nsCOMPtr<nsIXULWindow> newWindow;
    1778               0 :   appShell->CreateTopLevelWindow(this, uri,
    1779                 :                                  aChromeFlags, 615, 480,
    1780               0 :                                  getter_AddRefs(newWindow));
    1781                 : 
    1782               0 :   NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
    1783                 : 
    1784                 :   // Specify that we want the window to remain locked until the chrome has loaded.
    1785                 :   nsXULWindow *xulWin = static_cast<nsXULWindow*>
    1786                 :                                    (static_cast<nsIXULWindow*>
    1787               0 :                                                (newWindow));
    1788                 : 
    1789               0 :   xulWin->LockUntilChromeLoad();
    1790                 : 
    1791                 :   // Push nsnull onto the JSContext stack before we dispatch a native event.
    1792               0 :   nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1"));
    1793               0 :   if (stack && NS_SUCCEEDED(stack->Push(nsnull))) {
    1794               0 :     nsIThread *thread = NS_GetCurrentThread();
    1795               0 :     while (xulWin->IsLocked()) {
    1796               0 :       if (!NS_ProcessNextEvent(thread))
    1797               0 :         break;
    1798                 :     }
    1799                 :     JSContext *cx;
    1800               0 :     stack->Pop(&cx);
    1801               0 :     NS_ASSERTION(cx == nsnull, "JSContextStack mismatch");
    1802                 :   }
    1803                 : 
    1804               0 :   NS_ENSURE_STATE(xulWin->mPrimaryContentShell);
    1805                 : 
    1806               0 :   *_retval = newWindow;
    1807               0 :   NS_ADDREF(*_retval);
    1808                 : 
    1809               0 :   return NS_OK;
    1810                 : }
    1811                 : 
    1812               0 : void nsXULWindow::EnableParent(bool aEnable)
    1813                 : {
    1814               0 :   nsCOMPtr<nsIBaseWindow> parentWindow;
    1815               0 :   nsCOMPtr<nsIWidget>     parentWidget;
    1816                 : 
    1817               0 :   parentWindow = do_QueryReferent(mParentWindow);
    1818               0 :   if (parentWindow)
    1819               0 :     parentWindow->GetMainWidget(getter_AddRefs(parentWidget));
    1820               0 :   if (parentWidget)
    1821               0 :     parentWidget->Enable(aEnable);
    1822               0 : }
    1823                 : 
    1824                 : // Constrain the window to its proper z-level
    1825               0 : bool nsXULWindow::ConstrainToZLevel(bool        aImmediate,
    1826                 :                                       nsWindowZ  *aPlacement,
    1827                 :                                       nsIWidget  *aReqBelow,
    1828                 :                                       nsIWidget **aActualBelow)
    1829                 : {
    1830                 : #if 0
    1831                 :   /* Do we have a parent window? This means our z-order is already constrained,
    1832                 :      since we're a dependent window. Our window list isn't hierarchical,
    1833                 :      so we can't properly calculate placement for such a window.
    1834                 :      Should we just abort? */
    1835                 :   nsCOMPtr<nsIBaseWindow> parentWindow = do_QueryReferent(mParentWindow);
    1836                 :   if (parentWindow)
    1837                 :     return false;
    1838                 : #endif
    1839                 : 
    1840               0 :   nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
    1841               0 :   if (!mediator)
    1842               0 :     return false;
    1843                 : 
    1844                 :   bool           altered;
    1845                 :   PRUint32       position,
    1846                 :                  newPosition,
    1847                 :                  zLevel;
    1848               0 :   nsIXULWindow  *us = this;
    1849                 : 
    1850               0 :   altered = false;
    1851               0 :   mediator->GetZLevel(this, &zLevel);
    1852                 : 
    1853                 :   // translate from nsGUIEvent to nsIWindowMediator constants
    1854               0 :   position = nsIWindowMediator::zLevelTop;
    1855               0 :   if (*aPlacement == nsWindowZBottom || zLevel == nsIXULWindow::lowestZ)
    1856               0 :     position = nsIWindowMediator::zLevelBottom;
    1857               0 :   else if (*aPlacement == nsWindowZRelative)
    1858               0 :     position = nsIWindowMediator::zLevelBelow;
    1859                 : 
    1860               0 :   if (NS_SUCCEEDED(mediator->CalculateZPosition(us, position, aReqBelow,
    1861                 :                                &newPosition, aActualBelow, &altered))) {
    1862                 :     /* If we were asked to move to the top but constrained to remain
    1863                 :        below one of our other windows, first move all windows in that
    1864                 :        window's layer and above to the top. This allows the user to
    1865                 :        click a window which can't be topmost and still bring mozilla
    1866                 :        to the foreground. */
    1867               0 :     if (altered &&
    1868                 :         (position == nsIWindowMediator::zLevelTop ||
    1869                 :          (position == nsIWindowMediator::zLevelBelow && aReqBelow == 0)))
    1870               0 :       PlaceWindowLayersBehind(zLevel + 1, nsIXULWindow::highestZ, 0);
    1871                 : 
    1872               0 :     if (*aPlacement != nsWindowZBottom &&
    1873                 :         position == nsIWindowMediator::zLevelBottom)
    1874               0 :       altered = true;
    1875               0 :     if (altered || aImmediate) {
    1876               0 :       if (newPosition == nsIWindowMediator::zLevelTop)
    1877               0 :         *aPlacement = nsWindowZTop;
    1878               0 :       else if (newPosition == nsIWindowMediator::zLevelBottom)
    1879               0 :         *aPlacement = nsWindowZBottom;
    1880                 :       else
    1881               0 :         *aPlacement = nsWindowZRelative;
    1882                 : 
    1883               0 :       if (aImmediate) {
    1884               0 :         nsCOMPtr<nsIBaseWindow> ourBase = do_QueryObject(this);
    1885               0 :         if (ourBase) {
    1886               0 :           nsCOMPtr<nsIWidget> ourWidget;
    1887               0 :           ourBase->GetMainWidget(getter_AddRefs(ourWidget));
    1888               0 :           ourWidget->PlaceBehind(*aPlacement == nsWindowZBottom ?
    1889                 :                                    eZPlacementBottom : eZPlacementBelow,
    1890               0 :                                  *aActualBelow, false);
    1891                 :         }
    1892                 :       }
    1893                 :     }
    1894                 : 
    1895                 :     /* CalculateZPosition can tell us to be below nothing, because it tries
    1896                 :        not to change something it doesn't recognize. A request to verify
    1897                 :        being below an unrecognized window, then, is treated as a request
    1898                 :        to come to the top (below null) */
    1899               0 :     nsCOMPtr<nsIXULWindow> windowAbove;
    1900               0 :     if (newPosition == nsIWindowMediator::zLevelBelow && *aActualBelow) {
    1901                 :       void *data;
    1902               0 :       (*aActualBelow)->GetClientData(data);
    1903               0 :       if (data) {
    1904               0 :         windowAbove = reinterpret_cast<nsWebShellWindow*>(data);
    1905                 :       }
    1906                 :     }
    1907                 : 
    1908               0 :     mediator->SetZPosition(us, newPosition, windowAbove);
    1909                 :   }
    1910                 : 
    1911               0 :   return altered;
    1912                 : }
    1913                 : 
    1914                 : /* Re-z-position all windows in the layers from aLowLevel to aHighLevel,
    1915                 :    inclusive, to be behind aBehind. aBehind of null means on top.
    1916                 :    Note this method actually does nothing to our relative window positions.
    1917                 :    (And therefore there's no need to inform WindowMediator we're moving
    1918                 :    things, because we aren't.) This method is useful for, say, moving
    1919                 :    a range of layers of our own windows relative to windows belonging to
    1920                 :    external applications.
    1921                 : */
    1922               0 : void nsXULWindow::PlaceWindowLayersBehind(PRUint32 aLowLevel,
    1923                 :                                           PRUint32 aHighLevel,
    1924                 :                                           nsIXULWindow *aBehind)
    1925                 : {
    1926                 :   // step through windows in z-order from top to bottommost window
    1927                 : 
    1928               0 :   nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
    1929               0 :   if (!mediator)
    1930                 :     return;
    1931                 : 
    1932               0 :   nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
    1933               0 :   mediator->GetZOrderXULWindowEnumerator(0, true,
    1934               0 :               getter_AddRefs(windowEnumerator));
    1935               0 :   if (!windowEnumerator)
    1936                 :     return;
    1937                 : 
    1938                 :   // each window will be moved behind previousHighWidget, itself
    1939                 :   // a moving target. initialize it.
    1940               0 :   nsCOMPtr<nsIWidget> previousHighWidget;
    1941               0 :   if (aBehind) {
    1942               0 :     nsCOMPtr<nsIBaseWindow> highBase(do_QueryInterface(aBehind));
    1943               0 :     if (highBase)
    1944               0 :       highBase->GetMainWidget(getter_AddRefs(previousHighWidget));
    1945                 :   }
    1946                 : 
    1947                 :   // get next lower window
    1948                 :   bool more;
    1949               0 :   while (windowEnumerator->HasMoreElements(&more), more) {
    1950                 :     PRUint32 nextZ; // z-level of nextWindow
    1951               0 :     nsCOMPtr<nsISupports> nextWindow;
    1952               0 :     windowEnumerator->GetNext(getter_AddRefs(nextWindow));
    1953               0 :     nsCOMPtr<nsIXULWindow> nextXULWindow(do_QueryInterface(nextWindow));
    1954               0 :     nextXULWindow->GetZLevel(&nextZ);
    1955               0 :     if (nextZ < aLowLevel)
    1956                 :       break; // we've processed all windows through aLowLevel
    1957                 :     
    1958                 :     // move it just below its next higher window
    1959               0 :     nsCOMPtr<nsIBaseWindow> nextBase(do_QueryInterface(nextXULWindow));
    1960               0 :     if (nextBase) {
    1961               0 :       nsCOMPtr<nsIWidget> nextWidget;
    1962               0 :       nextBase->GetMainWidget(getter_AddRefs(nextWidget));
    1963               0 :       if (nextZ <= aHighLevel)
    1964               0 :         nextWidget->PlaceBehind(eZPlacementBelow, previousHighWidget, false);
    1965               0 :       previousHighWidget = nextWidget;
    1966                 :     }
    1967                 :   }
    1968                 : }
    1969                 : 
    1970               0 : void nsXULWindow::SetContentScrollbarVisibility(bool aVisible)
    1971                 : {
    1972               0 :   nsCOMPtr<nsIDOMWindow> contentWin(do_GetInterface(mPrimaryContentShell));
    1973               0 :   if (contentWin) {
    1974               0 :     nsCOMPtr<nsIDOMBarProp> scrollbars;
    1975               0 :     contentWin->GetScrollbars(getter_AddRefs(scrollbars));
    1976               0 :     if (scrollbars)
    1977               0 :       scrollbars->SetVisible(aVisible);
    1978                 :   }
    1979               0 : }
    1980                 : 
    1981               0 : bool nsXULWindow::GetContentScrollbarVisibility()
    1982                 : {
    1983                 :   // This code already exists in dom/src/base/nsBarProp.cpp, but we
    1984                 :   // can't safely get to that from here as this function is called
    1985                 :   // while the DOM window is being set up, and we need the DOM window
    1986                 :   // to get to that code.
    1987               0 :   nsCOMPtr<nsIScrollable> scroller(do_QueryInterface(mPrimaryContentShell));
    1988                 : 
    1989               0 :   if (scroller) {
    1990                 :     PRInt32 prefValue;
    1991               0 :     scroller->GetDefaultScrollbarPreferences(
    1992               0 :                   nsIScrollable::ScrollOrientation_Y, &prefValue);
    1993               0 :     if (prefValue == nsIScrollable::Scrollbar_Never) // try the other way
    1994               0 :       scroller->GetDefaultScrollbarPreferences(
    1995               0 :                   nsIScrollable::ScrollOrientation_X, &prefValue);
    1996                 : 
    1997               0 :     if (prefValue == nsIScrollable::Scrollbar_Never)
    1998               0 :       return false;
    1999                 :   }
    2000                 : 
    2001               0 :   return true;
    2002                 : }
    2003                 : 
    2004                 : // during spinup, attributes that haven't been loaded yet can't be dirty
    2005               0 : void nsXULWindow::PersistentAttributesDirty(PRUint32 aDirtyFlags)
    2006                 : {
    2007               0 :   mPersistentAttributesDirty |= aDirtyFlags & mPersistentAttributesMask;
    2008               0 : }
    2009                 : 
    2010               0 : NS_IMETHODIMP nsXULWindow::ApplyChromeFlags()
    2011                 : {
    2012               0 :   nsCOMPtr<nsIDOMElement> window;
    2013               0 :   GetWindowDOMElement(getter_AddRefs(window));
    2014               0 :   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
    2015                 : 
    2016               0 :   if (mChromeLoaded) {
    2017                 :     // The two calls in this block don't need to happen early because they
    2018                 :     // don't cause a global restyle on the document.  Not only that, but the
    2019                 :     // scrollbar stuff needs a content area to toggle the scrollbars on anyway.
    2020                 :     // So just don't do these until mChromeLoaded is true.
    2021                 :     
    2022                 :     // Scrollbars have their own special treatment.
    2023                 :     SetContentScrollbarVisibility(mChromeFlags &
    2024                 :                                   nsIWebBrowserChrome::CHROME_SCROLLBARS ?
    2025               0 :                                     true : false);
    2026                 :   }
    2027                 : 
    2028                 :   /* the other flags are handled together. we have style rules
    2029                 :      in navigator.css that trigger visibility based on
    2030                 :      the 'chromehidden' attribute of the <window> tag. */
    2031               0 :   nsAutoString newvalue;
    2032                 : 
    2033               0 :   if (! (mChromeFlags & nsIWebBrowserChrome::CHROME_MENUBAR))
    2034               0 :     newvalue.AppendLiteral("menubar ");
    2035                 : 
    2036               0 :   if (! (mChromeFlags & nsIWebBrowserChrome::CHROME_TOOLBAR))
    2037               0 :     newvalue.AppendLiteral("toolbar ");
    2038                 : 
    2039               0 :   if (! (mChromeFlags & nsIWebBrowserChrome::CHROME_LOCATIONBAR))
    2040               0 :     newvalue.AppendLiteral("location ");
    2041                 : 
    2042               0 :   if (! (mChromeFlags & nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR))
    2043               0 :     newvalue.AppendLiteral("directories ");
    2044                 : 
    2045               0 :   if (! (mChromeFlags & nsIWebBrowserChrome::CHROME_STATUSBAR))
    2046               0 :     newvalue.AppendLiteral("status ");
    2047                 : 
    2048               0 :   if (! (mChromeFlags & nsIWebBrowserChrome::CHROME_EXTRA))
    2049               0 :     newvalue.AppendLiteral("extrachrome ");
    2050                 : 
    2051                 :   // Note that if we're not actually changing the value this will be a no-op,
    2052                 :   // so no need to compare to the old value.
    2053               0 :   window->SetAttribute(NS_LITERAL_STRING("chromehidden"), newvalue);
    2054                 : 
    2055               0 :   return NS_OK;
    2056                 : }
    2057                 : 
    2058               0 : NS_IMETHODIMP nsXULWindow::GetXULBrowserWindow(nsIXULBrowserWindow * *aXULBrowserWindow)
    2059                 : {
    2060               0 :   NS_IF_ADDREF(*aXULBrowserWindow = mXULBrowserWindow);
    2061               0 :   return NS_OK;
    2062                 : }
    2063                 : 
    2064               0 : NS_IMETHODIMP nsXULWindow::SetXULBrowserWindow(nsIXULBrowserWindow * aXULBrowserWindow)
    2065                 : {
    2066               0 :   mXULBrowserWindow = aXULBrowserWindow;
    2067               0 :   return NS_OK;
    2068                 : }
    2069                 : 
    2070                 : //*****************************************************************************
    2071                 : // nsXULWindow: Accessors
    2072                 : //*****************************************************************************
    2073                 : 
    2074               0 : PRUint32 nsXULWindow::AppUnitsPerDevPixel()
    2075                 : {
    2076               0 :   if (mWindow && mWindow->GetDeviceContext()) {
    2077               0 :     mAppPerDev = mWindow->GetDeviceContext()->AppUnitsPerDevPixel();
    2078                 :   } else {
    2079                 :     NS_ERROR("nsXULWindow::AppUnitsPerDevPixel called with no window "
    2080               0 :              "or no dev context");
    2081                 :   }
    2082               0 :   return mAppPerDev;
    2083                 : }
    2084                 : 
    2085                 : //*****************************************************************************
    2086                 : //*** nsContentShellInfo: Object Management
    2087                 : //*****************************************************************************   
    2088                 : 
    2089               0 : nsContentShellInfo::nsContentShellInfo(const nsAString& aID,
    2090                 :                                        nsIWeakReference* aContentShell)
    2091                 :   : id(aID),
    2092               0 :     child(aContentShell)
    2093                 : {
    2094               0 :   MOZ_COUNT_CTOR(nsContentShellInfo);
    2095               0 : }
    2096                 : 
    2097               0 : nsContentShellInfo::~nsContentShellInfo()
    2098                 : {
    2099               0 :   MOZ_COUNT_DTOR(nsContentShellInfo);
    2100                 :    //XXX Set Tree Owner to null if the tree owner is nsXULWindow->mContentTreeOwner
    2101               0 : } 

Generated by: LCOV version 1.7