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 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/MathAlgorithms.h"
10 #include "nsXULWindow.h"
14 #include "nsPrintfCString.h"
16 #include "nsWidgetsCID.h"
18 #include "nsThreadUtils.h"
21 //Interfaces needed to be included
22 #include "nsIAppShell.h"
23 #include "nsIAppShellService.h"
24 #include "nsIServiceManager.h"
25 #include "nsIContentViewer.h"
26 #include "nsIDocument.h"
27 #include "nsIDOMDocument.h"
28 #include "nsIDOMXULDocument.h"
29 #include "nsIDOMElement.h"
30 #include "nsIDOMXULElement.h"
31 #include "nsPIDOMWindow.h"
32 #include "nsIDOMScreen.h"
33 #include "nsIEmbeddingSiteWindow.h"
34 #include "nsIInterfaceRequestor.h"
35 #include "nsIInterfaceRequestorUtils.h"
36 #include "nsIIOService.h"
37 #include "nsIObserverService.h"
38 #include "nsIWindowMediator.h"
39 #include "nsIScreenManager.h"
40 #include "nsIScreen.h"
41 #include "nsIScrollable.h"
42 #include "nsIScriptSecurityManager.h"
43 #include "nsIWindowWatcher.h"
45 #include "nsIDOMCSSStyleDeclaration.h"
46 #include "nsAppShellCID.h"
47 #include "nsReadableUtils.h"
48 #include "nsStyleConsts.h"
49 #include "nsPresContext.h"
50 #include "nsContentUtils.h"
51 #include "nsWebShellWindow.h" // get rid of this one, too...
52 #include "nsGlobalWindow.h"
55 #include "mozilla/AutoRestore.h"
56 #include "mozilla/Preferences.h"
57 #include "mozilla/dom/BarProps.h"
58 #include "mozilla/dom/Element.h"
59 #include "mozilla/dom/Event.h"
60 #include "mozilla/dom/ScriptSettings.h"
62 using namespace mozilla
;
63 using dom::AutoNoJSAPI
;
65 #define SIZEMODE_NORMAL NS_LITERAL_STRING("normal")
66 #define SIZEMODE_MAXIMIZED NS_LITERAL_STRING("maximized")
67 #define SIZEMODE_MINIMIZED NS_LITERAL_STRING("minimized")
68 #define SIZEMODE_FULLSCREEN NS_LITERAL_STRING("fullscreen")
70 #define WINDOWTYPE_ATTRIBUTE NS_LITERAL_STRING("windowtype")
72 #define PERSIST_ATTRIBUTE NS_LITERAL_STRING("persist")
73 #define SCREENX_ATTRIBUTE NS_LITERAL_STRING("screenX")
74 #define SCREENY_ATTRIBUTE NS_LITERAL_STRING("screenY")
75 #define WIDTH_ATTRIBUTE NS_LITERAL_STRING("width")
76 #define HEIGHT_ATTRIBUTE NS_LITERAL_STRING("height")
77 #define MODE_ATTRIBUTE NS_LITERAL_STRING("sizemode")
78 #define ZLEVEL_ATTRIBUTE NS_LITERAL_STRING("zlevel")
81 //*****************************************************************************
82 //*** nsXULWindow: Object Management
83 //*****************************************************************************
85 nsXULWindow::nsXULWindow(uint32_t aChromeFlags
)
86 : mChromeTreeOwner(nullptr),
87 mContentTreeOwner(nullptr),
88 mPrimaryContentTreeOwner(nullptr),
90 mContinueModalLoop(false),
93 mShowAfterLoad(false),
94 mIntrinsicallySized(false),
95 mCenterAfterLoad(false),
96 mIsHiddenWindow(false),
97 mLockedUntilChromeLoad(false),
98 mIgnoreXULSize(false),
99 mIgnoreXULPosition(false),
100 mChromeFlagsFrozen(false),
101 mIgnoreXULSizeMode(false),
104 mPersistentAttributesDirty(0),
105 mPersistentAttributesMask(0),
106 mChromeFlags(aChromeFlags
)
110 nsXULWindow::~nsXULWindow()
115 //*****************************************************************************
116 // nsXULWindow::nsISupports
117 //*****************************************************************************
119 NS_IMPL_ADDREF(nsXULWindow
)
120 NS_IMPL_RELEASE(nsXULWindow
)
122 NS_INTERFACE_MAP_BEGIN(nsXULWindow
)
123 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIXULWindow
)
124 NS_INTERFACE_MAP_ENTRY(nsIXULWindow
)
125 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow
)
126 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor
)
127 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference
)
128 if (aIID
.Equals(NS_GET_IID(nsXULWindow
)))
129 foundInterface
= reinterpret_cast<nsISupports
*>(this);
133 //*****************************************************************************
134 // nsXULWindow::nsIIntefaceRequestor
135 //*****************************************************************************
137 NS_IMETHODIMP
nsXULWindow::GetInterface(const nsIID
& aIID
, void** aSink
)
141 NS_ENSURE_ARG_POINTER(aSink
);
143 if (aIID
.Equals(NS_GET_IID(nsIPrompt
))) {
144 rv
= EnsurePrompter();
145 if (NS_FAILED(rv
)) return rv
;
146 return mPrompter
->QueryInterface(aIID
, aSink
);
148 if (aIID
.Equals(NS_GET_IID(nsIAuthPrompt
))) {
149 rv
= EnsureAuthPrompter();
150 if (NS_FAILED(rv
)) return rv
;
151 return mAuthPrompter
->QueryInterface(aIID
, aSink
);
153 if (aIID
.Equals(NS_GET_IID(nsIDOMWindow
))) {
154 return GetWindowDOMWindow(reinterpret_cast<nsIDOMWindow
**>(aSink
));
156 if (aIID
.Equals(NS_GET_IID(nsIDOMWindowInternal
))) {
157 nsIDOMWindow
* domWindow
= nullptr;
158 rv
= GetWindowDOMWindow(&domWindow
);
159 nsIDOMWindowInternal
* domWindowInternal
=
160 static_cast<nsIDOMWindowInternal
*>(domWindow
);
161 *aSink
= domWindowInternal
;
164 if (aIID
.Equals(NS_GET_IID(nsIWebBrowserChrome
)) &&
165 NS_SUCCEEDED(EnsureContentTreeOwner()) &&
166 NS_SUCCEEDED(mContentTreeOwner
->QueryInterface(aIID
, aSink
)))
169 if (aIID
.Equals(NS_GET_IID(nsIEmbeddingSiteWindow
)) &&
170 NS_SUCCEEDED(EnsureContentTreeOwner()) &&
171 NS_SUCCEEDED(mContentTreeOwner
->QueryInterface(aIID
, aSink
)))
174 return QueryInterface(aIID
, aSink
);
177 //*****************************************************************************
178 // nsXULWindow::nsIXULWindow
179 //*****************************************************************************
181 NS_IMETHODIMP
nsXULWindow::GetDocShell(nsIDocShell
** aDocShell
)
183 NS_ENSURE_ARG_POINTER(aDocShell
);
185 *aDocShell
= mDocShell
;
186 NS_IF_ADDREF(*aDocShell
);
190 NS_IMETHODIMP
nsXULWindow::GetZLevel(uint32_t *outLevel
)
192 nsCOMPtr
<nsIWindowMediator
> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
194 mediator
->GetZLevel(this, outLevel
);
200 NS_IMETHODIMP
nsXULWindow::SetZLevel(uint32_t aLevel
)
202 nsCOMPtr
<nsIWindowMediator
> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
204 return NS_ERROR_FAILURE
;
207 mediator
->GetZLevel(this, &zLevel
);
208 if (zLevel
== aLevel
)
211 /* refuse to raise a maximized window above the normal browser level,
212 for fear it could hide newly opened browser windows */
213 if (aLevel
> nsIXULWindow::normalZ
&& mWindow
) {
214 int32_t sizeMode
= mWindow
->SizeMode();
215 if (sizeMode
== nsSizeMode_Maximized
|| sizeMode
== nsSizeMode_Fullscreen
) {
216 return NS_ERROR_FAILURE
;
221 mediator
->SetZLevel(this, aLevel
);
222 PersistentAttributesDirty(PAD_MISC
);
223 SavePersistentAttributes();
225 nsCOMPtr
<nsIContentViewer
> cv
;
226 mDocShell
->GetContentViewer(getter_AddRefs(cv
));
228 nsCOMPtr
<nsIDocument
> doc
= cv
->GetDocument();
231 nsRefPtr
<dom::Event
> event
=
232 doc
->CreateEvent(NS_LITERAL_STRING("Events"),rv
);
234 event
->InitEvent(NS_LITERAL_STRING("windowZLevel"), true, false);
236 event
->SetTrusted(true);
238 bool defaultActionEnabled
;
239 doc
->DispatchEvent(event
, &defaultActionEnabled
);
246 NS_IMETHODIMP
nsXULWindow::GetContextFlags(uint32_t *aContextFlags
)
248 NS_ENSURE_ARG_POINTER(aContextFlags
);
249 *aContextFlags
= mContextFlags
;
253 NS_IMETHODIMP
nsXULWindow::SetContextFlags(uint32_t aContextFlags
)
255 mContextFlags
= aContextFlags
;
259 NS_IMETHODIMP
nsXULWindow::GetChromeFlags(uint32_t *aChromeFlags
)
261 NS_ENSURE_ARG_POINTER(aChromeFlags
);
262 *aChromeFlags
= mChromeFlags
;
263 /* mChromeFlags is kept up to date, except for scrollbar visibility.
264 That can be changed directly by the content DOM window, which
265 doesn't know to update the chrome window. So that we must check
268 // however, it's pointless to ask if the window isn't set up yet
272 if (GetContentScrollbarVisibility())
273 *aChromeFlags
|= nsIWebBrowserChrome::CHROME_SCROLLBARS
;
275 *aChromeFlags
&= ~nsIWebBrowserChrome::CHROME_SCROLLBARS
;
280 NS_IMETHODIMP
nsXULWindow::SetChromeFlags(uint32_t aChromeFlags
)
282 NS_ASSERTION(!mChromeFlagsFrozen
,
283 "SetChromeFlags() after AssumeChromeFlagsAreFrozen()!");
285 mChromeFlags
= aChromeFlags
;
287 NS_ENSURE_SUCCESS(ApplyChromeFlags(), NS_ERROR_FAILURE
);
291 NS_IMETHODIMP
nsXULWindow::AssumeChromeFlagsAreFrozen()
293 mChromeFlagsFrozen
= true;
297 NS_IMETHODIMP
nsXULWindow::SetIntrinsicallySized(bool aIntrinsicallySized
)
299 mIntrinsicallySized
= aIntrinsicallySized
;
303 NS_IMETHODIMP
nsXULWindow::GetIntrinsicallySized(bool* aIntrinsicallySized
)
305 NS_ENSURE_ARG_POINTER(aIntrinsicallySized
);
307 *aIntrinsicallySized
= mIntrinsicallySized
;
311 NS_IMETHODIMP
nsXULWindow::GetPrimaryContentShell(nsIDocShellTreeItem
**
314 NS_ENSURE_ARG_POINTER(aDocShellTreeItem
);
315 NS_IF_ADDREF(*aDocShellTreeItem
= mPrimaryContentShell
);
319 NS_IMETHODIMP
nsXULWindow::GetContentShellById(const char16_t
* aID
,
320 nsIDocShellTreeItem
** aDocShellTreeItem
)
322 NS_ENSURE_ARG_POINTER(aDocShellTreeItem
);
323 *aDocShellTreeItem
= nullptr;
325 uint32_t count
= mContentShells
.Length();
326 for (uint32_t i
= 0; i
< count
; i
++) {
327 nsContentShellInfo
* shellInfo
= mContentShells
.ElementAt(i
);
328 if (shellInfo
->id
.Equals(aID
)) {
329 *aDocShellTreeItem
= nullptr;
330 if (shellInfo
->child
)
331 CallQueryReferent(shellInfo
->child
.get(), aDocShellTreeItem
);
335 return NS_ERROR_FAILURE
;
338 NS_IMETHODIMP
nsXULWindow::AddChildWindow(nsIXULWindow
*aChild
)
340 // we're not really keeping track of this right now
344 NS_IMETHODIMP
nsXULWindow::RemoveChildWindow(nsIXULWindow
*aChild
)
346 // we're not really keeping track of this right now
350 NS_IMETHODIMP
nsXULWindow::ShowModal()
352 // Store locally so it doesn't die on us
353 nsCOMPtr
<nsIWidget
> window
= mWindow
;
354 nsCOMPtr
<nsIXULWindow
> tempRef
= this;
356 window
->SetModal(true);
357 mContinueModalLoop
= true;
362 nsIThread
*thread
= NS_GetCurrentThread();
363 while (mContinueModalLoop
) {
364 if (!NS_ProcessNextEvent(thread
))
369 mContinueModalLoop
= false;
370 window
->SetModal(false);
371 /* Note there's no EnableParent(true) here to match the false one
372 above. That's done in ExitModalLoop. It's important that the parent
373 be re-enabled before this window is made invisible; to do otherwise
374 causes bizarre z-ordering problems. At this point, the window is
376 No known current implementation of Enable would have a problem with
377 re-enabling the parent twice, so we could do it again here without
378 breaking any current implementation. But that's unnecessary if the
379 modal loop is always exited using ExitModalLoop (the other way would be
380 to change the protected member variable directly.)
386 //*****************************************************************************
387 // nsXULWindow::nsIBaseWindow
388 //*****************************************************************************
390 NS_IMETHODIMP
nsXULWindow::InitWindow(nativeWindow aParentNativeWindow
,
391 nsIWidget
* parentWidget
, int32_t x
, int32_t y
, int32_t cx
, int32_t cy
)
394 NS_ASSERTION(false, "Not Yet Implemented");
398 NS_IMETHODIMP
nsXULWindow::Create()
401 NS_ASSERTION(false, "Not Yet Implemented");
405 NS_IMETHODIMP
nsXULWindow::Destroy()
410 // Ensure we don't reenter this code
414 mozilla::AutoRestore
<bool> guard(mDestroying
);
417 nsCOMPtr
<nsIAppShellService
> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID
));
418 NS_ASSERTION(appShell
, "Couldn't get appShell... xpcom shutdown?");
420 appShell
->UnregisterTopLevelWindow(static_cast<nsIXULWindow
*>(this));
422 nsCOMPtr
<nsIXULWindow
> parentWindow(do_QueryReferent(mParentWindow
));
424 parentWindow
->RemoveChildWindow(this);
426 // let's make sure the window doesn't get deleted out from under us
427 // while we are trying to close....this can happen if the docshell
428 // we close ends up being the last owning reference to this xulwindow
430 // XXXTAB This shouldn't be an issue anymore because the ownership model
431 // only goes in one direction. When webshell container is fully removed
432 // try removing this...
434 nsCOMPtr
<nsIXULWindow
> placeHolder
= this;
436 // Remove modality (if any) and hide while destroying. More than
437 // a convenience, the hide prevents user interaction with the partially
438 // destroyed window. This is especially necessary when the eldest window
439 // in a stack of modal windows is destroyed first. It happens.
440 ExitModalLoop(NS_OK
);
442 mWindow
->Show(false);
445 // We need to explicitly set the focus on Windows, but
446 // only if the parent is visible.
447 nsCOMPtr
<nsIBaseWindow
> parent(do_QueryReferent(mParentWindow
));
449 nsCOMPtr
<nsIWidget
> parentWidget
;
450 parent
->GetMainWidget(getter_AddRefs(parentWidget
));
451 if (!parentWidget
|| parentWidget
->IsVisible()) {
452 nsCOMPtr
<nsIBaseWindow
> baseHiddenWindow
;
454 nsCOMPtr
<nsIXULWindow
> hiddenWindow
;
455 appShell
->GetHiddenWindow(getter_AddRefs(hiddenWindow
));
457 baseHiddenWindow
= do_GetInterface(hiddenWindow
);
459 // somebody screwed up somewhere. hiddenwindow shouldn't be anybody's
460 // parent. still, when it happens, skip activating it.
461 if (baseHiddenWindow
!= parent
) {
462 nsCOMPtr
<nsIWidget
> parentWidget
;
463 parent
->GetMainWidget(getter_AddRefs(parentWidget
));
465 parentWidget
->PlaceBehind(eZPlacementTop
, 0, true);
471 mDOMWindow
= nullptr;
473 nsCOMPtr
<nsIBaseWindow
> shellAsWin(do_QueryInterface(mDocShell
));
474 shellAsWin
->Destroy();
475 mDocShell
= nullptr; // this can cause reentrancy of this function
478 // Remove our ref on the content shells
479 uint32_t count
= mContentShells
.Length();
480 for (uint32_t i
= 0; i
< count
; i
++) {
481 nsContentShellInfo
* shellInfo
= mContentShells
.ElementAt(i
);
484 mContentShells
.Clear();
485 mPrimaryContentShell
= nullptr;
487 if (mContentTreeOwner
) {
488 mContentTreeOwner
->XULWindow(nullptr);
489 NS_RELEASE(mContentTreeOwner
);
491 if (mPrimaryContentTreeOwner
) {
492 mPrimaryContentTreeOwner
->XULWindow(nullptr);
493 NS_RELEASE(mPrimaryContentTreeOwner
);
495 if (mChromeTreeOwner
) {
496 mChromeTreeOwner
->XULWindow(nullptr);
497 NS_RELEASE(mChromeTreeOwner
);
500 mWindow
->SetWidgetListener(nullptr); // nsWebShellWindow hackery
505 if (!mIsHiddenWindow
) {
506 /* Inform appstartup we've destroyed this window and it could
507 quit now if it wanted. This must happen at least after mDocShell
508 is destroyed, because onunload handlers fire then, and those being
509 script, anything could happen. A new window could open, even.
511 nsCOMPtr
<nsIObserverService
> obssvc
=
512 do_GetService("@mozilla.org/observer-service;1");
513 NS_ASSERTION(obssvc
, "Couldn't get observer service?");
516 obssvc
->NotifyObservers(nullptr, "xul-window-destroyed", nullptr);
522 NS_IMETHODIMP
nsXULWindow::GetUnscaledDevicePixelsPerCSSPixel(double *aScale
)
524 *aScale
= mWindow
? mWindow
->GetDefaultScale().scale
: 1.0;
528 NS_IMETHODIMP
nsXULWindow::SetPosition(int32_t aX
, int32_t aY
)
530 // Don't reset the window's size mode here - platforms that don't want to move
531 // maximized windows should reset it in their respective Move implementation.
532 CSSToLayoutDeviceScale scale
= mWindow
->GetDefaultScale();
533 double invScale
= 1.0 / scale
.scale
;
534 nsresult rv
= mWindow
->Move(aX
* invScale
, aY
* invScale
);
535 NS_ENSURE_SUCCESS(rv
, NS_ERROR_FAILURE
);
536 if (!mChromeLoaded
) {
537 // If we're called before the chrome is loaded someone obviously wants this
538 // window at this position. We don't persist this one-time position.
539 mIgnoreXULPosition
= true;
542 PersistentAttributesDirty(PAD_POSITION
);
543 SavePersistentAttributes();
547 NS_IMETHODIMP
nsXULWindow::GetPosition(int32_t* aX
, int32_t* aY
)
549 return GetPositionAndSize(aX
, aY
, nullptr, nullptr);
552 NS_IMETHODIMP
nsXULWindow::SetSize(int32_t aCX
, int32_t aCY
, bool aRepaint
)
554 /* any attempt to set the window's size or position overrides the window's
555 zoom state. this is important when these two states are competing while
556 the window is being opened. but it should probably just always be so. */
557 mWindow
->SetSizeMode(nsSizeMode_Normal
);
559 mIntrinsicallySized
= false;
561 CSSToLayoutDeviceScale scale
= mWindow
->GetDefaultScale();
562 double invScale
= 1.0 / scale
.scale
;
563 nsresult rv
= mWindow
->Resize(aCX
* invScale
, aCY
* invScale
, aRepaint
);
564 NS_ENSURE_SUCCESS(rv
, NS_ERROR_FAILURE
);
565 if (!mChromeLoaded
) {
566 // If we're called before the chrome is loaded someone obviously wants this
567 // window at this size & in the normal size mode (since it is the only mode
568 // in which setting dimensions makes sense). We don't persist this one-time
570 mIgnoreXULSize
= true;
571 mIgnoreXULSizeMode
= true;
574 PersistentAttributesDirty(PAD_SIZE
);
575 SavePersistentAttributes();
579 NS_IMETHODIMP
nsXULWindow::GetSize(int32_t* aCX
, int32_t* aCY
)
581 return GetPositionAndSize(nullptr, nullptr, aCX
, aCY
);
584 NS_IMETHODIMP
nsXULWindow::SetPositionAndSize(int32_t aX
, int32_t aY
,
585 int32_t aCX
, int32_t aCY
, bool aRepaint
)
587 /* any attempt to set the window's size or position overrides the window's
588 zoom state. this is important when these two states are competing while
589 the window is being opened. but it should probably just always be so. */
590 mWindow
->SetSizeMode(nsSizeMode_Normal
);
592 mIntrinsicallySized
= false;
594 CSSToLayoutDeviceScale scale
= mWindow
->GetDefaultScale();
595 double invScale
= 1.0 / scale
.scale
;
596 nsresult rv
= mWindow
->Resize(aX
* invScale
, aY
* invScale
,
597 aCX
* invScale
, aCY
* invScale
,
599 NS_ENSURE_SUCCESS(rv
, NS_ERROR_FAILURE
);
600 if (!mChromeLoaded
) {
601 // If we're called before the chrome is loaded someone obviously wants this
602 // window at this size and position. We don't persist this one-time setting.
603 mIgnoreXULPosition
= true;
604 mIgnoreXULSize
= true;
605 mIgnoreXULSizeMode
= true;
608 PersistentAttributesDirty(PAD_POSITION
| PAD_SIZE
);
609 SavePersistentAttributes();
613 NS_IMETHODIMP
nsXULWindow::GetPositionAndSize(int32_t* x
, int32_t* y
, int32_t* cx
,
619 return NS_ERROR_FAILURE
;
621 mWindow
->GetScreenBounds(rect
);
635 NS_IMETHODIMP
nsXULWindow::Center(nsIXULWindow
*aRelative
, bool aScreen
, bool aAlert
)
637 int32_t left
, top
, width
, height
,
639 bool screenCoordinates
= false,
640 windowCoordinates
= false;
643 if (!mChromeLoaded
) {
644 // note we lose the parameters. at time of writing, this isn't a problem.
645 mCenterAfterLoad
= true;
649 if (!aScreen
&& !aRelative
)
650 return NS_ERROR_INVALID_ARG
;
652 nsCOMPtr
<nsIScreenManager
> screenmgr
= do_GetService("@mozilla.org/gfx/screenmanager;1", &result
);
653 if (NS_FAILED(result
))
656 nsCOMPtr
<nsIScreen
> screen
;
659 nsCOMPtr
<nsIBaseWindow
> base(do_QueryInterface(aRelative
, &result
));
662 result
= base
->GetPositionAndSize(&left
, &top
, &width
, &height
);
663 if (NS_SUCCEEDED(result
)) {
665 if (NS_SUCCEEDED(base
->GetUnscaledDevicePixelsPerCSSPixel(&scale
))) {
666 // convert device-pixel coordinates to global display pixels
667 left
= NSToIntRound(left
/ scale
);
668 top
= NSToIntRound(top
/ scale
);
669 width
= NSToIntRound(width
/ scale
);
670 height
= NSToIntRound(height
/ scale
);
672 // if centering on screen, convert that to the corresponding screen
674 screenmgr
->ScreenForRect(left
, top
, width
, height
, getter_AddRefs(screen
));
676 windowCoordinates
= true;
678 // something's wrong with the reference window.
679 // fall back to the primary screen
686 if (!mOpenerScreenRect
.IsEmpty()) {
687 // FIXME - check if these are device or display pixels
688 screenmgr
->ScreenForRect(mOpenerScreenRect
.x
, mOpenerScreenRect
.y
,
689 mOpenerScreenRect
.width
, mOpenerScreenRect
.height
,
690 getter_AddRefs(screen
));
692 screenmgr
->GetPrimaryScreen(getter_AddRefs(screen
));
696 if (aScreen
&& screen
) {
697 screen
->GetAvailRectDisplayPix(&left
, &top
, &width
, &height
);
698 screenCoordinates
= true;
701 if (screenCoordinates
|| windowCoordinates
) {
702 NS_ASSERTION(mWindow
, "what, no window?");
703 CSSToLayoutDeviceScale scale
= mWindow
->GetDefaultScale();
704 GetSize(&ourWidth
, &ourHeight
);
705 ourWidth
= NSToIntRound(ourWidth
/ scale
.scale
);
706 ourHeight
= NSToIntRound(ourHeight
/ scale
.scale
);
707 left
+= (width
- ourWidth
) / 2;
708 top
+= (height
- ourHeight
) / (aAlert
? 3 : 2);
709 if (windowCoordinates
) {
710 mWindow
->ConstrainPosition(false, &left
, &top
);
712 SetPosition(left
* scale
.scale
, top
* scale
.scale
);
715 return NS_ERROR_FAILURE
;
718 NS_IMETHODIMP
nsXULWindow::Repaint(bool aForce
)
721 NS_ASSERTION(false, "Not Yet Implemented");
725 NS_IMETHODIMP
nsXULWindow::GetParentWidget(nsIWidget
** aParentWidget
)
727 NS_ENSURE_ARG_POINTER(aParentWidget
);
728 NS_ENSURE_STATE(mWindow
);
730 NS_IF_ADDREF(*aParentWidget
= mWindow
->GetParent());
734 NS_IMETHODIMP
nsXULWindow::SetParentWidget(nsIWidget
* aParentWidget
)
737 NS_ASSERTION(false, "Not Yet Implemented");
741 NS_IMETHODIMP
nsXULWindow::GetParentNativeWindow(nativeWindow
* aParentNativeWindow
)
743 NS_ENSURE_ARG_POINTER(aParentNativeWindow
);
745 nsCOMPtr
<nsIWidget
> parentWidget
;
746 NS_ENSURE_SUCCESS(GetParentWidget(getter_AddRefs(parentWidget
)), NS_ERROR_FAILURE
);
749 *aParentNativeWindow
= parentWidget
->GetNativeData(NS_NATIVE_WIDGET
);
755 NS_IMETHODIMP
nsXULWindow::SetParentNativeWindow(nativeWindow aParentNativeWindow
)
758 NS_ASSERTION(false, "Not Yet Implemented");
762 NS_IMETHODIMP
nsXULWindow::GetNativeHandle(nsAString
& aNativeHandle
)
764 nsCOMPtr
<nsIWidget
> mainWidget
;
765 NS_ENSURE_SUCCESS(GetMainWidget(getter_AddRefs(mainWidget
)), NS_ERROR_FAILURE
);
768 nativeWindow nativeWindowPtr
= mainWidget
->GetNativeData(NS_NATIVE_WINDOW
);
769 /* the nativeWindow pointer is converted to and exposed as a string. This
770 is a more reliable way not to lose information (as opposed to JS
771 |Number| for instance) */
772 aNativeHandle
= NS_ConvertASCIItoUTF16(nsPrintfCString("0x%p", nativeWindowPtr
));
778 NS_IMETHODIMP
nsXULWindow::GetVisibility(bool* aVisibility
)
780 NS_ENSURE_ARG_POINTER(aVisibility
);
782 // Always claim to be visible for now. See bug
783 // https://bugzilla.mozilla.org/show_bug.cgi?id=306245.
790 NS_IMETHODIMP
nsXULWindow::SetVisibility(bool aVisibility
)
792 if (!mChromeLoaded
) {
793 mShowAfterLoad
= aVisibility
;
800 mDebuting
= true; // (Show / Focus is recursive)
802 //XXXTAB Do we really need to show docshell and the window? Isn't
803 // the window good enough?
804 nsCOMPtr
<nsIBaseWindow
> shellAsWin(do_QueryInterface(mDocShell
));
805 shellAsWin
->SetVisibility(aVisibility
);
806 // Store locally so it doesn't die on us. 'Show' can result in the window
807 // being closed with nsXULWindow::Destroy being called. That would set
808 // mWindow to null and posibly destroy the nsIWidget while its Show method
809 // is on the stack. We need to keep it alive until Show finishes.
810 nsCOMPtr
<nsIWidget
> window
= mWindow
;
811 window
->Show(aVisibility
);
813 nsCOMPtr
<nsIWindowMediator
> windowMediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
815 windowMediator
->UpdateWindowTimeStamp(static_cast<nsIXULWindow
*>(this));
817 // notify observers so that we can hide the splash screen if possible
818 nsCOMPtr
<nsIObserverService
> obssvc
819 (do_GetService("@mozilla.org/observer-service;1"));
820 NS_ASSERTION(obssvc
, "Couldn't get observer service.");
822 obssvc
->NotifyObservers(nullptr, "xul-window-visible", nullptr);
829 NS_IMETHODIMP
nsXULWindow::GetEnabled(bool *aEnabled
)
831 NS_ENSURE_ARG_POINTER(aEnabled
);
834 *aEnabled
= mWindow
->IsEnabled();
838 *aEnabled
= true; // better guess than most
839 return NS_ERROR_FAILURE
;
842 NS_IMETHODIMP
nsXULWindow::SetEnabled(bool aEnable
)
845 mWindow
->Enable(aEnable
);
848 return NS_ERROR_FAILURE
;
851 NS_IMETHODIMP
nsXULWindow::GetMainWidget(nsIWidget
** aMainWidget
)
853 NS_ENSURE_ARG_POINTER(aMainWidget
);
855 *aMainWidget
= mWindow
;
856 NS_IF_ADDREF(*aMainWidget
);
860 NS_IMETHODIMP
nsXULWindow::SetFocus()
863 NS_ASSERTION(false, "Not Yet Implemented");
867 NS_IMETHODIMP
nsXULWindow::GetTitle(char16_t
** aTitle
)
869 NS_ENSURE_ARG_POINTER(aTitle
);
871 *aTitle
= ToNewUnicode(mTitle
);
873 return NS_ERROR_OUT_OF_MEMORY
;
877 NS_IMETHODIMP
nsXULWindow::SetTitle(const char16_t
* aTitle
)
879 NS_ENSURE_STATE(mWindow
);
880 mTitle
.Assign(aTitle
);
881 mTitle
.StripChars("\n\r");
882 NS_ENSURE_SUCCESS(mWindow
->SetTitle(mTitle
), NS_ERROR_FAILURE
);
884 // Tell the window mediator that a title has changed
885 nsCOMPtr
<nsIWindowMediator
> windowMediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
889 windowMediator
->UpdateWindowTitle(static_cast<nsIXULWindow
*>(this), aTitle
);
895 //*****************************************************************************
896 // nsXULWindow: Helpers
897 //*****************************************************************************
899 NS_IMETHODIMP
nsXULWindow::EnsureChromeTreeOwner()
901 if (mChromeTreeOwner
)
904 mChromeTreeOwner
= new nsChromeTreeOwner();
905 NS_ENSURE_TRUE(mChromeTreeOwner
, NS_ERROR_OUT_OF_MEMORY
);
907 NS_ADDREF(mChromeTreeOwner
);
908 mChromeTreeOwner
->XULWindow(this);
913 NS_IMETHODIMP
nsXULWindow::EnsureContentTreeOwner()
915 if (mContentTreeOwner
)
918 mContentTreeOwner
= new nsContentTreeOwner(false);
919 NS_ENSURE_TRUE(mContentTreeOwner
, NS_ERROR_FAILURE
);
921 NS_ADDREF(mContentTreeOwner
);
922 mContentTreeOwner
->XULWindow(this);
927 NS_IMETHODIMP
nsXULWindow::EnsurePrimaryContentTreeOwner()
929 if (mPrimaryContentTreeOwner
)
932 mPrimaryContentTreeOwner
= new nsContentTreeOwner(true);
933 NS_ENSURE_TRUE(mPrimaryContentTreeOwner
, NS_ERROR_FAILURE
);
935 NS_ADDREF(mPrimaryContentTreeOwner
);
936 mPrimaryContentTreeOwner
->XULWindow(this);
941 NS_IMETHODIMP
nsXULWindow::EnsurePrompter()
946 nsCOMPtr
<nsIDOMWindow
> ourWindow
;
947 nsresult rv
= GetWindowDOMWindow(getter_AddRefs(ourWindow
));
948 if (NS_SUCCEEDED(rv
)) {
949 nsCOMPtr
<nsIWindowWatcher
> wwatch
=
950 do_GetService(NS_WINDOWWATCHER_CONTRACTID
);
952 wwatch
->GetNewPrompter(ourWindow
, getter_AddRefs(mPrompter
));
954 return mPrompter
? NS_OK
: NS_ERROR_FAILURE
;
957 NS_IMETHODIMP
nsXULWindow::EnsureAuthPrompter()
962 nsCOMPtr
<nsIDOMWindow
> ourWindow
;
963 nsresult rv
= GetWindowDOMWindow(getter_AddRefs(ourWindow
));
964 if (NS_SUCCEEDED(rv
)) {
965 nsCOMPtr
<nsIWindowWatcher
> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID
));
967 wwatch
->GetNewAuthPrompter(ourWindow
, getter_AddRefs(mAuthPrompter
));
969 return mAuthPrompter
? NS_OK
: NS_ERROR_FAILURE
;
972 void nsXULWindow::OnChromeLoaded()
974 nsresult rv
= EnsureContentTreeOwner();
976 if (NS_SUCCEEDED(rv
)) {
977 mChromeLoaded
= true;
979 SyncAttributesToWidget();
982 if (mIntrinsicallySized
) {
983 // (if LoadSizeFromXUL set the size, mIntrinsicallySized will be false)
984 nsCOMPtr
<nsIContentViewer
> cv
;
985 mDocShell
->GetContentViewer(getter_AddRefs(cv
));
987 nsCOMPtr
<nsIDocShellTreeItem
> docShellAsItem
= do_QueryInterface(mDocShell
);
988 nsCOMPtr
<nsIDocShellTreeOwner
> treeOwner
;
989 docShellAsItem
->GetTreeOwner(getter_AddRefs(treeOwner
));
991 int32_t width
, height
;
992 cv
->GetContentSize(&width
, &height
);
993 treeOwner
->SizeShellTo(docShellAsItem
, width
, height
);
998 bool positionSet
= !mIgnoreXULPosition
;
999 nsCOMPtr
<nsIXULWindow
> parentWindow(do_QueryReferent(mParentWindow
));
1000 #if defined(XP_UNIX) && !defined(XP_MACOSX)
1001 // don't override WM placement on unix for independent, top-level windows
1002 // (however, we think the benefits of intelligent dependent window placement
1003 // trump that override.)
1005 positionSet
= false;
1008 positionSet
= LoadPositionFromXUL();
1009 LoadMiscPersistentAttributesFromXUL();
1011 if (mCenterAfterLoad
&& !positionSet
)
1012 Center(parentWindow
, parentWindow
? false : true, false);
1014 if (mShowAfterLoad
) {
1015 SetVisibility(true);
1016 // At this point the window may have been closed during Show(), so
1017 // nsXULWindow::Destroy may already have been called. Take care!
1020 mPersistentAttributesMask
|= PAD_POSITION
| PAD_SIZE
| PAD_MISC
;
1023 bool nsXULWindow::LoadPositionFromXUL()
1025 bool gotPosition
= false;
1027 // if we're the hidden window, don't try to validate our size/position. We're
1029 if (mIsHiddenWindow
)
1032 nsCOMPtr
<dom::Element
> windowElement
= GetWindowDOMElement();
1033 NS_ENSURE_TRUE(windowElement
, false);
1037 int32_t currWidth
= 0;
1038 int32_t currHeight
= 0;
1042 GetPositionAndSize(&currX
, &currY
, &currWidth
, &currHeight
);
1044 // Convert to global display pixels for consistent window management across
1045 // screens with diverse resolutions
1046 CSSToLayoutDeviceScale scale
= mWindow
->GetDefaultScale();
1047 currX
= NSToIntRound(currX
/ scale
.scale
);
1048 currY
= NSToIntRound(currY
/ scale
.scale
);
1049 currWidth
= NSToIntRound(currWidth
/ scale
.scale
);
1050 currHeight
= NSToIntRound(currHeight
/ scale
.scale
);
1052 // Obtain the position information from the <xul:window> element.
1053 int32_t specX
= currX
;
1054 int32_t specY
= currY
;
1055 nsAutoString posString
;
1057 windowElement
->GetAttribute(SCREENX_ATTRIBUTE
, posString
);
1058 temp
= posString
.ToInteger(&errorCode
);
1059 if (NS_SUCCEEDED(errorCode
)) {
1063 windowElement
->GetAttribute(SCREENY_ATTRIBUTE
, posString
);
1064 temp
= posString
.ToInteger(&errorCode
);
1065 if (NS_SUCCEEDED(errorCode
)) {
1071 // our position will be relative to our parent, if any
1072 nsCOMPtr
<nsIBaseWindow
> parent(do_QueryReferent(mParentWindow
));
1074 int32_t parentX
, parentY
;
1075 if (NS_SUCCEEDED(parent
->GetPosition(&parentX
, &parentY
))) {
1077 if (NS_SUCCEEDED(parent
->GetUnscaledDevicePixelsPerCSSPixel(&scale
))) {
1078 parentX
= NSToIntRound(parentX
/ scale
);
1079 parentY
= NSToIntRound(parentY
/ scale
);
1086 StaggerPosition(specX
, specY
, currWidth
, currHeight
);
1089 mWindow
->ConstrainPosition(false, &specX
, &specY
);
1090 if (specX
!= currX
|| specY
!= currY
) {
1091 CSSToLayoutDeviceScale scale
= mWindow
->GetDefaultScale();
1092 SetPosition(specX
* scale
.scale
, specY
* scale
.scale
);
1098 bool nsXULWindow::LoadSizeFromXUL()
1100 bool gotSize
= false;
1102 // if we're the hidden window, don't try to validate our size/position. We're
1104 if (mIsHiddenWindow
)
1107 nsCOMPtr
<dom::Element
> windowElement
= GetWindowDOMElement();
1108 NS_ENSURE_TRUE(windowElement
, false);
1110 int32_t currWidth
= 0;
1111 int32_t currHeight
= 0;
1115 NS_ASSERTION(mWindow
, "we expected to have a window already");
1117 CSSToLayoutDeviceScale scale
= mWindow
? mWindow
->GetDefaultScale()
1118 : CSSToLayoutDeviceScale(1.0);
1119 GetSize(&currWidth
, &currHeight
);
1120 currWidth
= NSToIntRound(currWidth
/ scale
.scale
);
1121 currHeight
= NSToIntRound(currHeight
/ scale
.scale
);
1123 // Obtain the position and sizing information from the <xul:window> element.
1124 int32_t specWidth
= currWidth
;
1125 int32_t specHeight
= currHeight
;
1126 nsAutoString sizeString
;
1128 windowElement
->GetAttribute(WIDTH_ATTRIBUTE
, sizeString
);
1129 temp
= sizeString
.ToInteger(&errorCode
);
1130 if (NS_SUCCEEDED(errorCode
) && temp
> 0) {
1131 specWidth
= std::max(temp
, 100);
1134 windowElement
->GetAttribute(HEIGHT_ATTRIBUTE
, sizeString
);
1135 temp
= sizeString
.ToInteger(&errorCode
);
1136 if (NS_SUCCEEDED(errorCode
) && temp
> 0) {
1137 specHeight
= std::max(temp
, 100);
1142 // constrain to screen size
1143 nsCOMPtr
<nsIDOMWindow
> domWindow
;
1144 GetWindowDOMWindow(getter_AddRefs(domWindow
));
1146 nsCOMPtr
<nsIDOMScreen
> screen
;
1147 domWindow
->GetScreen(getter_AddRefs(screen
));
1149 int32_t screenWidth
;
1150 int32_t screenHeight
;
1151 screen
->GetAvailWidth(&screenWidth
);
1152 screen
->GetAvailHeight(&screenHeight
);
1153 if (specWidth
> screenWidth
)
1154 specWidth
= screenWidth
;
1155 if (specHeight
> screenHeight
)
1156 specHeight
= screenHeight
;
1160 mIntrinsicallySized
= false;
1161 if (specWidth
!= currWidth
|| specHeight
!= currHeight
) {
1162 CSSToLayoutDeviceScale scale
= mWindow
->GetDefaultScale();
1163 SetSize(specWidth
* scale
.scale
, specHeight
* scale
.scale
, false);
1170 /* Miscellaneous persistent attributes are attributes named in the
1171 |persist| attribute, other than size and position. Those are special
1172 because it's important to load those before one of the misc
1173 attributes (sizemode) and they require extra processing. */
1174 bool nsXULWindow::LoadMiscPersistentAttributesFromXUL()
1176 bool gotState
= false;
1178 /* There are no misc attributes of interest to the hidden window.
1179 It's especially important not to try to validate that window's
1180 size or position, because some platforms (Mac OS X) need to
1181 make it visible and offscreen. */
1182 if (mIsHiddenWindow
)
1185 nsCOMPtr
<dom::Element
> windowElement
= GetWindowDOMElement();
1186 NS_ENSURE_TRUE(windowElement
, false);
1188 nsAutoString stateString
;
1191 windowElement
->GetAttribute(MODE_ATTRIBUTE
, stateString
);
1192 int32_t sizeMode
= nsSizeMode_Normal
;
1193 /* ignore request to minimize, to not confuse novices
1194 if (stateString.Equals(SIZEMODE_MINIMIZED))
1195 sizeMode = nsSizeMode_Minimized;
1197 if (!mIgnoreXULSizeMode
&&
1198 (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 if (mChromeFlags
& nsIWebBrowserChrome::CHROME_WINDOW_RESIZE
) {
1203 mIntrinsicallySized
= false;
1205 if (stateString
.Equals(SIZEMODE_MAXIMIZED
))
1206 sizeMode
= nsSizeMode_Maximized
;
1208 sizeMode
= nsSizeMode_Fullscreen
;
1212 // If we are told to ignore the size mode attribute update the
1213 // document so the attribute and window are in sync.
1214 if (mIgnoreXULSizeMode
) {
1215 nsAutoString sizeString
;
1216 if (sizeMode
== nsSizeMode_Maximized
)
1217 sizeString
.Assign(SIZEMODE_MAXIMIZED
);
1218 else if (sizeMode
== nsSizeMode_Fullscreen
)
1219 sizeString
.Assign(SIZEMODE_FULLSCREEN
);
1220 else if (sizeMode
== nsSizeMode_Normal
)
1221 sizeString
.Assign(SIZEMODE_NORMAL
);
1222 if (!sizeString
.IsEmpty()) {
1224 windowElement
->SetAttribute(MODE_ATTRIBUTE
, sizeString
, rv
);
1228 if (sizeMode
== nsSizeMode_Fullscreen
) {
1229 nsCOMPtr
<nsIDOMWindow
> ourWindow
;
1230 GetWindowDOMWindow(getter_AddRefs(ourWindow
));
1231 ourWindow
->SetFullScreen(true);
1233 mWindow
->SetSizeMode(sizeMode
);
1238 windowElement
->GetAttribute(ZLEVEL_ATTRIBUTE
, stateString
);
1239 if (!stateString
.IsEmpty()) {
1241 int32_t zLevel
= stateString
.ToInteger(&errorCode
);
1242 if (NS_SUCCEEDED(errorCode
) && zLevel
>= lowestZ
&& zLevel
<= highestZ
)
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.
1254 void nsXULWindow::StaggerPosition(int32_t &aRequestedX
, int32_t &aRequestedY
,
1255 int32_t aSpecWidth
, int32_t aSpecHeight
)
1257 const int32_t kOffset
= 22;
1258 const uint32_t kSlop
= 4;
1261 int bouncedX
= 0, // bounced off vertical edge of screen
1262 bouncedY
= 0; // bounced off horizontal edge
1264 // look for any other windows of this type
1265 nsCOMPtr
<nsIWindowMediator
> wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
1269 nsCOMPtr
<dom::Element
> windowElement
= GetWindowDOMElement();
1273 nsCOMPtr
<nsIXULWindow
> ourXULWindow(this);
1275 nsAutoString windowType
;
1276 windowElement
->GetAttribute(WINDOWTYPE_ATTRIBUTE
, windowType
);
1278 int32_t screenTop
= 0, // it's pointless to initialize these ...
1279 screenRight
= 0, // ... but to prevent oversalubrious and ...
1280 screenBottom
= 0, // ... underbright compilers from ...
1281 screenLeft
= 0; // ... issuing warnings.
1282 bool gotScreen
= false;
1284 { // fetch screen coordinates
1285 nsCOMPtr
<nsIScreenManager
> screenMgr(do_GetService(
1286 "@mozilla.org/gfx/screenmanager;1"));
1288 nsCOMPtr
<nsIScreen
> ourScreen
;
1289 // the coordinates here are already display pixels
1290 screenMgr
->ScreenForRect(aRequestedX
, aRequestedY
,
1291 aSpecWidth
, aSpecHeight
,
1292 getter_AddRefs(ourScreen
));
1294 int32_t screenWidth
, screenHeight
;
1295 ourScreen
->GetAvailRectDisplayPix(&screenLeft
, &screenTop
,
1296 &screenWidth
, &screenHeight
);
1297 screenBottom
= screenTop
+ screenHeight
;
1298 screenRight
= screenLeft
+ screenWidth
;
1304 // One full pass through all windows of this type, repeat until no collisions.
1307 nsCOMPtr
<nsISimpleEnumerator
> windowList
;
1308 wm
->GetXULWindowEnumerator(windowType
.get(), getter_AddRefs(windowList
));
1313 // One full pass through all windows of this type, offset and stop on collision.
1316 windowList
->HasMoreElements(&more
);
1320 nsCOMPtr
<nsISupports
> supportsWindow
;
1321 windowList
->GetNext(getter_AddRefs(supportsWindow
));
1323 nsCOMPtr
<nsIXULWindow
> listXULWindow(do_QueryInterface(supportsWindow
));
1324 if (listXULWindow
!= ourXULWindow
) {
1325 int32_t listX
, listY
;
1326 nsCOMPtr
<nsIBaseWindow
> listBaseWindow(do_QueryInterface(supportsWindow
));
1327 listBaseWindow
->GetPosition(&listX
, &listY
);
1329 if (NS_SUCCEEDED(listBaseWindow
->GetUnscaledDevicePixelsPerCSSPixel(&scale
))) {
1330 listX
= NSToIntRound(listX
/ scale
);
1331 listY
= NSToIntRound(listY
/ scale
);
1334 if (Abs(listX
- aRequestedX
) <= kSlop
&& Abs(listY
- aRequestedY
) <= kSlop
) {
1335 // collision! offset and start over
1337 aRequestedX
-= kOffset
;
1339 aRequestedX
+= kOffset
;
1340 aRequestedY
+= kOffset
;
1343 // if we're moving to the right and we need to bounce...
1344 if (!(bouncedX
& 0x1) && ((aRequestedX
+ aSpecWidth
) > screenRight
)) {
1345 aRequestedX
= screenRight
- aSpecWidth
;
1349 // if we're moving to the left and we need to bounce...
1350 if ((bouncedX
& 0x1) && aRequestedX
< screenLeft
) {
1351 aRequestedX
= screenLeft
;
1355 // if we hit the bottom then bounce to the top
1356 if (aRequestedY
+ aSpecHeight
> screenBottom
) {
1357 aRequestedY
= screenTop
;
1362 /* loop around again,
1363 but it's time to give up once we've covered the screen.
1364 there's a potential infinite loop with lots of windows. */
1365 keepTrying
= bouncedX
< 2 || bouncedY
== 0;
1370 } while (keepTrying
);
1373 void nsXULWindow::SyncAttributesToWidget()
1375 nsCOMPtr
<dom::Element
> windowElement
= GetWindowDOMElement();
1381 // "hidechrome" attribute
1382 if (windowElement
->AttrValueIs(kNameSpaceID_None
, nsGkAtoms::hidechrome
,
1383 nsGkAtoms::_true
, eCaseMatters
)) {
1384 mWindow
->HideWindowChrome(true);
1387 // "chromemargin" attribute
1388 nsIntMargin margins
;
1389 windowElement
->GetAttribute(NS_LITERAL_STRING("chromemargin"), attr
);
1390 if (nsContentUtils::ParseIntMarginValue(attr
, margins
)) {
1391 mWindow
->SetNonClientMargins(margins
);
1394 // "accelerated" attribute
1395 bool isAccelerated
= windowElement
->HasAttribute(NS_LITERAL_STRING("accelerated"));
1396 mWindow
->SetLayersAcceleration(isAccelerated
);
1398 // "windowtype" attribute
1399 windowElement
->GetAttribute(WINDOWTYPE_ATTRIBUTE
, attr
);
1400 if (!attr
.IsEmpty()) {
1401 mWindow
->SetWindowClass(attr
);
1404 // "id" attribute for icon
1405 windowElement
->GetAttribute(NS_LITERAL_STRING("id"), attr
);
1406 if (attr
.IsEmpty()) {
1407 attr
.AssignLiteral("default");
1409 mWindow
->SetIcon(attr
);
1411 // "drawtitle" attribute
1412 windowElement
->GetAttribute(NS_LITERAL_STRING("drawtitle"), attr
);
1413 mWindow
->SetDrawsTitle(attr
.LowerCaseEqualsLiteral("true"));
1415 // "toggletoolbar" attribute
1416 windowElement
->GetAttribute(NS_LITERAL_STRING("toggletoolbar"), attr
);
1417 mWindow
->SetShowsToolbarButton(attr
.LowerCaseEqualsLiteral("true"));
1419 // "fullscreenbutton" attribute
1420 windowElement
->GetAttribute(NS_LITERAL_STRING("fullscreenbutton"), attr
);
1421 mWindow
->SetShowsFullScreenButton(attr
.LowerCaseEqualsLiteral("true"));
1423 // "macanimationtype" attribute
1424 windowElement
->GetAttribute(NS_LITERAL_STRING("macanimationtype"), attr
);
1425 if (attr
.EqualsLiteral("document")) {
1426 mWindow
->SetWindowAnimationType(nsIWidget::eDocumentWindowAnimation
);
1430 NS_IMETHODIMP
nsXULWindow::SavePersistentAttributes()
1432 // can happen when the persistence timer fires at an inopportune time
1433 // during window shutdown
1435 return NS_ERROR_FAILURE
;
1437 nsCOMPtr
<dom::Element
> docShellElement
= GetWindowDOMElement();
1438 if (!docShellElement
)
1439 return NS_ERROR_FAILURE
;
1441 nsAutoString persistString
;
1442 docShellElement
->GetAttribute(PERSIST_ATTRIBUTE
, persistString
);
1443 if (persistString
.IsEmpty()) { // quick check which sometimes helps
1444 mPersistentAttributesDirty
= 0;
1448 // get our size, position and mode to persist
1450 bool gotRestoredBounds
= NS_SUCCEEDED(mWindow
->GetRestoredBounds(rect
));
1452 CSSToLayoutDeviceScale scale
= mWindow
->GetDefaultScale();
1454 // make our position relative to our parent, if any
1455 nsCOMPtr
<nsIBaseWindow
> parent(do_QueryReferent(mParentWindow
));
1456 if (parent
&& gotRestoredBounds
) {
1457 int32_t parentX
, parentY
;
1458 if (NS_SUCCEEDED(parent
->GetPosition(&parentX
, &parentY
))) {
1465 nsAutoString sizeString
;
1466 nsAutoString windowElementId
;
1467 nsCOMPtr
<nsIDOMXULDocument
> ownerXULDoc
;
1469 // fetch docShellElement's ID and XUL owner document
1470 ownerXULDoc
= do_QueryInterface(docShellElement
->OwnerDoc());
1471 if (docShellElement
->IsXUL()) {
1472 docShellElement
->GetId(windowElementId
);
1476 // (only for size elements which are persisted)
1477 if ((mPersistentAttributesDirty
& PAD_POSITION
) && gotRestoredBounds
) {
1478 if (persistString
.Find("screenX") >= 0) {
1479 PR_snprintf(sizeBuf
, sizeof(sizeBuf
), "%d", NSToIntRound(rect
.x
/ scale
.scale
));
1480 sizeString
.AssignWithConversion(sizeBuf
);
1481 docShellElement
->SetAttribute(SCREENX_ATTRIBUTE
, sizeString
, rv
);
1482 if (ownerXULDoc
) // force persistence in case the value didn't change
1483 ownerXULDoc
->Persist(windowElementId
, SCREENX_ATTRIBUTE
);
1485 if (persistString
.Find("screenY") >= 0) {
1486 PR_snprintf(sizeBuf
, sizeof(sizeBuf
), "%d", NSToIntRound(rect
.y
/ scale
.scale
));
1487 sizeString
.AssignWithConversion(sizeBuf
);
1488 docShellElement
->SetAttribute(SCREENY_ATTRIBUTE
, sizeString
, rv
);
1490 ownerXULDoc
->Persist(windowElementId
, SCREENY_ATTRIBUTE
);
1494 if ((mPersistentAttributesDirty
& PAD_SIZE
) && gotRestoredBounds
) {
1495 if (persistString
.Find("width") >= 0) {
1496 PR_snprintf(sizeBuf
, sizeof(sizeBuf
), "%d", NSToIntRound(rect
.width
/ scale
.scale
));
1497 sizeString
.AssignWithConversion(sizeBuf
);
1498 docShellElement
->SetAttribute(WIDTH_ATTRIBUTE
, sizeString
, rv
);
1500 ownerXULDoc
->Persist(windowElementId
, WIDTH_ATTRIBUTE
);
1502 if (persistString
.Find("height") >= 0) {
1503 PR_snprintf(sizeBuf
, sizeof(sizeBuf
), "%d", NSToIntRound(rect
.height
/ scale
.scale
));
1504 sizeString
.AssignWithConversion(sizeBuf
);
1505 docShellElement
->SetAttribute(HEIGHT_ATTRIBUTE
, sizeString
, rv
);
1507 ownerXULDoc
->Persist(windowElementId
, HEIGHT_ATTRIBUTE
);
1511 if (mPersistentAttributesDirty
& PAD_MISC
) {
1512 int32_t sizeMode
= mWindow
->SizeMode();
1514 if (sizeMode
!= nsSizeMode_Minimized
) {
1515 if (sizeMode
== nsSizeMode_Maximized
)
1516 sizeString
.Assign(SIZEMODE_MAXIMIZED
);
1517 else if (sizeMode
== nsSizeMode_Fullscreen
)
1518 sizeString
.Assign(SIZEMODE_FULLSCREEN
);
1520 sizeString
.Assign(SIZEMODE_NORMAL
);
1521 docShellElement
->SetAttribute(MODE_ATTRIBUTE
, sizeString
, rv
);
1522 if (ownerXULDoc
&& persistString
.Find("sizemode") >= 0)
1523 ownerXULDoc
->Persist(windowElementId
, MODE_ATTRIBUTE
);
1525 if (persistString
.Find("zlevel") >= 0) {
1527 nsCOMPtr
<nsIWindowMediator
> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
1529 mediator
->GetZLevel(this, &zLevel
);
1530 PR_snprintf(sizeBuf
, sizeof(sizeBuf
), "%lu", (unsigned long)zLevel
);
1531 sizeString
.AssignWithConversion(sizeBuf
);
1532 docShellElement
->SetAttribute(ZLEVEL_ATTRIBUTE
, sizeString
, rv
);
1533 ownerXULDoc
->Persist(windowElementId
, ZLEVEL_ATTRIBUTE
);
1538 mPersistentAttributesDirty
= 0;
1542 NS_IMETHODIMP
nsXULWindow::GetWindowDOMWindow(nsIDOMWindow
** aDOMWindow
)
1544 NS_ENSURE_STATE(mDocShell
);
1547 mDOMWindow
= mDocShell
->GetWindow();
1548 NS_ENSURE_TRUE(mDOMWindow
, NS_ERROR_FAILURE
);
1550 *aDOMWindow
= mDOMWindow
;
1551 NS_ADDREF(*aDOMWindow
);
1556 nsXULWindow::GetWindowDOMElement() const
1558 NS_ENSURE_TRUE(mDocShell
, nullptr);
1560 nsCOMPtr
<nsIContentViewer
> cv
;
1561 mDocShell
->GetContentViewer(getter_AddRefs(cv
));
1562 NS_ENSURE_TRUE(cv
, nullptr);
1564 const nsIDocument
* document
= cv
->GetDocument();
1565 NS_ENSURE_TRUE(document
, nullptr);
1567 return document
->GetRootElement();
1570 nsresult
nsXULWindow::ContentShellAdded(nsIDocShellTreeItem
* aContentShell
,
1571 bool aPrimary
, bool aTargetable
, const nsAString
& aID
)
1573 nsContentShellInfo
* shellInfo
= nullptr;
1575 uint32_t i
, count
= mContentShells
.Length();
1576 nsWeakPtr contentShellWeak
= do_GetWeakReference(aContentShell
);
1577 for (i
= 0; i
< count
; i
++) {
1578 nsContentShellInfo
* info
= mContentShells
.ElementAt(i
);
1579 if (info
->id
.Equals(aID
)) {
1580 // We already exist. Do a replace.
1581 info
->child
= contentShellWeak
;
1584 else if (info
->child
== contentShellWeak
)
1585 info
->child
= nullptr;
1589 shellInfo
= new nsContentShellInfo(aID
, contentShellWeak
);
1590 mContentShells
.AppendElement(shellInfo
);
1593 // Set the default content tree owner
1595 NS_ENSURE_SUCCESS(EnsurePrimaryContentTreeOwner(), NS_ERROR_FAILURE
);
1596 aContentShell
->SetTreeOwner(mPrimaryContentTreeOwner
);
1597 mPrimaryContentShell
= aContentShell
;
1600 NS_ENSURE_SUCCESS(EnsureContentTreeOwner(), NS_ERROR_FAILURE
);
1601 aContentShell
->SetTreeOwner(mContentTreeOwner
);
1602 if (mPrimaryContentShell
== aContentShell
)
1603 mPrimaryContentShell
= nullptr;
1608 int32_t debugCount
= mTargetableShells
.Count();
1609 int32_t debugCounter
;
1610 for (debugCounter
= debugCount
- 1; debugCounter
>= 0; --debugCounter
) {
1611 nsCOMPtr
<nsIDocShellTreeItem
> curItem
=
1612 do_QueryReferent(mTargetableShells
[debugCounter
]);
1613 NS_ASSERTION(!SameCOMIdentity(curItem
, aContentShell
),
1614 "Adding already existing item to mTargetableShells");
1618 // put the new shell at the start of the targetable shells list if either
1619 // it's the new primary shell or there is no existing primary shell (which
1620 // means that chances are this one just stopped being primary). If we
1621 // really cared, we could keep track of the "last no longer primary shell"
1622 // explicitly, but it probably doesn't matter enough: the difference would
1623 // only be felt in a situation where all shells were non-primary, which
1624 // doesn't happen much. In a situation where there is one and only one
1625 // primary shell, and in which shells get unmarked as primary before some
1626 // other shell gets marked as primary, this effectively stores the list of
1627 // targetable shells in "most recently primary first" order.
1629 if (aPrimary
|| !mPrimaryContentShell
) {
1630 inserted
= mTargetableShells
.InsertObjectAt(contentShellWeak
, 0);
1632 inserted
= mTargetableShells
.AppendObject(contentShellWeak
);
1634 NS_ENSURE_TRUE(inserted
, NS_ERROR_OUT_OF_MEMORY
);
1640 nsresult
nsXULWindow::ContentShellRemoved(nsIDocShellTreeItem
* aContentShell
)
1642 if (mPrimaryContentShell
== aContentShell
) {
1643 mPrimaryContentShell
= nullptr;
1646 int32_t i
, count
= mContentShells
.Length();
1647 for (i
= count
- 1; i
>= 0; --i
) {
1648 nsContentShellInfo
* info
= mContentShells
.ElementAt(i
);
1649 nsCOMPtr
<nsIDocShellTreeItem
> curItem
= do_QueryReferent(info
->child
);
1650 if (!curItem
|| SameCOMIdentity(curItem
, aContentShell
)) {
1651 mContentShells
.RemoveElementAt(i
);
1656 count
= mTargetableShells
.Count();
1657 for (i
= count
- 1; i
>= 0; --i
) {
1658 nsCOMPtr
<nsIDocShellTreeItem
> curItem
=
1659 do_QueryReferent(mTargetableShells
[i
]);
1660 if (!curItem
|| SameCOMIdentity(curItem
, aContentShell
)) {
1661 mTargetableShells
.RemoveObjectAt(i
);
1668 NS_IMETHODIMP
nsXULWindow::SizeShellTo(nsIDocShellTreeItem
* aShellItem
,
1669 int32_t aCX
, int32_t aCY
)
1671 // XXXTAB This is wrong, we should actually reflow based on the passed in
1672 // shell. For now we are hacking and doing delta sizing. This is bad
1673 // because it assumes all size we add will go to the shell which probably
1676 nsCOMPtr
<nsIBaseWindow
> shellAsWin(do_QueryInterface(aShellItem
));
1677 NS_ENSURE_TRUE(shellAsWin
, NS_ERROR_FAILURE
);
1681 shellAsWin
->GetSize(&width
, &height
);
1683 int32_t widthDelta
= aCX
- width
;
1684 int32_t heightDelta
= aCY
- height
;
1686 if (widthDelta
|| heightDelta
) {
1690 GetSize(&winCX
, &winCY
);
1691 // There's no point in trying to make the window smaller than the
1692 // desired docshell size --- that's not likely to work. This whole
1693 // function assumes that the outer docshell is adding some constant
1694 // "border" chrome to aShellItem.
1695 winCX
= std::max(winCX
+ widthDelta
, aCX
);
1696 winCY
= std::max(winCY
+ heightDelta
, aCY
);
1697 SetSize(winCX
, winCY
, true);
1703 NS_IMETHODIMP
nsXULWindow::ExitModalLoop(nsresult aStatus
)
1705 if (mContinueModalLoop
)
1707 mContinueModalLoop
= false;
1708 mModalStatus
= aStatus
;
1712 // top-level function to create a new window
1713 NS_IMETHODIMP
nsXULWindow::CreateNewWindow(int32_t aChromeFlags
,
1714 nsITabParent
*aOpeningTab
,
1715 nsIXULWindow
**_retval
)
1717 NS_ENSURE_ARG_POINTER(_retval
);
1719 if (aChromeFlags
& nsIWebBrowserChrome::CHROME_OPENAS_CHROME
)
1720 return CreateNewChromeWindow(aChromeFlags
, aOpeningTab
, _retval
);
1721 return CreateNewContentWindow(aChromeFlags
, aOpeningTab
, _retval
);
1724 NS_IMETHODIMP
nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags
,
1725 nsITabParent
*aOpeningTab
,
1726 nsIXULWindow
**_retval
)
1728 nsCOMPtr
<nsIAppShellService
> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID
));
1729 NS_ENSURE_TRUE(appShell
, NS_ERROR_FAILURE
);
1731 // Just do a normal create of a window and return.
1733 nsCOMPtr
<nsIXULWindow
> newWindow
;
1734 appShell
->CreateTopLevelWindow(this, nullptr, aChromeFlags
,
1735 nsIAppShellService::SIZE_TO_CONTENT
,
1736 nsIAppShellService::SIZE_TO_CONTENT
,
1738 getter_AddRefs(newWindow
));
1740 NS_ENSURE_TRUE(newWindow
, NS_ERROR_FAILURE
);
1742 *_retval
= newWindow
;
1743 NS_ADDREF(*_retval
);
1748 NS_IMETHODIMP
nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags
,
1749 nsITabParent
*aOpeningTab
,
1750 nsIXULWindow
**_retval
)
1752 nsCOMPtr
<nsIAppShellService
> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID
));
1753 NS_ENSURE_TRUE(appShell
, NS_ERROR_FAILURE
);
1755 // We need to create a new top level window and then enter a nested
1756 // loop. Eventually the new window will be told that it has loaded,
1757 // at which time we know it is safe to spin out of the nested loop
1758 // and allow the opening code to proceed.
1760 nsCOMPtr
<nsIURI
> uri
;
1762 nsAdoptingCString urlStr
= Preferences::GetCString("browser.chromeURL");
1763 if (urlStr
.IsEmpty()) {
1764 urlStr
.AssignLiteral("chrome://navigator/content/navigator.xul");
1767 nsCOMPtr
<nsIIOService
> service(do_GetService(NS_IOSERVICE_CONTRACTID
));
1769 service
->NewURI(urlStr
, nullptr, nullptr, getter_AddRefs(uri
));
1771 NS_ENSURE_TRUE(uri
, NS_ERROR_FAILURE
);
1773 // We need to create a chrome window to contain the content window we're about
1774 // to pass back. The subject principal needs to be system while we're creating
1775 // it to make things work right, so force a system caller. See bug 799348
1776 // comment 13 for a description of what happens when we don't.
1777 nsCOMPtr
<nsIXULWindow
> newWindow
;
1779 AutoNoJSAPI nojsapi
;
1780 appShell
->CreateTopLevelWindow(this, uri
,
1781 aChromeFlags
, 615, 480,
1783 getter_AddRefs(newWindow
));
1784 NS_ENSURE_TRUE(newWindow
, NS_ERROR_FAILURE
);
1787 // Specify that we want the window to remain locked until the chrome has loaded.
1788 nsXULWindow
*xulWin
= static_cast<nsXULWindow
*>
1789 (static_cast<nsIXULWindow
*>
1792 xulWin
->LockUntilChromeLoad();
1795 AutoNoJSAPI nojsapi
;
1796 nsIThread
*thread
= NS_GetCurrentThread();
1797 while (xulWin
->IsLocked()) {
1798 if (!NS_ProcessNextEvent(thread
))
1803 // If aOpeningTab is not null, it means that we're creating a new window
1804 // with a remote browser, which doesn't have a primary docshell. In that
1805 // case, we check for the chrome window docshell and make sure that a new
1806 // remote tab was opened and stashed in that docshell.
1808 NS_ENSURE_STATE(xulWin
->mDocShell
);
1809 NS_ENSURE_STATE(xulWin
->mDocShell
->GetOpenedRemote());
1811 NS_ENSURE_STATE(xulWin
->mPrimaryContentShell
);
1814 *_retval
= newWindow
;
1815 NS_ADDREF(*_retval
);
1820 void nsXULWindow::EnableParent(bool aEnable
)
1822 nsCOMPtr
<nsIBaseWindow
> parentWindow
;
1823 nsCOMPtr
<nsIWidget
> parentWidget
;
1825 parentWindow
= do_QueryReferent(mParentWindow
);
1827 parentWindow
->GetMainWidget(getter_AddRefs(parentWidget
));
1829 parentWidget
->Enable(aEnable
);
1832 // Constrain the window to its proper z-level
1833 bool nsXULWindow::ConstrainToZLevel(bool aImmediate
,
1834 nsWindowZ
*aPlacement
,
1835 nsIWidget
*aReqBelow
,
1836 nsIWidget
**aActualBelow
)
1839 /* Do we have a parent window? This means our z-order is already constrained,
1840 since we're a dependent window. Our window list isn't hierarchical,
1841 so we can't properly calculate placement for such a window.
1842 Should we just abort? */
1843 nsCOMPtr
<nsIBaseWindow
> parentWindow
= do_QueryReferent(mParentWindow
);
1848 nsCOMPtr
<nsIWindowMediator
> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
1856 nsIXULWindow
*us
= this;
1859 mediator
->GetZLevel(this, &zLevel
);
1861 // translate from WidgetGUIEvent to nsIWindowMediator constants
1862 position
= nsIWindowMediator::zLevelTop
;
1863 if (*aPlacement
== nsWindowZBottom
|| zLevel
== nsIXULWindow::lowestZ
)
1864 position
= nsIWindowMediator::zLevelBottom
;
1865 else if (*aPlacement
== nsWindowZRelative
)
1866 position
= nsIWindowMediator::zLevelBelow
;
1868 if (NS_SUCCEEDED(mediator
->CalculateZPosition(us
, position
, aReqBelow
,
1869 &newPosition
, aActualBelow
, &altered
))) {
1870 /* If we were asked to move to the top but constrained to remain
1871 below one of our other windows, first move all windows in that
1872 window's layer and above to the top. This allows the user to
1873 click a window which can't be topmost and still bring mozilla
1874 to the foreground. */
1876 (position
== nsIWindowMediator::zLevelTop
||
1877 (position
== nsIWindowMediator::zLevelBelow
&& aReqBelow
== 0)))
1878 PlaceWindowLayersBehind(zLevel
+ 1, nsIXULWindow::highestZ
, 0);
1880 if (*aPlacement
!= nsWindowZBottom
&&
1881 position
== nsIWindowMediator::zLevelBottom
)
1883 if (altered
|| aImmediate
) {
1884 if (newPosition
== nsIWindowMediator::zLevelTop
)
1885 *aPlacement
= nsWindowZTop
;
1886 else if (newPosition
== nsIWindowMediator::zLevelBottom
)
1887 *aPlacement
= nsWindowZBottom
;
1889 *aPlacement
= nsWindowZRelative
;
1892 nsCOMPtr
<nsIBaseWindow
> ourBase
= do_QueryObject(this);
1894 nsCOMPtr
<nsIWidget
> ourWidget
;
1895 ourBase
->GetMainWidget(getter_AddRefs(ourWidget
));
1896 ourWidget
->PlaceBehind(*aPlacement
== nsWindowZBottom
?
1897 eZPlacementBottom
: eZPlacementBelow
,
1898 *aActualBelow
, false);
1903 /* CalculateZPosition can tell us to be below nothing, because it tries
1904 not to change something it doesn't recognize. A request to verify
1905 being below an unrecognized window, then, is treated as a request
1906 to come to the top (below null) */
1907 nsCOMPtr
<nsIXULWindow
> windowAbove
;
1908 if (newPosition
== nsIWindowMediator::zLevelBelow
&& *aActualBelow
) {
1909 windowAbove
= (*aActualBelow
)->GetWidgetListener()->GetXULWindow();
1912 mediator
->SetZPosition(us
, newPosition
, windowAbove
);
1918 /* Re-z-position all windows in the layers from aLowLevel to aHighLevel,
1919 inclusive, to be behind aBehind. aBehind of null means on top.
1920 Note this method actually does nothing to our relative window positions.
1921 (And therefore there's no need to inform WindowMediator we're moving
1922 things, because we aren't.) This method is useful for, say, moving
1923 a range of layers of our own windows relative to windows belonging to
1924 external applications.
1926 void nsXULWindow::PlaceWindowLayersBehind(uint32_t aLowLevel
,
1927 uint32_t aHighLevel
,
1928 nsIXULWindow
*aBehind
)
1930 // step through windows in z-order from top to bottommost window
1932 nsCOMPtr
<nsIWindowMediator
> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
1936 nsCOMPtr
<nsISimpleEnumerator
> windowEnumerator
;
1937 mediator
->GetZOrderXULWindowEnumerator(0, true,
1938 getter_AddRefs(windowEnumerator
));
1939 if (!windowEnumerator
)
1942 // each window will be moved behind previousHighWidget, itself
1943 // a moving target. initialize it.
1944 nsCOMPtr
<nsIWidget
> previousHighWidget
;
1946 nsCOMPtr
<nsIBaseWindow
> highBase(do_QueryInterface(aBehind
));
1948 highBase
->GetMainWidget(getter_AddRefs(previousHighWidget
));
1951 // get next lower window
1953 while (windowEnumerator
->HasMoreElements(&more
), more
) {
1954 uint32_t nextZ
; // z-level of nextWindow
1955 nsCOMPtr
<nsISupports
> nextWindow
;
1956 windowEnumerator
->GetNext(getter_AddRefs(nextWindow
));
1957 nsCOMPtr
<nsIXULWindow
> nextXULWindow(do_QueryInterface(nextWindow
));
1958 nextXULWindow
->GetZLevel(&nextZ
);
1959 if (nextZ
< aLowLevel
)
1960 break; // we've processed all windows through aLowLevel
1962 // move it just below its next higher window
1963 nsCOMPtr
<nsIBaseWindow
> nextBase(do_QueryInterface(nextXULWindow
));
1965 nsCOMPtr
<nsIWidget
> nextWidget
;
1966 nextBase
->GetMainWidget(getter_AddRefs(nextWidget
));
1967 if (nextZ
<= aHighLevel
)
1968 nextWidget
->PlaceBehind(eZPlacementBelow
, previousHighWidget
, false);
1969 previousHighWidget
= nextWidget
;
1974 void nsXULWindow::SetContentScrollbarVisibility(bool aVisible
)
1976 nsCOMPtr
<nsPIDOMWindow
> contentWin(do_GetInterface(mPrimaryContentShell
));
1978 mozilla::ErrorResult rv
;
1979 nsRefPtr
<nsGlobalWindow
> window
= static_cast<nsGlobalWindow
*>(contentWin
.get());
1980 nsRefPtr
<mozilla::dom::BarProp
> scrollbars
= window
->GetScrollbars(rv
);
1982 scrollbars
->SetVisible(aVisible
, rv
);
1987 bool nsXULWindow::GetContentScrollbarVisibility()
1989 // This code already exists in dom/src/base/nsBarProp.cpp, but we
1990 // can't safely get to that from here as this function is called
1991 // while the DOM window is being set up, and we need the DOM window
1992 // to get to that code.
1993 nsCOMPtr
<nsIScrollable
> scroller(do_QueryInterface(mPrimaryContentShell
));
1997 scroller
->GetDefaultScrollbarPreferences(
1998 nsIScrollable::ScrollOrientation_Y
, &prefValue
);
1999 if (prefValue
== nsIScrollable::Scrollbar_Never
) // try the other way
2000 scroller
->GetDefaultScrollbarPreferences(
2001 nsIScrollable::ScrollOrientation_X
, &prefValue
);
2003 if (prefValue
== nsIScrollable::Scrollbar_Never
)
2010 // during spinup, attributes that haven't been loaded yet can't be dirty
2011 void nsXULWindow::PersistentAttributesDirty(uint32_t aDirtyFlags
)
2013 mPersistentAttributesDirty
|= aDirtyFlags
& mPersistentAttributesMask
;
2016 NS_IMETHODIMP
nsXULWindow::ApplyChromeFlags()
2018 nsCOMPtr
<dom::Element
> window
= GetWindowDOMElement();
2019 NS_ENSURE_TRUE(window
, NS_ERROR_FAILURE
);
2021 if (mChromeLoaded
) {
2022 // The two calls in this block don't need to happen early because they
2023 // don't cause a global restyle on the document. Not only that, but the
2024 // scrollbar stuff needs a content area to toggle the scrollbars on anyway.
2025 // So just don't do these until mChromeLoaded is true.
2027 // Scrollbars have their own special treatment.
2028 SetContentScrollbarVisibility(mChromeFlags
&
2029 nsIWebBrowserChrome::CHROME_SCROLLBARS
?
2033 /* the other flags are handled together. we have style rules
2034 in navigator.css that trigger visibility based on
2035 the 'chromehidden' attribute of the <window> tag. */
2036 nsAutoString newvalue
;
2038 if (! (mChromeFlags
& nsIWebBrowserChrome::CHROME_MENUBAR
))
2039 newvalue
.AppendLiteral("menubar ");
2041 if (! (mChromeFlags
& nsIWebBrowserChrome::CHROME_TOOLBAR
))
2042 newvalue
.AppendLiteral("toolbar ");
2044 if (! (mChromeFlags
& nsIWebBrowserChrome::CHROME_LOCATIONBAR
))
2045 newvalue
.AppendLiteral("location ");
2047 if (! (mChromeFlags
& nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR
))
2048 newvalue
.AppendLiteral("directories ");
2050 if (! (mChromeFlags
& nsIWebBrowserChrome::CHROME_STATUSBAR
))
2051 newvalue
.AppendLiteral("status ");
2053 if (! (mChromeFlags
& nsIWebBrowserChrome::CHROME_EXTRA
))
2054 newvalue
.AppendLiteral("extrachrome ");
2056 // Note that if we're not actually changing the value this will be a no-op,
2057 // so no need to compare to the old value.
2059 window
->SetAttribute(NS_LITERAL_STRING("chromehidden"), newvalue
, rv
);
2064 NS_IMETHODIMP
nsXULWindow::GetXULBrowserWindow(nsIXULBrowserWindow
* *aXULBrowserWindow
)
2066 NS_IF_ADDREF(*aXULBrowserWindow
= mXULBrowserWindow
);
2070 NS_IMETHODIMP
nsXULWindow::SetXULBrowserWindow(nsIXULBrowserWindow
* aXULBrowserWindow
)
2072 mXULBrowserWindow
= aXULBrowserWindow
;
2076 //*****************************************************************************
2077 //*** nsContentShellInfo: Object Management
2078 //*****************************************************************************
2080 nsContentShellInfo::nsContentShellInfo(const nsAString
& aID
,
2081 nsIWeakReference
* aContentShell
)
2083 child(aContentShell
)
2085 MOZ_COUNT_CTOR(nsContentShellInfo
);
2088 nsContentShellInfo::~nsContentShellInfo()
2090 MOZ_COUNT_DTOR(nsContentShellInfo
);
2091 //XXX Set Tree Owner to null if the tree owner is nsXULWindow->mContentTreeOwner