1 /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=2 sw=2 et tw=80:
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 #include "nsContentTreeOwner.h"
10 #include "AppWindow.h"
12 // Interfaces needed to be included
13 #include "nsGlobalWindowOuter.h"
14 #include "nsIDOMWindow.h"
15 #include "nsIBrowserDOMWindow.h"
16 #include "nsIOpenWindowInfo.h"
17 #include "nsIPrompt.h"
18 #include "nsIAuthPrompt.h"
19 #include "nsIXULBrowserWindow.h"
20 #include "nsIPrincipal.h"
21 #include "nsIURIFixup.h"
22 #include "nsIWebNavigation.h"
23 #include "nsDocShellCID.h"
24 #include "nsIMIMEInfo.h"
25 #include "nsIWidget.h"
26 #include "nsWindowWatcher.h"
27 #include "nsIWindowMediator.h"
28 #include "mozilla/Components.h"
29 #include "mozilla/NullPrincipal.h"
30 #include "nsDocShell.h"
31 #include "nsDocShellLoadState.h"
32 #include "nsQueryActor.h"
34 #include "nsIScriptObjectPrincipal.h"
36 #include "mozilla/dom/Document.h"
37 #if defined(XP_MACOSX)
38 # include "nsThreadUtils.h"
41 #include "mozilla/Preferences.h"
42 #include "mozilla/Try.h"
43 #include "mozilla/dom/Element.h"
44 #include "mozilla/dom/ScriptSettings.h"
45 #include "mozilla/dom/UserActivation.h"
47 using namespace mozilla
;
49 //*****************************************************************************
50 //*** nsContentTreeOwner: Object Management
51 //*****************************************************************************
53 nsContentTreeOwner::nsContentTreeOwner(bool fPrimary
)
54 : mAppWindow(nullptr), mPrimary(fPrimary
) {}
56 //*****************************************************************************
57 // nsContentTreeOwner::nsISupports
58 //*****************************************************************************
60 NS_IMPL_ADDREF(nsContentTreeOwner
)
61 NS_IMPL_RELEASE(nsContentTreeOwner
)
63 NS_INTERFACE_MAP_BEGIN(nsContentTreeOwner
)
64 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIDocShellTreeOwner
)
65 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner
)
66 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow
)
67 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome
)
68 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor
)
69 NS_INTERFACE_MAP_ENTRY(nsIWindowProvider
)
72 //*****************************************************************************
73 // nsContentTreeOwner::nsIInterfaceRequestor
74 //*****************************************************************************
76 NS_IMETHODIMP
nsContentTreeOwner::GetInterface(const nsIID
& aIID
,
78 NS_ENSURE_ARG_POINTER(aSink
);
81 if (aIID
.Equals(NS_GET_IID(nsIPrompt
))) {
82 NS_ENSURE_STATE(mAppWindow
);
83 return mAppWindow
->GetInterface(aIID
, aSink
);
85 if (aIID
.Equals(NS_GET_IID(nsIAuthPrompt
))) {
86 NS_ENSURE_STATE(mAppWindow
);
87 return mAppWindow
->GetInterface(aIID
, aSink
);
89 if (aIID
.Equals(NS_GET_IID(nsIDocShellTreeItem
))) {
90 NS_ENSURE_STATE(mAppWindow
);
91 nsCOMPtr
<nsIDocShell
> shell
;
92 mAppWindow
->GetDocShell(getter_AddRefs(shell
));
93 if (shell
) return shell
->QueryInterface(aIID
, aSink
);
94 return NS_ERROR_FAILURE
;
97 if (aIID
.Equals(NS_GET_IID(nsIDOMWindow
)) ||
98 aIID
.Equals(NS_GET_IID(nsPIDOMWindowOuter
))) {
99 NS_ENSURE_STATE(mAppWindow
);
100 nsCOMPtr
<nsIDocShellTreeItem
> shell
;
101 mAppWindow
->GetPrimaryContentShell(getter_AddRefs(shell
));
103 nsCOMPtr
<nsIInterfaceRequestor
> thing(do_QueryInterface(shell
));
104 if (thing
) return thing
->GetInterface(aIID
, aSink
);
106 return NS_ERROR_FAILURE
;
109 if (aIID
.Equals(NS_GET_IID(nsIAppWindow
))) {
110 NS_ENSURE_STATE(mAppWindow
);
111 return mAppWindow
->QueryInterface(aIID
, aSink
);
114 return QueryInterface(aIID
, aSink
);
117 //*****************************************************************************
118 // nsContentTreeOwner::nsIDocShellTreeOwner
119 //*****************************************************************************
122 nsContentTreeOwner::ContentShellAdded(nsIDocShellTreeItem
* aContentShell
,
124 NS_ENSURE_STATE(mAppWindow
);
125 return mAppWindow
->ContentShellAdded(aContentShell
, aPrimary
);
129 nsContentTreeOwner::ContentShellRemoved(nsIDocShellTreeItem
* aContentShell
) {
130 NS_ENSURE_STATE(mAppWindow
);
131 return mAppWindow
->ContentShellRemoved(aContentShell
);
135 nsContentTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem
** aShell
) {
136 NS_ENSURE_STATE(mAppWindow
);
137 return mAppWindow
->GetPrimaryContentShell(aShell
);
141 nsContentTreeOwner::RemoteTabAdded(nsIRemoteTab
* aTab
, bool aPrimary
) {
142 NS_ENSURE_STATE(mAppWindow
);
143 return mAppWindow
->RemoteTabAdded(aTab
, aPrimary
);
147 nsContentTreeOwner::RemoteTabRemoved(nsIRemoteTab
* aTab
) {
148 NS_ENSURE_STATE(mAppWindow
);
149 return mAppWindow
->RemoteTabRemoved(aTab
);
153 nsContentTreeOwner::GetPrimaryRemoteTab(nsIRemoteTab
** aTab
) {
154 NS_ENSURE_STATE(mAppWindow
);
155 return mAppWindow
->GetPrimaryRemoteTab(aTab
);
159 nsContentTreeOwner::GetPrimaryContentBrowsingContext(
160 mozilla::dom::BrowsingContext
** aBc
) {
161 NS_ENSURE_STATE(mAppWindow
);
162 return mAppWindow
->GetPrimaryContentBrowsingContext(aBc
);
166 nsContentTreeOwner::GetPrimaryContentSize(int32_t* aWidth
, int32_t* aHeight
) {
167 NS_ENSURE_STATE(mAppWindow
);
168 return mAppWindow
->GetPrimaryContentSize(aWidth
, aHeight
);
172 nsContentTreeOwner::SetPrimaryContentSize(int32_t aWidth
, int32_t aHeight
) {
173 NS_ENSURE_STATE(mAppWindow
);
174 return mAppWindow
->SetPrimaryContentSize(aWidth
, aHeight
);
178 nsContentTreeOwner::GetRootShellSize(int32_t* aWidth
, int32_t* aHeight
) {
179 NS_ENSURE_STATE(mAppWindow
);
180 return mAppWindow
->GetRootShellSize(aWidth
, aHeight
);
184 nsContentTreeOwner::SetRootShellSize(int32_t aWidth
, int32_t aHeight
) {
185 NS_ENSURE_STATE(mAppWindow
);
186 return mAppWindow
->SetRootShellSize(aWidth
, aHeight
);
189 NS_IMETHODIMP
nsContentTreeOwner::SizeShellTo(nsIDocShellTreeItem
* aShellItem
,
190 int32_t aCX
, int32_t aCY
) {
191 NS_ENSURE_STATE(mAppWindow
);
192 return mAppWindow
->SizeShellTo(aShellItem
, aCX
, aCY
);
196 nsContentTreeOwner::SetPersistence(bool aPersistPosition
, bool aPersistSize
,
197 bool aPersistSizeMode
) {
198 NS_ENSURE_STATE(mAppWindow
);
199 nsCOMPtr
<dom::Element
> docShellElement
= mAppWindow
->GetWindowDOMElement();
200 if (!docShellElement
) return NS_ERROR_FAILURE
;
202 nsAutoString persistString
;
203 docShellElement
->GetAttr(nsGkAtoms::persist
, persistString
);
205 bool saveString
= false;
209 index
= persistString
.Find(u
"screenX");
210 if (!aPersistPosition
&& index
>= 0) {
211 persistString
.Cut(index
, 7);
213 } else if (aPersistPosition
&& index
< 0) {
214 persistString
.AppendLiteral(" screenX");
218 index
= persistString
.Find(u
"screenY");
219 if (!aPersistPosition
&& index
>= 0) {
220 persistString
.Cut(index
, 7);
222 } else if (aPersistPosition
&& index
< 0) {
223 persistString
.AppendLiteral(" screenY");
227 index
= persistString
.Find(u
"width");
228 if (!aPersistSize
&& index
>= 0) {
229 persistString
.Cut(index
, 5);
231 } else if (aPersistSize
&& index
< 0) {
232 persistString
.AppendLiteral(" width");
236 index
= persistString
.Find(u
"height");
237 if (!aPersistSize
&& index
>= 0) {
238 persistString
.Cut(index
, 6);
240 } else if (aPersistSize
&& index
< 0) {
241 persistString
.AppendLiteral(" height");
245 index
= persistString
.Find(u
"sizemode");
246 if (!aPersistSizeMode
&& (index
>= 0)) {
247 persistString
.Cut(index
, 8);
249 } else if (aPersistSizeMode
&& (index
< 0)) {
250 persistString
.AppendLiteral(" sizemode");
256 docShellElement
->SetAttribute(u
"persist"_ns
, persistString
, rv
);
263 nsContentTreeOwner::GetPersistence(bool* aPersistPosition
, bool* aPersistSize
,
264 bool* aPersistSizeMode
) {
265 NS_ENSURE_STATE(mAppWindow
);
266 nsCOMPtr
<dom::Element
> docShellElement
= mAppWindow
->GetWindowDOMElement();
267 if (!docShellElement
) return NS_ERROR_FAILURE
;
269 nsAutoString persistString
;
270 docShellElement
->GetAttr(nsGkAtoms::persist
, persistString
);
272 // data structure doesn't quite match the question, but it's close enough
273 // for what we want (since this method is never actually called...)
274 if (aPersistPosition
) {
275 *aPersistPosition
= persistString
.Find(u
"screenX") >= 0 ||
276 persistString
.Find(u
"screenY") >= 0;
280 persistString
.Find(u
"width") >= 0 || persistString
.Find(u
"height") >= 0;
282 if (aPersistSizeMode
) {
283 *aPersistSizeMode
= persistString
.Find(u
"sizemode") >= 0;
290 nsContentTreeOwner::GetTabCount(uint32_t* aResult
) {
292 return mAppWindow
->GetTabCount(aResult
);
300 nsContentTreeOwner::GetHasPrimaryContent(bool* aResult
) {
301 NS_ENSURE_STATE(mAppWindow
);
302 return mAppWindow
->GetHasPrimaryContent(aResult
);
305 //*****************************************************************************
306 // nsContentTreeOwner::nsIWebBrowserChrome
307 //*****************************************************************************
309 NS_IMETHODIMP
nsContentTreeOwner::SetLinkStatus(const nsAString
& aStatusText
) {
310 NS_ENSURE_STATE(mAppWindow
);
312 nsCOMPtr
<nsIXULBrowserWindow
> xulBrowserWindow
;
313 mAppWindow
->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow
));
315 if (xulBrowserWindow
) {
316 xulBrowserWindow
->SetOverLink(aStatusText
);
322 NS_IMETHODIMP
nsContentTreeOwner::SetChromeFlags(uint32_t aChromeFlags
) {
323 NS_ENSURE_STATE(mAppWindow
);
324 return mAppWindow
->SetChromeFlags(aChromeFlags
);
327 NS_IMETHODIMP
nsContentTreeOwner::GetChromeFlags(uint32_t* aChromeFlags
) {
328 NS_ENSURE_STATE(mAppWindow
);
329 return mAppWindow
->GetChromeFlags(aChromeFlags
);
332 NS_IMETHODIMP
nsContentTreeOwner::ShowAsModal() {
333 NS_ENSURE_STATE(mAppWindow
);
334 return mAppWindow
->ShowModal();
337 NS_IMETHODIMP
nsContentTreeOwner::IsWindowModal(bool* _retval
) {
338 NS_ENSURE_STATE(mAppWindow
);
339 *_retval
= mAppWindow
->mContinueModalLoop
;
343 //*****************************************************************************
344 // nsContentTreeOwner::nsIBaseWindow
345 //*****************************************************************************
347 NS_IMETHODIMP
nsContentTreeOwner::InitWindow(nativeWindow aParentNativeWindow
,
348 nsIWidget
* parentWidget
, int32_t x
,
349 int32_t y
, int32_t cx
,
351 // Ignore wigdet parents for now. Don't think those are a vaild thing to
353 NS_ENSURE_SUCCESS(SetPositionAndSize(x
, y
, cx
, cy
, 0), NS_ERROR_FAILURE
);
358 NS_IMETHODIMP
nsContentTreeOwner::Destroy() {
359 NS_ENSURE_STATE(mAppWindow
);
360 return mAppWindow
->Destroy();
363 double nsContentTreeOwner::GetWidgetCSSToDeviceScale() {
364 return mAppWindow
? mAppWindow
->GetWidgetCSSToDeviceScale() : 1.0;
367 NS_IMETHODIMP
nsContentTreeOwner::GetDevicePixelsPerDesktopPixel(
369 NS_ENSURE_STATE(mAppWindow
);
370 return mAppWindow
->GetDevicePixelsPerDesktopPixel(aScale
);
373 NS_IMETHODIMP
nsContentTreeOwner::SetPositionDesktopPix(int32_t aX
,
375 NS_ENSURE_STATE(mAppWindow
);
376 return mAppWindow
->SetPositionDesktopPix(aX
, aY
);
379 NS_IMETHODIMP
nsContentTreeOwner::SetPosition(int32_t aX
, int32_t aY
) {
380 NS_ENSURE_STATE(mAppWindow
);
381 return mAppWindow
->SetPosition(aX
, aY
);
384 NS_IMETHODIMP
nsContentTreeOwner::GetPosition(int32_t* aX
, int32_t* aY
) {
385 NS_ENSURE_STATE(mAppWindow
);
386 return mAppWindow
->GetPosition(aX
, aY
);
389 NS_IMETHODIMP
nsContentTreeOwner::SetSize(int32_t aCX
, int32_t aCY
,
391 NS_ENSURE_STATE(mAppWindow
);
392 return mAppWindow
->SetSize(aCX
, aCY
, aRepaint
);
395 NS_IMETHODIMP
nsContentTreeOwner::GetSize(int32_t* aCX
, int32_t* aCY
) {
396 NS_ENSURE_STATE(mAppWindow
);
397 return mAppWindow
->GetSize(aCX
, aCY
);
400 NS_IMETHODIMP
nsContentTreeOwner::SetPositionAndSize(int32_t aX
, int32_t aY
,
401 int32_t aCX
, int32_t aCY
,
403 NS_ENSURE_STATE(mAppWindow
);
404 return mAppWindow
->SetPositionAndSize(aX
, aY
, aCX
, aCY
, aFlags
);
407 NS_IMETHODIMP
nsContentTreeOwner::GetPositionAndSize(int32_t* aX
, int32_t* aY
,
410 NS_ENSURE_STATE(mAppWindow
);
411 return mAppWindow
->GetPositionAndSize(aX
, aY
, aCX
, aCY
);
415 nsContentTreeOwner::SetDimensions(DimensionRequest
&& aRequest
) {
416 NS_ENSURE_STATE(mAppWindow
);
417 if (aRequest
.mDimensionKind
== DimensionKind::Outer
) {
418 return mAppWindow
->SetDimensions(std::move(aRequest
));
421 MOZ_TRY(aRequest
.SupplementFrom(this));
422 return aRequest
.ApplyInnerTo(this, /* aAsRootShell */ false);
426 nsContentTreeOwner::GetDimensions(DimensionKind aDimensionKind
, int32_t* aX
,
427 int32_t* aY
, int32_t* aCX
, int32_t* aCY
) {
428 NS_ENSURE_STATE(mAppWindow
);
429 if (aDimensionKind
== DimensionKind::Outer
) {
430 return mAppWindow
->GetDimensions(aDimensionKind
, aX
, aY
, aCX
, aCY
);
433 return NS_ERROR_NOT_IMPLEMENTED
;
435 return GetPrimaryContentSize(aCX
, aCY
);
438 NS_IMETHODIMP
nsContentTreeOwner::Repaint(bool aForce
) {
439 NS_ENSURE_STATE(mAppWindow
);
440 return mAppWindow
->Repaint(aForce
);
443 NS_IMETHODIMP
nsContentTreeOwner::GetParentWidget(nsIWidget
** aParentWidget
) {
444 NS_ENSURE_STATE(mAppWindow
);
445 return mAppWindow
->GetParentWidget(aParentWidget
);
448 NS_IMETHODIMP
nsContentTreeOwner::SetParentWidget(nsIWidget
* aParentWidget
) {
449 NS_ASSERTION(false, "You can't call this");
450 return NS_ERROR_NOT_IMPLEMENTED
;
453 NS_IMETHODIMP
nsContentTreeOwner::GetParentNativeWindow(
454 nativeWindow
* aParentNativeWindow
) {
455 NS_ENSURE_STATE(mAppWindow
);
456 return mAppWindow
->GetParentNativeWindow(aParentNativeWindow
);
459 NS_IMETHODIMP
nsContentTreeOwner::SetParentNativeWindow(
460 nativeWindow aParentNativeWindow
) {
461 NS_ASSERTION(false, "You can't call this");
462 return NS_ERROR_NOT_IMPLEMENTED
;
465 NS_IMETHODIMP
nsContentTreeOwner::GetNativeHandle(nsAString
& aNativeHandle
) {
466 NS_ENSURE_STATE(mAppWindow
);
467 return mAppWindow
->GetNativeHandle(aNativeHandle
);
470 NS_IMETHODIMP
nsContentTreeOwner::GetVisibility(bool* aVisibility
) {
471 NS_ENSURE_STATE(mAppWindow
);
472 return mAppWindow
->GetVisibility(aVisibility
);
475 NS_IMETHODIMP
nsContentTreeOwner::SetVisibility(bool aVisibility
) {
476 NS_ENSURE_STATE(mAppWindow
);
477 return mAppWindow
->SetVisibility(aVisibility
);
480 NS_IMETHODIMP
nsContentTreeOwner::GetEnabled(bool* aEnabled
) {
481 NS_ENSURE_STATE(mAppWindow
);
482 return mAppWindow
->GetEnabled(aEnabled
);
485 NS_IMETHODIMP
nsContentTreeOwner::SetEnabled(bool aEnable
) {
486 NS_ENSURE_STATE(mAppWindow
);
487 return mAppWindow
->SetEnabled(aEnable
);
490 NS_IMETHODIMP
nsContentTreeOwner::GetMainWidget(nsIWidget
** aMainWidget
) {
491 NS_ENSURE_ARG_POINTER(aMainWidget
);
492 NS_ENSURE_STATE(mAppWindow
);
494 *aMainWidget
= mAppWindow
->mWindow
;
495 NS_IF_ADDREF(*aMainWidget
);
500 NS_IMETHODIMP
nsContentTreeOwner::GetTitle(nsAString
& aTitle
) {
501 NS_ENSURE_STATE(mAppWindow
);
503 return mAppWindow
->GetTitle(aTitle
);
506 NS_IMETHODIMP
nsContentTreeOwner::SetTitle(const nsAString
& aTitle
) {
510 //*****************************************************************************
511 // nsContentTreeOwner: nsIWindowProvider
512 //*****************************************************************************
514 nsContentTreeOwner::ProvideWindow(
515 nsIOpenWindowInfo
* aOpenWindowInfo
, uint32_t aChromeFlags
,
516 bool aCalledFromJS
, nsIURI
* aURI
, const nsAString
& aName
,
517 const nsACString
& aFeatures
,
518 const mozilla::dom::UserActivation::Modifiers
& aModifiers
,
519 bool aForceNoOpener
, bool aForceNoReferrer
, bool aIsPopupRequested
,
520 nsDocShellLoadState
* aLoadState
, bool* aWindowIsNew
,
521 dom::BrowsingContext
** aReturn
) {
522 NS_ENSURE_ARG_POINTER(aOpenWindowInfo
);
524 RefPtr
<dom::BrowsingContext
> parent
= aOpenWindowInfo
->GetParent();
529 // Nothing to do here
534 nsCOMPtr
<nsIDocShell
> docshell
= parent
->GetDocShell();
535 nsCOMPtr
<nsIDocShellTreeOwner
> parentOwner
= do_GetInterface(docshell
);
537 SameCOMIdentity(parentOwner
, static_cast<nsIDocShellTreeOwner
*>(this)),
538 "Parent from wrong docshell tree?");
541 int32_t openLocation
= nsWindowWatcher::GetWindowOpenLocation(
542 parent
->GetDOMWindow(), aChromeFlags
, aModifiers
, aCalledFromJS
,
543 aOpenWindowInfo
->GetIsForPrinting());
545 if (openLocation
!= nsIBrowserDOMWindow::OPEN_NEWTAB
&&
546 openLocation
!= nsIBrowserDOMWindow::OPEN_NEWTAB_BACKGROUND
&&
547 openLocation
!= nsIBrowserDOMWindow::OPEN_CURRENTWINDOW
&&
548 openLocation
!= nsIBrowserDOMWindow::OPEN_PRINT_BROWSER
) {
549 // Just open a window normally
553 nsCOMPtr
<mozIDOMWindowProxy
> domWin
;
554 mAppWindow
->GetWindowDOMWindow(getter_AddRefs(domWin
));
555 if (!domWin
|| !nsGlobalWindowOuter::Cast(domWin
)->IsChromeWindow()) {
556 // Really odd... but whatever
557 NS_WARNING("AppWindow's DOMWindow is not a chrome window");
561 nsCOMPtr
<nsIBrowserDOMWindow
> browserDOMWin
=
562 nsGlobalWindowOuter::Cast(domWin
)->GetBrowserDOMWindow();
563 if (!browserDOMWin
) {
567 *aWindowIsNew
= (openLocation
!= nsIBrowserDOMWindow::OPEN_CURRENTWINDOW
);
570 dom::AutoNoJSAPI nojsapi
;
572 uint32_t flags
= nsIBrowserDOMWindow::OPEN_NEW
;
573 if (aForceNoOpener
) {
574 flags
|= nsIBrowserDOMWindow::OPEN_NO_OPENER
;
576 if (aForceNoReferrer
) {
577 flags
|= nsIBrowserDOMWindow::OPEN_NO_REFERRER
;
580 // Get a new rendering area from the browserDOMWin.
581 // Since we are not loading any URI, we follow the principle of least
582 // privilege and use a nullPrincipal as the triggeringPrincipal.
584 // This method handles setting the opener for us, so we don't need to set it
586 RefPtr
<NullPrincipal
> nullPrincipal
=
587 NullPrincipal::CreateWithoutOriginAttributes();
588 return browserDOMWin
->CreateContentWindow(aURI
, aOpenWindowInfo
,
590 nullPrincipal
, nullptr, aReturn
);
594 //*****************************************************************************
595 // nsContentTreeOwner: Accessors
596 //*****************************************************************************
598 void nsContentTreeOwner::AppWindow(mozilla::AppWindow
* aAppWindow
) {
599 mAppWindow
= aAppWindow
;
602 mozilla::AppWindow
* nsContentTreeOwner::AppWindow() { return mAppWindow
; }
604 /* this implementation focuses another window. if there isn't another
605 window to focus, we do nothing. */
607 nsContentTreeOwner::Blur() {
608 NS_DEFINE_CID(kWindowMediatorCID
, NS_WINDOWMEDIATOR_CID
);
610 nsCOMPtr
<nsISimpleEnumerator
> windowEnumerator
;
611 nsCOMPtr
<nsIAppWindow
> appWindow
;
615 nsCOMPtr
<nsIWindowMediator
> windowMediator(
616 do_GetService(kWindowMediatorCID
));
617 if (windowMediator
) {
618 windowMediator
->GetZOrderAppWindowEnumerator(
619 nullptr, true, getter_AddRefs(windowEnumerator
));
623 if (!windowEnumerator
) return NS_ERROR_FAILURE
;
625 // step through the top-level windows
627 windowEnumerator
->HasMoreElements(&more
);
629 nsCOMPtr
<nsISupports
> nextWindow
;
630 nsCOMPtr
<nsIAppWindow
> nextAppWindow
;
632 windowEnumerator
->GetNext(getter_AddRefs(nextWindow
));
633 nextAppWindow
= do_QueryInterface(nextWindow
);
637 appWindow
= nextAppWindow
;
641 // remember the very first one, in case we have to wrap
642 if (!appWindow
) appWindow
= nextAppWindow
;
645 if (nextAppWindow
== mAppWindow
) {
649 windowEnumerator
->HasMoreElements(&more
);
652 // change focus to the window we just found
654 nsCOMPtr
<nsIDocShell
> docshell
;
655 appWindow
->GetDocShell(getter_AddRefs(docshell
));
660 nsCOMPtr
<nsPIDOMWindowOuter
> domWindow
= docshell
->GetWindow();
661 if (domWindow
) domWindow
->Focus(mozilla::dom::CallerType::System
);