Bug 1859954 - Use XP_DARWIN rather than XP_MACOS in PHC r=glandium
[gecko.git] / xpfe / appshell / nsContentTreeOwner.cpp
blob62b3d19453137b1475e2025513e897a4d3e52aff
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/. */
8 // Local Includes
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"
35 #include "nsIURI.h"
36 #include "mozilla/dom/Document.h"
37 #if defined(XP_MACOSX)
38 # include "nsThreadUtils.h"
39 #endif
41 #include "mozilla/Preferences.h"
42 #include "mozilla/Try.h"
43 #include "mozilla/dom/Element.h"
44 #include "mozilla/dom/ScriptSettings.h"
46 using namespace mozilla;
48 //*****************************************************************************
49 //*** nsContentTreeOwner: Object Management
50 //*****************************************************************************
52 nsContentTreeOwner::nsContentTreeOwner(bool fPrimary)
53 : mAppWindow(nullptr), mPrimary(fPrimary) {}
55 //*****************************************************************************
56 // nsContentTreeOwner::nsISupports
57 //*****************************************************************************
59 NS_IMPL_ADDREF(nsContentTreeOwner)
60 NS_IMPL_RELEASE(nsContentTreeOwner)
62 NS_INTERFACE_MAP_BEGIN(nsContentTreeOwner)
63 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
64 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
65 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
66 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
67 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
68 NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
69 NS_INTERFACE_MAP_END
71 //*****************************************************************************
72 // nsContentTreeOwner::nsIInterfaceRequestor
73 //*****************************************************************************
75 NS_IMETHODIMP nsContentTreeOwner::GetInterface(const nsIID& aIID,
76 void** aSink) {
77 NS_ENSURE_ARG_POINTER(aSink);
78 *aSink = nullptr;
80 if (aIID.Equals(NS_GET_IID(nsIPrompt))) {
81 NS_ENSURE_STATE(mAppWindow);
82 return mAppWindow->GetInterface(aIID, aSink);
84 if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
85 NS_ENSURE_STATE(mAppWindow);
86 return mAppWindow->GetInterface(aIID, aSink);
88 if (aIID.Equals(NS_GET_IID(nsIDocShellTreeItem))) {
89 NS_ENSURE_STATE(mAppWindow);
90 nsCOMPtr<nsIDocShell> shell;
91 mAppWindow->GetDocShell(getter_AddRefs(shell));
92 if (shell) return shell->QueryInterface(aIID, aSink);
93 return NS_ERROR_FAILURE;
96 if (aIID.Equals(NS_GET_IID(nsIDOMWindow)) ||
97 aIID.Equals(NS_GET_IID(nsPIDOMWindowOuter))) {
98 NS_ENSURE_STATE(mAppWindow);
99 nsCOMPtr<nsIDocShellTreeItem> shell;
100 mAppWindow->GetPrimaryContentShell(getter_AddRefs(shell));
101 if (shell) {
102 nsCOMPtr<nsIInterfaceRequestor> thing(do_QueryInterface(shell));
103 if (thing) return thing->GetInterface(aIID, aSink);
105 return NS_ERROR_FAILURE;
108 if (aIID.Equals(NS_GET_IID(nsIAppWindow))) {
109 NS_ENSURE_STATE(mAppWindow);
110 return mAppWindow->QueryInterface(aIID, aSink);
113 return QueryInterface(aIID, aSink);
116 //*****************************************************************************
117 // nsContentTreeOwner::nsIDocShellTreeOwner
118 //*****************************************************************************
120 NS_IMETHODIMP
121 nsContentTreeOwner::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
122 bool aPrimary) {
123 NS_ENSURE_STATE(mAppWindow);
124 return mAppWindow->ContentShellAdded(aContentShell, aPrimary);
127 NS_IMETHODIMP
128 nsContentTreeOwner::ContentShellRemoved(nsIDocShellTreeItem* aContentShell) {
129 NS_ENSURE_STATE(mAppWindow);
130 return mAppWindow->ContentShellRemoved(aContentShell);
133 NS_IMETHODIMP
134 nsContentTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell) {
135 NS_ENSURE_STATE(mAppWindow);
136 return mAppWindow->GetPrimaryContentShell(aShell);
139 NS_IMETHODIMP
140 nsContentTreeOwner::RemoteTabAdded(nsIRemoteTab* aTab, bool aPrimary) {
141 NS_ENSURE_STATE(mAppWindow);
142 return mAppWindow->RemoteTabAdded(aTab, aPrimary);
145 NS_IMETHODIMP
146 nsContentTreeOwner::RemoteTabRemoved(nsIRemoteTab* aTab) {
147 NS_ENSURE_STATE(mAppWindow);
148 return mAppWindow->RemoteTabRemoved(aTab);
151 NS_IMETHODIMP
152 nsContentTreeOwner::GetPrimaryRemoteTab(nsIRemoteTab** aTab) {
153 NS_ENSURE_STATE(mAppWindow);
154 return mAppWindow->GetPrimaryRemoteTab(aTab);
157 NS_IMETHODIMP
158 nsContentTreeOwner::GetPrimaryContentBrowsingContext(
159 mozilla::dom::BrowsingContext** aBc) {
160 NS_ENSURE_STATE(mAppWindow);
161 return mAppWindow->GetPrimaryContentBrowsingContext(aBc);
164 NS_IMETHODIMP
165 nsContentTreeOwner::GetPrimaryContentSize(int32_t* aWidth, int32_t* aHeight) {
166 NS_ENSURE_STATE(mAppWindow);
167 return mAppWindow->GetPrimaryContentSize(aWidth, aHeight);
170 NS_IMETHODIMP
171 nsContentTreeOwner::SetPrimaryContentSize(int32_t aWidth, int32_t aHeight) {
172 NS_ENSURE_STATE(mAppWindow);
173 return mAppWindow->SetPrimaryContentSize(aWidth, aHeight);
176 NS_IMETHODIMP
177 nsContentTreeOwner::GetRootShellSize(int32_t* aWidth, int32_t* aHeight) {
178 NS_ENSURE_STATE(mAppWindow);
179 return mAppWindow->GetRootShellSize(aWidth, aHeight);
182 NS_IMETHODIMP
183 nsContentTreeOwner::SetRootShellSize(int32_t aWidth, int32_t aHeight) {
184 NS_ENSURE_STATE(mAppWindow);
185 return mAppWindow->SetRootShellSize(aWidth, aHeight);
188 NS_IMETHODIMP nsContentTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
189 int32_t aCX, int32_t aCY) {
190 NS_ENSURE_STATE(mAppWindow);
191 return mAppWindow->SizeShellTo(aShellItem, aCX, aCY);
194 NS_IMETHODIMP
195 nsContentTreeOwner::SetPersistence(bool aPersistPosition, bool aPersistSize,
196 bool aPersistSizeMode) {
197 NS_ENSURE_STATE(mAppWindow);
198 nsCOMPtr<dom::Element> docShellElement = mAppWindow->GetWindowDOMElement();
199 if (!docShellElement) return NS_ERROR_FAILURE;
201 nsAutoString persistString;
202 docShellElement->GetAttr(nsGkAtoms::persist, persistString);
204 bool saveString = false;
205 int32_t index;
207 // Set X
208 index = persistString.Find(u"screenX");
209 if (!aPersistPosition && index >= 0) {
210 persistString.Cut(index, 7);
211 saveString = true;
212 } else if (aPersistPosition && index < 0) {
213 persistString.AppendLiteral(" screenX");
214 saveString = true;
216 // Set Y
217 index = persistString.Find(u"screenY");
218 if (!aPersistPosition && index >= 0) {
219 persistString.Cut(index, 7);
220 saveString = true;
221 } else if (aPersistPosition && index < 0) {
222 persistString.AppendLiteral(" screenY");
223 saveString = true;
225 // Set CX
226 index = persistString.Find(u"width");
227 if (!aPersistSize && index >= 0) {
228 persistString.Cut(index, 5);
229 saveString = true;
230 } else if (aPersistSize && index < 0) {
231 persistString.AppendLiteral(" width");
232 saveString = true;
234 // Set CY
235 index = persistString.Find(u"height");
236 if (!aPersistSize && index >= 0) {
237 persistString.Cut(index, 6);
238 saveString = true;
239 } else if (aPersistSize && index < 0) {
240 persistString.AppendLiteral(" height");
241 saveString = true;
243 // Set SizeMode
244 index = persistString.Find(u"sizemode");
245 if (!aPersistSizeMode && (index >= 0)) {
246 persistString.Cut(index, 8);
247 saveString = true;
248 } else if (aPersistSizeMode && (index < 0)) {
249 persistString.AppendLiteral(" sizemode");
250 saveString = true;
253 ErrorResult rv;
254 if (saveString) {
255 docShellElement->SetAttribute(u"persist"_ns, persistString, rv);
258 return NS_OK;
261 NS_IMETHODIMP
262 nsContentTreeOwner::GetPersistence(bool* aPersistPosition, bool* aPersistSize,
263 bool* aPersistSizeMode) {
264 NS_ENSURE_STATE(mAppWindow);
265 nsCOMPtr<dom::Element> docShellElement = mAppWindow->GetWindowDOMElement();
266 if (!docShellElement) return NS_ERROR_FAILURE;
268 nsAutoString persistString;
269 docShellElement->GetAttr(nsGkAtoms::persist, persistString);
271 // data structure doesn't quite match the question, but it's close enough
272 // for what we want (since this method is never actually called...)
273 if (aPersistPosition) {
274 *aPersistPosition = persistString.Find(u"screenX") >= 0 ||
275 persistString.Find(u"screenY") >= 0;
277 if (aPersistSize) {
278 *aPersistSize =
279 persistString.Find(u"width") >= 0 || persistString.Find(u"height") >= 0;
281 if (aPersistSizeMode) {
282 *aPersistSizeMode = persistString.Find(u"sizemode") >= 0;
285 return NS_OK;
288 NS_IMETHODIMP
289 nsContentTreeOwner::GetTabCount(uint32_t* aResult) {
290 if (mAppWindow) {
291 return mAppWindow->GetTabCount(aResult);
294 *aResult = 0;
295 return NS_OK;
298 NS_IMETHODIMP
299 nsContentTreeOwner::GetHasPrimaryContent(bool* aResult) {
300 NS_ENSURE_STATE(mAppWindow);
301 return mAppWindow->GetHasPrimaryContent(aResult);
304 //*****************************************************************************
305 // nsContentTreeOwner::nsIWebBrowserChrome
306 //*****************************************************************************
308 NS_IMETHODIMP nsContentTreeOwner::SetLinkStatus(const nsAString& aStatusText) {
309 NS_ENSURE_STATE(mAppWindow);
311 nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
312 mAppWindow->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
314 if (xulBrowserWindow) {
315 xulBrowserWindow->SetOverLink(aStatusText);
318 return NS_OK;
321 NS_IMETHODIMP nsContentTreeOwner::SetChromeFlags(uint32_t aChromeFlags) {
322 NS_ENSURE_STATE(mAppWindow);
323 return mAppWindow->SetChromeFlags(aChromeFlags);
326 NS_IMETHODIMP nsContentTreeOwner::GetChromeFlags(uint32_t* aChromeFlags) {
327 NS_ENSURE_STATE(mAppWindow);
328 return mAppWindow->GetChromeFlags(aChromeFlags);
331 NS_IMETHODIMP nsContentTreeOwner::ShowAsModal() {
332 NS_ENSURE_STATE(mAppWindow);
333 return mAppWindow->ShowModal();
336 NS_IMETHODIMP nsContentTreeOwner::IsWindowModal(bool* _retval) {
337 NS_ENSURE_STATE(mAppWindow);
338 *_retval = mAppWindow->mContinueModalLoop;
339 return NS_OK;
342 //*****************************************************************************
343 // nsContentTreeOwner::nsIBaseWindow
344 //*****************************************************************************
346 NS_IMETHODIMP nsContentTreeOwner::InitWindow(nativeWindow aParentNativeWindow,
347 nsIWidget* parentWidget, int32_t x,
348 int32_t y, int32_t cx,
349 int32_t cy) {
350 // Ignore wigdet parents for now. Don't think those are a vaild thing to
351 // call.
352 NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, 0), NS_ERROR_FAILURE);
354 return NS_OK;
357 NS_IMETHODIMP nsContentTreeOwner::Destroy() {
358 NS_ENSURE_STATE(mAppWindow);
359 return mAppWindow->Destroy();
362 double nsContentTreeOwner::GetWidgetCSSToDeviceScale() {
363 return mAppWindow ? mAppWindow->GetWidgetCSSToDeviceScale() : 1.0;
366 NS_IMETHODIMP nsContentTreeOwner::GetDevicePixelsPerDesktopPixel(
367 double* aScale) {
368 NS_ENSURE_STATE(mAppWindow);
369 return mAppWindow->GetDevicePixelsPerDesktopPixel(aScale);
372 NS_IMETHODIMP nsContentTreeOwner::SetPositionDesktopPix(int32_t aX,
373 int32_t aY) {
374 NS_ENSURE_STATE(mAppWindow);
375 return mAppWindow->SetPositionDesktopPix(aX, aY);
378 NS_IMETHODIMP nsContentTreeOwner::SetPosition(int32_t aX, int32_t aY) {
379 NS_ENSURE_STATE(mAppWindow);
380 return mAppWindow->SetPosition(aX, aY);
383 NS_IMETHODIMP nsContentTreeOwner::GetPosition(int32_t* aX, int32_t* aY) {
384 NS_ENSURE_STATE(mAppWindow);
385 return mAppWindow->GetPosition(aX, aY);
388 NS_IMETHODIMP nsContentTreeOwner::SetSize(int32_t aCX, int32_t aCY,
389 bool aRepaint) {
390 NS_ENSURE_STATE(mAppWindow);
391 return mAppWindow->SetSize(aCX, aCY, aRepaint);
394 NS_IMETHODIMP nsContentTreeOwner::GetSize(int32_t* aCX, int32_t* aCY) {
395 NS_ENSURE_STATE(mAppWindow);
396 return mAppWindow->GetSize(aCX, aCY);
399 NS_IMETHODIMP nsContentTreeOwner::SetPositionAndSize(int32_t aX, int32_t aY,
400 int32_t aCX, int32_t aCY,
401 uint32_t aFlags) {
402 NS_ENSURE_STATE(mAppWindow);
403 return mAppWindow->SetPositionAndSize(aX, aY, aCX, aCY, aFlags);
406 NS_IMETHODIMP nsContentTreeOwner::GetPositionAndSize(int32_t* aX, int32_t* aY,
407 int32_t* aCX,
408 int32_t* aCY) {
409 NS_ENSURE_STATE(mAppWindow);
410 return mAppWindow->GetPositionAndSize(aX, aY, aCX, aCY);
413 NS_IMETHODIMP
414 nsContentTreeOwner::SetDimensions(DimensionRequest&& aRequest) {
415 NS_ENSURE_STATE(mAppWindow);
416 if (aRequest.mDimensionKind == DimensionKind::Outer) {
417 return mAppWindow->SetDimensions(std::move(aRequest));
420 MOZ_TRY(aRequest.SupplementFrom(this));
421 return aRequest.ApplyInnerTo(this, /* aAsRootShell */ false);
424 NS_IMETHODIMP
425 nsContentTreeOwner::GetDimensions(DimensionKind aDimensionKind, int32_t* aX,
426 int32_t* aY, int32_t* aCX, int32_t* aCY) {
427 NS_ENSURE_STATE(mAppWindow);
428 if (aDimensionKind == DimensionKind::Outer) {
429 return mAppWindow->GetDimensions(aDimensionKind, aX, aY, aCX, aCY);
431 if (aY || aX) {
432 return NS_ERROR_NOT_IMPLEMENTED;
434 return GetPrimaryContentSize(aCX, aCY);
437 NS_IMETHODIMP nsContentTreeOwner::Repaint(bool aForce) {
438 NS_ENSURE_STATE(mAppWindow);
439 return mAppWindow->Repaint(aForce);
442 NS_IMETHODIMP nsContentTreeOwner::GetParentWidget(nsIWidget** aParentWidget) {
443 NS_ENSURE_STATE(mAppWindow);
444 return mAppWindow->GetParentWidget(aParentWidget);
447 NS_IMETHODIMP nsContentTreeOwner::SetParentWidget(nsIWidget* aParentWidget) {
448 NS_ASSERTION(false, "You can't call this");
449 return NS_ERROR_NOT_IMPLEMENTED;
452 NS_IMETHODIMP nsContentTreeOwner::GetParentNativeWindow(
453 nativeWindow* aParentNativeWindow) {
454 NS_ENSURE_STATE(mAppWindow);
455 return mAppWindow->GetParentNativeWindow(aParentNativeWindow);
458 NS_IMETHODIMP nsContentTreeOwner::SetParentNativeWindow(
459 nativeWindow aParentNativeWindow) {
460 NS_ASSERTION(false, "You can't call this");
461 return NS_ERROR_NOT_IMPLEMENTED;
464 NS_IMETHODIMP nsContentTreeOwner::GetNativeHandle(nsAString& aNativeHandle) {
465 NS_ENSURE_STATE(mAppWindow);
466 return mAppWindow->GetNativeHandle(aNativeHandle);
469 NS_IMETHODIMP nsContentTreeOwner::GetVisibility(bool* aVisibility) {
470 NS_ENSURE_STATE(mAppWindow);
471 return mAppWindow->GetVisibility(aVisibility);
474 NS_IMETHODIMP nsContentTreeOwner::SetVisibility(bool aVisibility) {
475 NS_ENSURE_STATE(mAppWindow);
476 return mAppWindow->SetVisibility(aVisibility);
479 NS_IMETHODIMP nsContentTreeOwner::GetEnabled(bool* aEnabled) {
480 NS_ENSURE_STATE(mAppWindow);
481 return mAppWindow->GetEnabled(aEnabled);
484 NS_IMETHODIMP nsContentTreeOwner::SetEnabled(bool aEnable) {
485 NS_ENSURE_STATE(mAppWindow);
486 return mAppWindow->SetEnabled(aEnable);
489 NS_IMETHODIMP nsContentTreeOwner::GetMainWidget(nsIWidget** aMainWidget) {
490 NS_ENSURE_ARG_POINTER(aMainWidget);
491 NS_ENSURE_STATE(mAppWindow);
493 *aMainWidget = mAppWindow->mWindow;
494 NS_IF_ADDREF(*aMainWidget);
496 return NS_OK;
499 NS_IMETHODIMP nsContentTreeOwner::GetTitle(nsAString& aTitle) {
500 NS_ENSURE_STATE(mAppWindow);
502 return mAppWindow->GetTitle(aTitle);
505 NS_IMETHODIMP nsContentTreeOwner::SetTitle(const nsAString& aTitle) {
506 return NS_OK;
509 //*****************************************************************************
510 // nsContentTreeOwner: nsIWindowProvider
511 //*****************************************************************************
512 NS_IMETHODIMP
513 nsContentTreeOwner::ProvideWindow(
514 nsIOpenWindowInfo* aOpenWindowInfo, uint32_t aChromeFlags,
515 bool aCalledFromJS, nsIURI* aURI, const nsAString& aName,
516 const nsACString& aFeatures, bool aForceNoOpener, bool aForceNoReferrer,
517 bool aIsPopupRequested, nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
518 dom::BrowsingContext** aReturn) {
519 NS_ENSURE_ARG_POINTER(aOpenWindowInfo);
521 RefPtr<dom::BrowsingContext> parent = aOpenWindowInfo->GetParent();
523 *aReturn = nullptr;
525 if (!mAppWindow) {
526 // Nothing to do here
527 return NS_OK;
530 #ifdef DEBUG
531 nsCOMPtr<nsIDocShell> docshell = parent->GetDocShell();
532 nsCOMPtr<nsIDocShellTreeOwner> parentOwner = do_GetInterface(docshell);
533 NS_ASSERTION(
534 SameCOMIdentity(parentOwner, static_cast<nsIDocShellTreeOwner*>(this)),
535 "Parent from wrong docshell tree?");
536 #endif
538 int32_t openLocation = nsWindowWatcher::GetWindowOpenLocation(
539 parent->GetDOMWindow(), aChromeFlags, aCalledFromJS,
540 aOpenWindowInfo->GetIsForPrinting());
542 if (openLocation != nsIBrowserDOMWindow::OPEN_NEWTAB &&
543 openLocation != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW &&
544 openLocation != nsIBrowserDOMWindow::OPEN_PRINT_BROWSER) {
545 // Just open a window normally
546 return NS_OK;
549 nsCOMPtr<mozIDOMWindowProxy> domWin;
550 mAppWindow->GetWindowDOMWindow(getter_AddRefs(domWin));
551 if (!domWin || !nsGlobalWindowOuter::Cast(domWin)->IsChromeWindow()) {
552 // Really odd... but whatever
553 NS_WARNING("AppWindow's DOMWindow is not a chrome window");
554 return NS_OK;
557 nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin =
558 nsGlobalWindowOuter::Cast(domWin)->GetBrowserDOMWindow();
559 if (!browserDOMWin) {
560 return NS_OK;
563 *aWindowIsNew = (openLocation != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW);
566 dom::AutoNoJSAPI nojsapi;
568 uint32_t flags = nsIBrowserDOMWindow::OPEN_NEW;
569 if (aForceNoOpener) {
570 flags |= nsIBrowserDOMWindow::OPEN_NO_OPENER;
572 if (aForceNoReferrer) {
573 flags |= nsIBrowserDOMWindow::OPEN_NO_REFERRER;
576 // Get a new rendering area from the browserDOMWin.
577 // Since we are not loading any URI, we follow the principle of least
578 // privilege and use a nullPrincipal as the triggeringPrincipal.
580 // This method handles setting the opener for us, so we don't need to set it
581 // ourselves.
582 RefPtr<NullPrincipal> nullPrincipal =
583 NullPrincipal::CreateWithoutOriginAttributes();
584 return browserDOMWin->CreateContentWindow(aURI, aOpenWindowInfo,
585 openLocation, flags,
586 nullPrincipal, nullptr, aReturn);
590 //*****************************************************************************
591 // nsContentTreeOwner: Accessors
592 //*****************************************************************************
594 void nsContentTreeOwner::AppWindow(mozilla::AppWindow* aAppWindow) {
595 mAppWindow = aAppWindow;
598 mozilla::AppWindow* nsContentTreeOwner::AppWindow() { return mAppWindow; }
600 /* this implementation focuses another window. if there isn't another
601 window to focus, we do nothing. */
602 NS_IMETHODIMP
603 nsContentTreeOwner::Blur() {
604 NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
606 nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
607 nsCOMPtr<nsIAppWindow> appWindow;
608 bool more, foundUs;
611 nsCOMPtr<nsIWindowMediator> windowMediator(
612 do_GetService(kWindowMediatorCID));
613 if (windowMediator) {
614 windowMediator->GetZOrderAppWindowEnumerator(
615 nullptr, true, getter_AddRefs(windowEnumerator));
619 if (!windowEnumerator) return NS_ERROR_FAILURE;
621 // step through the top-level windows
622 foundUs = false;
623 windowEnumerator->HasMoreElements(&more);
624 while (more) {
625 nsCOMPtr<nsISupports> nextWindow;
626 nsCOMPtr<nsIAppWindow> nextAppWindow;
628 windowEnumerator->GetNext(getter_AddRefs(nextWindow));
629 nextAppWindow = do_QueryInterface(nextWindow);
631 // got it!(?)
632 if (foundUs) {
633 appWindow = nextAppWindow;
634 break;
637 // remember the very first one, in case we have to wrap
638 if (!appWindow) appWindow = nextAppWindow;
640 // look for us
641 if (nextAppWindow == mAppWindow) {
642 foundUs = true;
645 windowEnumerator->HasMoreElements(&more);
648 // change focus to the window we just found
649 if (appWindow) {
650 nsCOMPtr<nsIDocShell> docshell;
651 appWindow->GetDocShell(getter_AddRefs(docshell));
652 if (!docshell) {
653 return NS_OK;
656 nsCOMPtr<nsPIDOMWindowOuter> domWindow = docshell->GetWindow();
657 if (domWindow) domWindow->Focus(mozilla::dom::CallerType::System);
659 return NS_OK;