Bug 1470510 - Merge nsWebShellWindow into nsXULWindow r=smaug
☠☠ backed out by 75a7a3400888 ☠ ☠
authorBrendan Dahl <bdahl@mozilla.com>
Mon, 04 Nov 2019 16:52:24 +0000
changeset 500407 067a556bb614b3b377581c79367adbc1ae220d24
parent 500406 eaf25cd8fd0357f04a5e25d662e8232c2a366a70
child 500408 5967bf6335748dbdeca580449b34c20a45d8a64a
push id36763
push userrmaries@mozilla.com
push dateMon, 04 Nov 2019 21:44:06 +0000
treeherdermozilla-central@75a7a3400888 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1470510
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1470510 - Merge nsWebShellWindow into nsXULWindow r=smaug nsWebShellWindow is the only class that extends nsXULWindow and only nsWebShellWindows are ever instantiated. Differential Revision: https://phabricator.services.mozilla.com/D51155
dom/base/nsGlobalWindowOuter.cpp
xpfe/appshell/moz.build
xpfe/appshell/nsAppShellService.cpp
xpfe/appshell/nsAppShellService.h
xpfe/appshell/nsWebShellWindow.cpp
xpfe/appshell/nsWebShellWindow.h
xpfe/appshell/nsXULWindow.cpp
xpfe/appshell/nsXULWindow.h
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -1541,17 +1541,17 @@ void nsGlobalWindowOuter::SetInitialPrin
     nsIContentSecurityPolicy* aCSP) {
   // First, grab the subject principal.
   nsCOMPtr<nsIPrincipal> newWindowPrincipal =
       nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
 
   // We should never create windows with an expanded principal.
   // If we have a system principal, make sure we're not using it for a content
   // docshell.
-  // NOTE: Please keep this logic in sync with nsWebShellWindow::Initialize().
+  // NOTE: Please keep this logic in sync with nsXULWindow::Initialize().
   if (nsContentUtils::IsExpandedPrincipal(newWindowPrincipal) ||
       (nsContentUtils::IsSystemPrincipal(newWindowPrincipal) &&
        GetDocShell()->ItemType() != nsIDocShellTreeItem::typeChrome)) {
     newWindowPrincipal = nullptr;
   }
 
   // If there's an existing document, bail if it either:
   if (mDoc) {
--- a/xpfe/appshell/moz.build
+++ b/xpfe/appshell/moz.build
@@ -25,17 +25,16 @@ EXPORTS += [
     'nsAppShellCID.h',
 ]
 
 UNIFIED_SOURCES += [
     'nsAppShellService.cpp',
     'nsAppShellWindowEnumerator.cpp',
     'nsChromeTreeOwner.cpp',
     'nsContentTreeOwner.cpp',
-    'nsWebShellWindow.cpp',
     'nsWindowMediator.cpp',
     'nsXULWindow.cpp',
 ]
 
 XPCOM_MANIFESTS += [
     'components.conf',
 ]
 
--- a/xpfe/appshell/nsAppShellService.cpp
+++ b/xpfe/appshell/nsAppShellService.cpp
@@ -12,17 +12,17 @@
 #include "nsIObserver.h"
 #include "nsIXPConnect.h"
 #include "nsIXULRuntime.h"
 
 #include "nsIWindowMediator.h"
 #include "nsIWindowWatcher.h"
 #include "nsPIWindowWatcher.h"
 #include "nsPIDOMWindow.h"
-#include "nsWebShellWindow.h"
+#include "nsXULWindow.h"
 
 #include "nsWidgetInitData.h"
 #include "nsWidgetsCID.h"
 #include "nsIWidget.h"
 #include "nsIRequestObserver.h"
 #include "nsIEmbeddingSiteWindow.h"
 
 #include "nsAppDirectoryServiceDefs.h"
@@ -128,17 +128,17 @@ nsAppShellService::CreateHiddenWindow() 
   static const char hiddenWindowURL[] = DEFAULT_HIDDENWINDOW_URL;
   uint32_t chromeMask = nsIWebBrowserChrome::CHROME_ALL;
 #endif
 
   nsCOMPtr<nsIURI> url;
   rv = NS_NewURI(getter_AddRefs(url), hiddenWindowURL);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  RefPtr<nsWebShellWindow> newWindow;
+  RefPtr<nsXULWindow> newWindow;
   rv =
       JustCreateTopWindow(nullptr, url, chromeMask, initialWidth, initialHeight,
                           true, nullptr, nullptr, getter_AddRefs(newWindow));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDocShell> docShell;
   newWindow->GetDocShell(getter_AddRefs(docShell));
   if (docShell) {
@@ -170,17 +170,17 @@ nsAppShellService::CreateTopLevelWindow(
     int32_t aInitialWidth, int32_t aInitialHeight, nsIRemoteTab* aOpeningTab,
     mozIDOMWindowProxy* aOpenerWindow, nsIXULWindow** aResult)
 
 {
   nsresult rv;
 
   StartupTimeline::RecordOnce(StartupTimeline::CREATE_TOP_LEVEL_WINDOW);
 
-  RefPtr<nsWebShellWindow> newWindow;
+  RefPtr<nsXULWindow> newWindow;
   rv = JustCreateTopWindow(aParent, aUrl, aChromeMask, aInitialWidth,
                            aInitialHeight, false, aOpeningTab, aOpenerWindow,
                            getter_AddRefs(newWindow));
   newWindow.forget(aResult);
 
   if (NS_SUCCEEDED(rv)) {
     // the addref resulting from this is the owning addref for this window
     RegisterTopLevelWindow(*aResult);
@@ -553,24 +553,24 @@ static bool CheckForFullscreenWindow() {
 
 /*
  * Just do the window-making part of CreateTopLevelWindow
  */
 nsresult nsAppShellService::JustCreateTopWindow(
     nsIXULWindow* aParent, nsIURI* aUrl, uint32_t aChromeMask,
     int32_t aInitialWidth, int32_t aInitialHeight, bool aIsHiddenWindow,
     nsIRemoteTab* aOpeningTab, mozIDOMWindowProxy* aOpenerWindow,
-    nsWebShellWindow** aResult) {
+    nsXULWindow** aResult) {
   *aResult = nullptr;
   NS_ENSURE_STATE(!mXPCOMWillShutDown);
 
   nsCOMPtr<nsIXULWindow> parent;
   if (aChromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT) parent = aParent;
 
-  RefPtr<nsWebShellWindow> window = new nsWebShellWindow(aChromeMask);
+  RefPtr<nsXULWindow> window = new nsXULWindow(aChromeMask);
 
 #ifdef XP_WIN
   // If the parent is currently fullscreen, tell the child to ignore persisted
   // full screen states. This way new browser windows open on top of fullscreen
   // windows normally.
   if (window && CheckForFullscreenWindow()) window->IgnoreXULSizeMode(true);
 #endif
 
--- a/xpfe/appshell/nsAppShellService.h
+++ b/xpfe/appshell/nsAppShellService.h
@@ -5,17 +5,17 @@
 
 #ifndef __nsAppShellService_h
 #define __nsAppShellService_h
 
 #include "nsIAppShellService.h"
 #include "nsIObserver.h"
 
 // Interfaces Needed
-#include "nsWebShellWindow.h"
+#include "nsXULWindow.h"
 #include "nsStringFwd.h"
 #include "nsAutoPtr.h"
 #include "nsIRemoteTab.h"
 #include "mozilla/Attributes.h"
 
 // {0099907D-123C-4853-A46A-43098B5FB68C}
 #define NS_APPSHELLSERVICE_CID                      \
   {                                                 \
@@ -37,20 +37,20 @@ class nsAppShellService final : public n
 
   void EnsureHiddenWindow();
 
   nsresult JustCreateTopWindow(nsIXULWindow* aParent, nsIURI* aUrl,
                                uint32_t aChromeMask, int32_t aInitialWidth,
                                int32_t aInitialHeight, bool aIsHiddenWindow,
                                nsIRemoteTab* aOpeningTab,
                                mozIDOMWindowProxy* aOpenerWindow,
-                               nsWebShellWindow** aResult);
+                               nsXULWindow** aResult);
   uint32_t CalculateWindowZLevel(nsIXULWindow* aParent, uint32_t aChromeMask);
 
-  RefPtr<nsWebShellWindow> mHiddenWindow;
+  RefPtr<nsXULWindow> mHiddenWindow;
   bool mXPCOMWillShutDown;
   bool mXPCOMShuttingDown;
   uint16_t mModalWindowCount;
   bool mApplicationProvidedHiddenWindow;
   uint32_t mScreenId;
 };
 
 #endif
deleted file mode 100644
--- a/xpfe/appshell/nsWebShellWindow.cpp
+++ /dev/null
@@ -1,818 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsWebShellWindow.h"
-
-#include "nsLayoutCID.h"
-#include "nsContentCID.h"
-#include "nsContentList.h"
-#include "nsIWeakReference.h"
-#include "nsIContentViewer.h"
-#include "nsIComponentManager.h"
-#include "nsIServiceManager.h"
-#include "nsIURL.h"
-#include "nsIIOService.h"
-#include "nsIURL.h"
-#include "nsNetCID.h"
-#include "nsIStringBundle.h"
-#include "nsReadableUtils.h"
-
-#include "nsContentUtils.h"
-#include "nsEscape.h"
-#include "nsPIDOMWindow.h"
-#include "nsIWebNavigation.h"
-#include "nsIWindowWatcher.h"
-
-#include "nsWidgetInitData.h"
-#include "nsWidgetsCID.h"
-#include "nsIWidget.h"
-#include "nsIWidgetListener.h"
-
-#include "nsINodeList.h"
-
-#include "nsITimer.h"
-#include "nsXULPopupManager.h"
-
-#include "nsFocusManager.h"
-
-#include "nsIWebProgress.h"
-#include "nsIWebProgressListener.h"
-
-#include "mozilla/dom/Document.h"
-#include "nsIDocumentLoaderFactory.h"
-#include "nsIObserverService.h"
-
-#include "nsIScreenManager.h"
-#include "nsIScreen.h"
-
-#include "nsIContent.h"  // for menus
-#include "nsIScriptSecurityManager.h"
-
-// For calculating size
-#include "nsPresContext.h"
-
-#include "nsIBaseWindow.h"
-#include "nsIDocShellTreeItem.h"
-#include "nsDocShell.h"
-
-#include "mozilla/Attributes.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/EventDispatcher.h"
-#include "mozilla/MouseEvents.h"
-#include "mozilla/PresShell.h"
-
-#include "mozilla/dom/BrowsingContext.h"
-#include "mozilla/dom/LoadURIOptionsBinding.h"
-
-#include "nsPIWindowRoot.h"
-
-#include "gfxPlatform.h"
-
-#ifdef XP_MACOSX
-#  include "nsINativeMenuService.h"
-#  define USE_NATIVE_MENUS
-#endif
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-#define SIZE_PERSISTENCE_TIMEOUT 500  // msec
-
-nsWebShellWindow::nsWebShellWindow(uint32_t aChromeFlags)
-    : nsXULWindow(aChromeFlags),
-      mSPTimerLock("nsWebShellWindow.mSPTimerLock"),
-      mWidgetListenerDelegate(this) {}
-
-nsWebShellWindow::~nsWebShellWindow() {
-  MutexAutoLock lock(mSPTimerLock);
-  if (mSPTimer) mSPTimer->Cancel();
-}
-
-NS_IMPL_ADDREF_INHERITED(nsWebShellWindow, nsXULWindow)
-NS_IMPL_RELEASE_INHERITED(nsWebShellWindow, nsXULWindow)
-
-NS_INTERFACE_MAP_BEGIN(nsWebShellWindow)
-  NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
-NS_INTERFACE_MAP_END_INHERITING(nsXULWindow)
-
-nsresult nsWebShellWindow::Initialize(
-    nsIXULWindow* aParent, nsIXULWindow* aOpener, nsIURI* aUrl,
-    int32_t aInitialWidth, int32_t aInitialHeight, bool aIsHiddenWindow,
-    nsIRemoteTab* aOpeningTab, mozIDOMWindowProxy* aOpenerWindow,
-    nsWidgetInitData& widgetInitData) {
-  nsresult rv;
-  nsCOMPtr<nsIWidget> parentWidget;
-
-  mIsHiddenWindow = aIsHiddenWindow;
-
-  int32_t initialX = 0, initialY = 0;
-  nsCOMPtr<nsIBaseWindow> base(do_QueryInterface(aOpener));
-  if (base) {
-    int32_t x, y, width, height;
-    rv = base->GetPositionAndSize(&x, &y, &width, &height);
-    if (NS_FAILED(rv)) {
-      mOpenerScreenRect.SetEmpty();
-    } else {
-      double scale;
-      if (NS_SUCCEEDED(base->GetUnscaledDevicePixelsPerCSSPixel(&scale))) {
-        mOpenerScreenRect.SetRect(
-            NSToIntRound(x / scale), NSToIntRound(y / scale),
-            NSToIntRound(width / scale), NSToIntRound(height / scale));
-      } else {
-        mOpenerScreenRect.SetRect(x, y, width, height);
-      }
-      initialX = mOpenerScreenRect.X();
-      initialY = mOpenerScreenRect.Y();
-      ConstrainToOpenerScreen(&initialX, &initialY);
-    }
-  }
-
-  // XXX: need to get the default window size from prefs...
-  // Doesn't come from prefs... will come from CSS/XUL/RDF
-  DesktopIntRect deskRect(initialX, initialY, aInitialWidth, aInitialHeight);
-
-  // Create top level window
-  if (gfxPlatform::IsHeadless()) {
-    mWindow = nsIWidget::CreateHeadlessWidget();
-  } else {
-    mWindow = nsIWidget::CreateTopLevelWindow();
-  }
-  if (!mWindow) {
-    return NS_ERROR_FAILURE;
-  }
-
-  /* This next bit is troublesome. We carry two different versions of a pointer
-     to our parent window. One is the parent window's widget, which is passed
-     to our own widget. The other is a weak reference we keep here to our
-     parent WebShellWindow. The former is useful to the widget, and we can't
-     trust its treatment of the parent reference because they're platform-
-     specific. The latter is useful to this class.
-       A better implementation would be one in which the parent keeps strong
-     references to its children and closes them before it allows itself
-     to be closed. This would mimic the behaviour of OSes that support
-     top-level child windows in OSes that do not. Later.
-  */
-  nsCOMPtr<nsIBaseWindow> parentAsWin(do_QueryInterface(aParent));
-  if (parentAsWin) {
-    parentAsWin->GetMainWidget(getter_AddRefs(parentWidget));
-    mParentWindow = do_GetWeakReference(aParent);
-  }
-
-  mWindow->SetWidgetListener(&mWidgetListenerDelegate);
-  rv = mWindow->Create((nsIWidget*)parentWidget,  // Parent nsIWidget
-                       nullptr,                   // Native parent widget
-                       deskRect,                  // Widget dimensions
-                       &widgetInitData);          // Widget initialization data
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  LayoutDeviceIntRect r = mWindow->GetClientBounds();
-  // Match the default background color of content. Important on windows
-  // since we no longer use content child widgets.
-  mWindow->SetBackgroundColor(NS_RGB(255, 255, 255));
-
-  // Create web shell
-  RefPtr<BrowsingContext> openerContext =
-      aOpenerWindow
-          ? nsPIDOMWindowOuter::From(aOpenerWindow)->GetBrowsingContext()
-          : nullptr;
-  RefPtr<BrowsingContext> browsingContext =
-      BrowsingContext::Create(/* aParent */ nullptr, openerContext,
-                              EmptyString(), BrowsingContext::Type::Chrome);
-  mDocShell = nsDocShell::Create(browsingContext);
-  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
-
-  // XXX(nika): This is used to handle propagating opener across remote tab
-  // creation. We should come up with a better system for doing this (probably
-  // based on BrowsingContext).
-  mDocShell->SetOpener(aOpeningTab);
-
-  // Make sure to set the item type on the docshell _before_ calling
-  // Create() so it knows what type it is.
-  nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(mDocShell);
-  NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
-  NS_ENSURE_SUCCESS(EnsureChromeTreeOwner(), NS_ERROR_FAILURE);
-
-  docShellAsItem->SetTreeOwner(mChromeTreeOwner);
-
-  r.MoveTo(0, 0);
-  nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
-  NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nullptr, mWindow, r.X(), r.Y(),
-                                              r.Width(), r.Height()),
-                    NS_ERROR_FAILURE);
-  NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE);
-
-  // Attach a WebProgress listener.during initialization...
-  nsCOMPtr<nsIWebProgress> webProgress(do_GetInterface(mDocShell, &rv));
-  if (webProgress) {
-    webProgress->AddProgressListener(this,
-                                     nsIWebProgress::NOTIFY_STATE_NETWORK);
-  }
-
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
-  if (aOpenerWindow) {
-    BrowsingContext* bc = mDocShell->GetBrowsingContext();
-    BrowsingContext* openerBC =
-        nsPIDOMWindowOuter::From(aOpenerWindow)->GetBrowsingContext();
-    MOZ_DIAGNOSTIC_ASSERT(bc->GetOpenerId() == openerBC->Id());
-    MOZ_DIAGNOSTIC_ASSERT(bc->HadOriginalOpener());
-  }
-#endif
-
-  // Eagerly create an about:blank content viewer with the right principal here,
-  // rather than letting it happening in the upcoming call to
-  // SetInitialPrincipalToSubject. This avoids creating the about:blank document
-  // and then blowing it away with a second one, which can cause problems for
-  // the top-level chrome window case. See bug 789773. Note that we don't accept
-  // expanded principals here, similar to SetInitialPrincipalToSubject.
-  if (nsContentUtils::IsInitialized()) {  // Sometimes this happens really early
-                                          // See bug 793370.
-    MOZ_ASSERT(mDocShell->ItemType() == nsIDocShellTreeItem::typeChrome);
-    nsCOMPtr<nsIPrincipal> principal =
-        nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
-    if (nsContentUtils::IsExpandedPrincipal(principal)) {
-      principal = nullptr;
-    }
-    // Use the subject (or system) principal as the storage principal too until
-    // the new window finishes navigating and gets a real storage principal.
-    rv = mDocShell->CreateAboutBlankContentViewer(principal, principal,
-                                                  /* aCsp = */ nullptr);
-    NS_ENSURE_SUCCESS(rv, rv);
-    RefPtr<Document> doc = mDocShell->GetDocument();
-    NS_ENSURE_TRUE(!!doc, NS_ERROR_FAILURE);
-    doc->SetIsInitialDocument(true);
-  }
-
-  if (nullptr != aUrl) {
-    nsCString tmpStr;
-
-    rv = aUrl->GetSpec(tmpStr);
-    if (NS_FAILED(rv)) return rv;
-
-    NS_ConvertUTF8toUTF16 urlString(tmpStr);
-    nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
-    NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
-
-    LoadURIOptions loadURIOptions;
-    loadURIOptions.mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
-
-    rv = webNav->LoadURI(urlString, loadURIOptions);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return rv;
-}
-
-PresShell* nsWebShellWindow::GetPresShell() {
-  if (!mDocShell) {
-    return nullptr;
-  }
-  return mDocShell->GetPresShell();
-}
-
-bool nsWebShellWindow::WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) {
-  nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
-  if (pm) {
-    nsCOMPtr<nsPIDOMWindowOuter> window =
-        mDocShell ? mDocShell->GetWindow() : nullptr;
-    pm->AdjustPopupsOnWindowChange(window);
-  }
-
-  // Notify all tabs that the widget moved.
-  if (mDocShell && mDocShell->GetWindow()) {
-    nsCOMPtr<EventTarget> eventTarget =
-        mDocShell->GetWindow()->GetTopWindowRoot();
-    nsContentUtils::DispatchChromeEvent(mDocShell->GetDocument(), eventTarget,
-                                        NS_LITERAL_STRING("MozUpdateWindowPos"),
-                                        CanBubble::eNo, Cancelable::eNo,
-                                        nullptr);
-  }
-
-  // Persist position, but not immediately, in case this OS is firing
-  // repeated move events as the user drags the window
-  SetPersistenceTimer(PAD_POSITION);
-  return false;
-}
-
-bool nsWebShellWindow::WindowResized(nsIWidget* aWidget, int32_t aWidth,
-                                     int32_t aHeight) {
-  nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(mDocShell));
-  if (shellAsWin) {
-    shellAsWin->SetPositionAndSize(0, 0, aWidth, aHeight, 0);
-  }
-  // Persist size, but not immediately, in case this OS is firing
-  // repeated size events as the user drags the sizing handle
-  if (!IsLocked()) SetPersistenceTimer(PAD_POSITION | PAD_SIZE | PAD_MISC);
-  return true;
-}
-
-bool nsWebShellWindow::RequestWindowClose(nsIWidget* aWidget) {
-  // Maintain a reference to this as it is about to get destroyed.
-  nsCOMPtr<nsIXULWindow> xulWindow(this);
-
-  nsCOMPtr<nsPIDOMWindowOuter> window(mDocShell ? mDocShell->GetWindow()
-                                                : nullptr);
-  nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(window);
-
-  RefPtr<PresShell> presShell = mDocShell->GetPresShell();
-  if (!presShell) {
-    mozilla::DebugOnly<bool> dying;
-    MOZ_ASSERT(NS_SUCCEEDED(mDocShell->IsBeingDestroyed(&dying)) && dying,
-               "No presShell, but window is not being destroyed");
-  } else if (eventTarget) {
-    RefPtr<nsPresContext> presContext = presShell->GetPresContext();
-
-    nsEventStatus status = nsEventStatus_eIgnore;
-    WidgetMouseEvent event(true, eClose, nullptr, WidgetMouseEvent::eReal);
-    if (NS_SUCCEEDED(EventDispatcher::Dispatch(eventTarget, presContext, &event,
-                                               nullptr, &status)) &&
-        status == nsEventStatus_eConsumeNoDefault)
-      return false;
-  }
-
-  Destroy();
-  return false;
-}
-
-void nsWebShellWindow::SizeModeChanged(nsSizeMode sizeMode) {
-  // An alwaysRaised (or higher) window will hide any newly opened normal
-  // browser windows, so here we just drop a raised window to the normal
-  // zlevel if it's maximized. We make no provision for automatically
-  // re-raising it when restored.
-  if (sizeMode == nsSizeMode_Maximized || sizeMode == nsSizeMode_Fullscreen) {
-    uint32_t zLevel;
-    GetZLevel(&zLevel);
-    if (zLevel > nsIXULWindow::normalZ) SetZLevel(nsIXULWindow::normalZ);
-  }
-  mWindow->SetSizeMode(sizeMode);
-
-  // Persist mode, but not immediately, because in many (all?)
-  // cases this will merge with the similar call in NS_SIZE and
-  // write the attribute values only once.
-  SetPersistenceTimer(PAD_MISC);
-  nsCOMPtr<nsPIDOMWindowOuter> ourWindow =
-      mDocShell ? mDocShell->GetWindow() : nullptr;
-  if (ourWindow) {
-    // Ensure that the fullscreen state is synchronized between
-    // the widget and the outer window object.
-    if (sizeMode == nsSizeMode_Fullscreen) {
-      ourWindow->SetFullScreen(true);
-    } else if (sizeMode != nsSizeMode_Minimized) {
-      if (ourWindow->GetFullScreen()) {
-        // The first SetFullscreenInternal call below ensures that we do
-        // not trigger any fullscreen transition even if the window was
-        // put in fullscreen only for the Fullscreen API. The second
-        // SetFullScreen call ensures that the window really exit from
-        // fullscreen even if it entered fullscreen for both Fullscreen
-        // Mode and Fullscreen API.
-        ourWindow->SetFullscreenInternal(
-            FullscreenReason::ForForceExitFullscreen, false);
-        ourWindow->SetFullScreen(false);
-      }
-    }
-
-    // And always fire a user-defined sizemodechange event on the window
-    ourWindow->DispatchCustomEvent(NS_LITERAL_STRING("sizemodechange"));
-  }
-
-  if (PresShell* presShell = GetPresShell()) {
-    presShell->GetPresContext()->SizeModeChanged(sizeMode);
-  }
-
-  // Note the current implementation of SetSizeMode just stores
-  // the new state; it doesn't actually resize. So here we store
-  // the state and pass the event on to the OS. The day is coming
-  // when we'll handle the event here, and the return result will
-  // then need to be different.
-}
-
-void nsWebShellWindow::UIResolutionChanged() {
-  nsCOMPtr<nsPIDOMWindowOuter> ourWindow =
-      mDocShell ? mDocShell->GetWindow() : nullptr;
-  if (ourWindow) {
-    ourWindow->DispatchCustomEvent(NS_LITERAL_STRING("resolutionchange"));
-  }
-}
-
-void nsWebShellWindow::FullscreenWillChange(bool aInFullscreen) {
-  if (mDocShell) {
-    if (nsCOMPtr<nsPIDOMWindowOuter> ourWindow = mDocShell->GetWindow()) {
-      ourWindow->FullscreenWillChange(aInFullscreen);
-    }
-  }
-}
-
-void nsWebShellWindow::FullscreenChanged(bool aInFullscreen) {
-  if (mDocShell) {
-    if (nsCOMPtr<nsPIDOMWindowOuter> ourWindow = mDocShell->GetWindow()) {
-      ourWindow->FinishFullscreenChange(aInFullscreen);
-    }
-  }
-}
-
-void nsWebShellWindow::OcclusionStateChanged(bool aIsFullyOccluded) {
-  nsCOMPtr<nsPIDOMWindowOuter> ourWindow =
-      mDocShell ? mDocShell->GetWindow() : nullptr;
-  if (ourWindow) {
-    // And always fire a user-defined occlusionstatechange event on the window
-    ourWindow->DispatchCustomEvent(NS_LITERAL_STRING("occlusionstatechange"));
-  }
-}
-
-void nsWebShellWindow::OSToolbarButtonPressed() {
-  // Keep a reference as setting the chrome flags can fire events.
-  nsCOMPtr<nsIXULWindow> xulWindow(this);
-
-  // rjc: don't use "nsIWebBrowserChrome::CHROME_EXTRA"
-  //      due to components with multiple sidebar components
-  //      (such as Mail/News, Addressbook, etc)... and frankly,
-  //      Mac IE, OmniWeb, and other Mac OS X apps all work this way
-  uint32_t chromeMask = (nsIWebBrowserChrome::CHROME_TOOLBAR |
-                         nsIWebBrowserChrome::CHROME_LOCATIONBAR |
-                         nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR);
-
-  nsCOMPtr<nsIWebBrowserChrome> wbc(do_GetInterface(xulWindow));
-  if (!wbc) return;
-
-  uint32_t chromeFlags, newChromeFlags = 0;
-  wbc->GetChromeFlags(&chromeFlags);
-  newChromeFlags = chromeFlags & chromeMask;
-  if (!newChromeFlags)
-    chromeFlags |= chromeMask;
-  else
-    chromeFlags &= (~newChromeFlags);
-  wbc->SetChromeFlags(chromeFlags);
-}
-
-bool nsWebShellWindow::ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement,
-                                     nsIWidget* aRequestBelow,
-                                     nsIWidget** aActualBelow) {
-  if (aActualBelow) *aActualBelow = nullptr;
-
-  return ConstrainToZLevel(aImmediate, aPlacement, aRequestBelow, aActualBelow);
-}
-
-void nsWebShellWindow::WindowActivated() {
-  nsCOMPtr<nsIXULWindow> xulWindow(this);
-
-  // focusing the window could cause it to close, so keep a reference to it
-  nsCOMPtr<nsPIDOMWindowOuter> window =
-      mDocShell ? mDocShell->GetWindow() : nullptr;
-  nsFocusManager* fm = nsFocusManager::GetFocusManager();
-  if (fm && window) fm->WindowRaised(window);
-
-  if (mChromeLoaded) {
-    PersistentAttributesDirty(PAD_POSITION | PAD_SIZE | PAD_MISC);
-    SavePersistentAttributes();
-  }
-}
-
-void nsWebShellWindow::WindowDeactivated() {
-  nsCOMPtr<nsIXULWindow> xulWindow(this);
-
-  nsCOMPtr<nsPIDOMWindowOuter> window =
-      mDocShell ? mDocShell->GetWindow() : nullptr;
-  nsFocusManager* fm = nsFocusManager::GetFocusManager();
-  if (fm && window && !fm->IsTestMode()) fm->WindowLowered(window);
-}
-
-#ifdef USE_NATIVE_MENUS
-static void LoadNativeMenus(Document* aDoc, nsIWidget* aParentWindow) {
-  if (gfxPlatform::IsHeadless()) {
-    return;
-  }
-  nsCOMPtr<nsINativeMenuService> nms =
-      do_GetService("@mozilla.org/widget/nativemenuservice;1");
-  if (!nms) {
-    return;
-  }
-
-  // Find the menubar tag (if there is more than one, we ignore all but
-  // the first).
-  nsCOMPtr<nsINodeList> menubarElements = aDoc->GetElementsByTagNameNS(
-      NS_LITERAL_STRING(
-          "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"),
-      NS_LITERAL_STRING("menubar"));
-
-  nsCOMPtr<nsINode> menubarNode;
-  if (menubarElements) {
-    menubarNode = menubarElements->Item(0);
-  }
-
-  if (menubarNode) {
-    nsCOMPtr<Element> menubarContent(do_QueryInterface(menubarNode));
-    nms->CreateNativeMenuBar(aParentWindow, menubarContent);
-  } else {
-    nms->CreateNativeMenuBar(aParentWindow, nullptr);
-  }
-}
-#endif
-
-namespace mozilla {
-
-class WebShellWindowTimerCallback final : public nsITimerCallback,
-                                          public nsINamed {
- public:
-  explicit WebShellWindowTimerCallback(nsWebShellWindow* aWindow)
-      : mWindow(aWindow) {}
-
-  NS_DECL_THREADSAFE_ISUPPORTS
-
-  NS_IMETHOD Notify(nsITimer* aTimer) override {
-    // Although this object participates in a refcount cycle (this -> mWindow
-    // -> mSPTimer -> this), mSPTimer is a one-shot timer and releases this
-    // after it fires.  So we don't need to release mWindow here.
-
-    mWindow->FirePersistenceTimer();
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetName(nsACString& aName) override {
-    aName.AssignLiteral("WebShellWindowTimerCallback");
-    return NS_OK;
-  }
-
- private:
-  ~WebShellWindowTimerCallback() {}
-
-  RefPtr<nsWebShellWindow> mWindow;
-};
-
-NS_IMPL_ISUPPORTS(WebShellWindowTimerCallback, nsITimerCallback, nsINamed)
-
-}  // namespace mozilla
-
-void nsWebShellWindow::SetPersistenceTimer(uint32_t aDirtyFlags) {
-  MutexAutoLock lock(mSPTimerLock);
-  if (!mSPTimer) {
-    mSPTimer = NS_NewTimer();
-    if (!mSPTimer) {
-      NS_WARNING("Couldn't create @mozilla.org/timer;1 instance?");
-      return;
-    }
-  }
-
-  RefPtr<WebShellWindowTimerCallback> callback =
-      new WebShellWindowTimerCallback(this);
-  mSPTimer->InitWithCallback(callback, SIZE_PERSISTENCE_TIMEOUT,
-                             nsITimer::TYPE_ONE_SHOT);
-
-  PersistentAttributesDirty(aDirtyFlags);
-}
-
-void nsWebShellWindow::FirePersistenceTimer() {
-  MutexAutoLock lock(mSPTimerLock);
-  SavePersistentAttributes();
-}
-
-//----------------------------------------
-// nsIWebProgessListener implementation
-//----------------------------------------
-NS_IMETHODIMP
-nsWebShellWindow::OnProgressChange(nsIWebProgress* aProgress,
-                                   nsIRequest* aRequest,
-                                   int32_t aCurSelfProgress,
-                                   int32_t aMaxSelfProgress,
-                                   int32_t aCurTotalProgress,
-                                   int32_t aMaxTotalProgress) {
-  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsWebShellWindow::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
-                                uint32_t aStateFlags, nsresult aStatus) {
-  // If the notification is not about a document finishing, then just
-  // ignore it...
-  if (!(aStateFlags & nsIWebProgressListener::STATE_STOP) ||
-      !(aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK)) {
-    return NS_OK;
-  }
-
-  if (mChromeLoaded) return NS_OK;
-
-  // If this document notification is for a frame then ignore it...
-  nsCOMPtr<mozIDOMWindowProxy> eventWin;
-  aProgress->GetDOMWindow(getter_AddRefs(eventWin));
-  auto* eventPWin = nsPIDOMWindowOuter::From(eventWin);
-  if (eventPWin) {
-    nsPIDOMWindowOuter* rootPWin = eventPWin->GetPrivateRoot();
-    if (eventPWin != rootPWin) return NS_OK;
-  }
-
-  mChromeLoaded = true;
-  mLockedUntilChromeLoad = false;
-
-#ifdef USE_NATIVE_MENUS
-  ///////////////////////////////
-  // Find the Menubar DOM  and Load the menus, hooking them up to the loaded
-  // commands
-  ///////////////////////////////
-  nsCOMPtr<nsIContentViewer> cv;
-  mDocShell->GetContentViewer(getter_AddRefs(cv));
-  if (cv) {
-    RefPtr<Document> menubarDoc = cv->GetDocument();
-    if (menubarDoc) LoadNativeMenus(menubarDoc, mWindow);
-  }
-#endif  // USE_NATIVE_MENUS
-
-  OnChromeLoaded();
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsWebShellWindow::OnLocationChange(nsIWebProgress* aProgress,
-                                   nsIRequest* aRequest, nsIURI* aURI,
-                                   uint32_t aFlags) {
-  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsWebShellWindow::OnStatusChange(nsIWebProgress* aWebProgress,
-                                 nsIRequest* aRequest, nsresult aStatus,
-                                 const char16_t* aMessage) {
-  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsWebShellWindow::OnSecurityChange(nsIWebProgress* aWebProgress,
-                                   nsIRequest* aRequest, uint32_t aState) {
-  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsWebShellWindow::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
-                                         nsIRequest* aRequest,
-                                         uint32_t aEvent) {
-  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
-  return NS_OK;
-}
-
-/**
- * ExecuteCloseHandler - Run the close handler, if any.
- * @return true iff we found a close handler to run.
- */
-bool nsWebShellWindow::ExecuteCloseHandler() {
-  /* If the event handler closes this window -- a likely scenario --
-     things get deleted out of order without this death grip.
-     (The problem may be the death grip in nsWindow::windowProc,
-     which forces this window's widget to remain alive longer
-     than it otherwise would.) */
-  nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
-
-  nsCOMPtr<EventTarget> eventTarget;
-  if (mDocShell) {
-    eventTarget = do_QueryInterface(mDocShell->GetWindow());
-  }
-
-  if (eventTarget) {
-    nsCOMPtr<nsIContentViewer> contentViewer;
-    mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
-    if (contentViewer) {
-      RefPtr<nsPresContext> presContext = contentViewer->GetPresContext();
-
-      nsEventStatus status = nsEventStatus_eIgnore;
-      WidgetMouseEvent event(true, eClose, nullptr, WidgetMouseEvent::eReal);
-
-      nsresult rv = EventDispatcher::Dispatch(eventTarget, presContext, &event,
-                                              nullptr, &status);
-      if (NS_SUCCEEDED(rv) && status == nsEventStatus_eConsumeNoDefault)
-        return true;
-      // else fall through and return false
-    }
-  }
-
-  return false;
-}  // ExecuteCloseHandler
-
-void nsWebShellWindow::ConstrainToOpenerScreen(int32_t* aX, int32_t* aY) {
-  if (mOpenerScreenRect.IsEmpty()) {
-    *aX = *aY = 0;
-    return;
-  }
-
-  int32_t left, top, width, height;
-  // Constrain initial positions to the same screen as opener
-  nsCOMPtr<nsIScreenManager> screenmgr =
-      do_GetService("@mozilla.org/gfx/screenmanager;1");
-  if (screenmgr) {
-    nsCOMPtr<nsIScreen> screen;
-    screenmgr->ScreenForRect(
-        mOpenerScreenRect.X(), mOpenerScreenRect.Y(), mOpenerScreenRect.Width(),
-        mOpenerScreenRect.Height(), getter_AddRefs(screen));
-    if (screen) {
-      screen->GetAvailRectDisplayPix(&left, &top, &width, &height);
-      if (*aX < left || *aX > left + width) {
-        *aX = left;
-      }
-      if (*aY < top || *aY > top + height) {
-        *aY = top;
-      }
-    }
-  }
-}
-
-// nsIBaseWindow
-NS_IMETHODIMP nsWebShellWindow::Destroy() {
-  nsresult rv;
-  nsCOMPtr<nsIWebProgress> webProgress(do_GetInterface(mDocShell, &rv));
-  if (webProgress) {
-    webProgress->RemoveProgressListener(this);
-  }
-
-  nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
-  {
-    MutexAutoLock lock(mSPTimerLock);
-    if (mSPTimer) {
-      mSPTimer->Cancel();
-      SavePersistentAttributes();
-      mSPTimer = nullptr;
-    }
-  }
-  return nsXULWindow::Destroy();
-}
-
-nsIXULWindow* nsWebShellWindow::WidgetListenerDelegate::GetXULWindow() {
-  return mWebShellWindow->GetXULWindow();
-}
-
-PresShell* nsWebShellWindow::WidgetListenerDelegate::GetPresShell() {
-  return mWebShellWindow->GetPresShell();
-}
-
-bool nsWebShellWindow::WidgetListenerDelegate::WindowMoved(nsIWidget* aWidget,
-                                                           int32_t aX,
-                                                           int32_t aY) {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  return holder->WindowMoved(aWidget, aX, aY);
-}
-
-bool nsWebShellWindow::WidgetListenerDelegate::WindowResized(nsIWidget* aWidget,
-                                                             int32_t aWidth,
-                                                             int32_t aHeight) {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  return holder->WindowResized(aWidget, aWidth, aHeight);
-}
-
-bool nsWebShellWindow::WidgetListenerDelegate::RequestWindowClose(
-    nsIWidget* aWidget) {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  return holder->RequestWindowClose(aWidget);
-}
-
-void nsWebShellWindow::WidgetListenerDelegate::SizeModeChanged(
-    nsSizeMode aSizeMode) {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  holder->SizeModeChanged(aSizeMode);
-}
-
-void nsWebShellWindow::WidgetListenerDelegate::UIResolutionChanged() {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  holder->UIResolutionChanged();
-}
-
-void nsWebShellWindow::WidgetListenerDelegate::FullscreenWillChange(
-    bool aInFullscreen) {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  holder->FullscreenWillChange(aInFullscreen);
-}
-
-void nsWebShellWindow::WidgetListenerDelegate::FullscreenChanged(
-    bool aInFullscreen) {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  holder->FullscreenChanged(aInFullscreen);
-}
-
-void nsWebShellWindow::WidgetListenerDelegate::OcclusionStateChanged(
-    bool aIsFullyOccluded) {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  holder->OcclusionStateChanged(aIsFullyOccluded);
-}
-
-void nsWebShellWindow::WidgetListenerDelegate::OSToolbarButtonPressed() {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  holder->OSToolbarButtonPressed();
-}
-
-bool nsWebShellWindow::WidgetListenerDelegate::ZLevelChanged(
-    bool aImmediate, nsWindowZ* aPlacement, nsIWidget* aRequestBelow,
-    nsIWidget** aActualBelow) {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  return holder->ZLevelChanged(aImmediate, aPlacement, aRequestBelow,
-                               aActualBelow);
-}
-
-void nsWebShellWindow::WidgetListenerDelegate::WindowActivated() {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  holder->WindowActivated();
-}
-
-void nsWebShellWindow::WidgetListenerDelegate::WindowDeactivated() {
-  RefPtr<nsWebShellWindow> holder = mWebShellWindow;
-  holder->WindowDeactivated();
-}
deleted file mode 100644
--- a/xpfe/appshell/nsWebShellWindow.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsWebShellWindow_h__
-#define nsWebShellWindow_h__
-
-#include "mozilla/Mutex.h"
-#include "nsIWebProgressListener.h"
-#include "nsITimer.h"
-#include "nsCOMPtr.h"
-#include "nsXULWindow.h"
-#include "nsIWidgetListener.h"
-#include "nsIRemoteTab.h"
-
-/* Forward declarations.... */
-class nsIURI;
-
-struct nsWidgetInitData;
-
-namespace mozilla {
-class PresShell;
-class WebShellWindowTimerCallback;
-}  // namespace mozilla
-
-class nsWebShellWindow final : public nsXULWindow,
-                               public nsIWebProgressListener {
- public:
-  // The implementation of non-refcounted nsIWidgetListener, which would hold a
-  // strong reference on stack before calling nsWebShellWindow's
-  // MOZ_CAN_RUN_SCRIPT methods.
-  class WidgetListenerDelegate : public nsIWidgetListener {
-   public:
-    explicit WidgetListenerDelegate(nsWebShellWindow* aWebShellWindow)
-        : mWebShellWindow(aWebShellWindow) {}
-
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual nsIXULWindow* GetXULWindow() override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual mozilla::PresShell* GetPresShell() override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual bool WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth,
-                               int32_t aHeight) override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual bool RequestWindowClose(nsIWidget* aWidget) override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual void SizeModeChanged(nsSizeMode sizeMode) override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual void UIResolutionChanged() override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual void FullscreenWillChange(bool aInFullscreen) override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual void FullscreenChanged(bool aInFullscreen) override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual void OcclusionStateChanged(bool aIsFullyOccluded) override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual void OSToolbarButtonPressed() override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual bool ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement,
-                               nsIWidget* aRequestBelow,
-                               nsIWidget** aActualBelow) override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual void WindowActivated() override;
-    MOZ_CAN_RUN_SCRIPT_BOUNDARY
-    virtual void WindowDeactivated() override;
-
-   private:
-    // The lifetime of WidgetListenerDelegate is bound to nsWebShellWindow so
-    // we just use a raw pointer here.
-    nsWebShellWindow* mWebShellWindow;
-  };
-
-  explicit nsWebShellWindow(uint32_t aChromeFlags);
-
-  // nsISupports interface...
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsWebShellWindow methods...
-  nsresult Initialize(nsIXULWindow* aParent, nsIXULWindow* aOpener,
-                      nsIURI* aUrl, int32_t aInitialWidth,
-                      int32_t aInitialHeight, bool aIsHiddenWindow,
-                      nsIRemoteTab* aOpeningTab,
-                      mozIDOMWindowProxy* aOpenerWIndow,
-                      nsWidgetInitData& widgetInitData);
-
-  nsresult Toolbar();
-
-  // nsIWebProgressListener
-  NS_DECL_NSIWEBPROGRESSLISTENER
-
-  // nsIBaseWindow
-  NS_IMETHOD Destroy() override;
-
-  // nsIWidgetListener methods for WidgetListenerDelegate.
-  nsIXULWindow* GetXULWindow() { return this; }
-  mozilla::PresShell* GetPresShell();
-  MOZ_CAN_RUN_SCRIPT
-  bool WindowMoved(nsIWidget* aWidget, int32_t aX, int32_t aY);
-  MOZ_CAN_RUN_SCRIPT
-  bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight);
-  MOZ_CAN_RUN_SCRIPT bool RequestWindowClose(nsIWidget* aWidget);
-  MOZ_CAN_RUN_SCRIPT void SizeModeChanged(nsSizeMode aSizeMode);
-  MOZ_CAN_RUN_SCRIPT void UIResolutionChanged();
-  MOZ_CAN_RUN_SCRIPT void FullscreenWillChange(bool aInFullscreen);
-  MOZ_CAN_RUN_SCRIPT void FullscreenChanged(bool aInFullscreen);
-  MOZ_CAN_RUN_SCRIPT void OcclusionStateChanged(bool aIsFullyOccluded);
-  MOZ_CAN_RUN_SCRIPT void OSToolbarButtonPressed();
-  MOZ_CAN_RUN_SCRIPT
-  bool ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement,
-                     nsIWidget* aRequestBelow, nsIWidget** aActualBelow);
-  MOZ_CAN_RUN_SCRIPT void WindowActivated();
-  MOZ_CAN_RUN_SCRIPT void WindowDeactivated();
-
- protected:
-  friend class mozilla::WebShellWindowTimerCallback;
-
-  virtual ~nsWebShellWindow();
-
-  bool ExecuteCloseHandler();
-  void ConstrainToOpenerScreen(int32_t* aX, int32_t* aY);
-
-  nsCOMPtr<nsITimer> mSPTimer;
-  mozilla::Mutex mSPTimerLock;
-  WidgetListenerDelegate mWidgetListenerDelegate;
-
-  void SetPersistenceTimer(uint32_t aDirtyFlags);
-  void FirePersistenceTimer();
-};
-
-#endif /* nsWebShellWindow_h__ */
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -41,37 +41,51 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsIWindowWatcher.h"
 #include "nsIURI.h"
 #include "nsAppShellCID.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsContentUtils.h"
-#include "nsWebShellWindow.h"  // get rid of this one, too...
 #include "nsGlobalWindow.h"
 #include "nsXULTooltipListener.h"
+#include "nsXULPopupManager.h"
+#include "nsFocusManager.h"
+#include "nsContentList.h"
 
 #include "prenv.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/BarProps.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/BrowserHost.h"
 #include "mozilla/dom/BrowserParent.h"
+#include "mozilla/dom/LoadURIOptionsBinding.h"
+#include "mozilla/EventDispatcher.h"
 
 #ifdef MOZ_NEW_XULSTORE
 #  include "mozilla/XULStore.h"
 #endif
 
+#ifdef XP_MACOSX
+#  include "nsINativeMenuService.h"
+#  define USE_NATIVE_MENUS
+#endif
+
 using namespace mozilla;
 using dom::AutoNoJSAPI;
+using dom::BrowserHost;
+using dom::BrowsingContext;
+using dom::Document;
+using dom::EventTarget;
+using dom::LoadURIOptions;
 
 #define SIZEMODE_NORMAL NS_LITERAL_STRING("normal")
 #define SIZEMODE_MAXIMIZED NS_LITERAL_STRING("maximized")
 #define SIZEMODE_MINIMIZED NS_LITERAL_STRING("minimized")
 #define SIZEMODE_FULLSCREEN NS_LITERAL_STRING("fullscreen")
 
 #define WINDOWTYPE_ATTRIBUTE NS_LITERAL_STRING("windowtype")
 
@@ -79,16 +93,18 @@ using dom::AutoNoJSAPI;
 #define SCREENX_ATTRIBUTE NS_LITERAL_STRING("screenX")
 #define SCREENY_ATTRIBUTE NS_LITERAL_STRING("screenY")
 #define WIDTH_ATTRIBUTE NS_LITERAL_STRING("width")
 #define HEIGHT_ATTRIBUTE NS_LITERAL_STRING("height")
 #define MODE_ATTRIBUTE NS_LITERAL_STRING("sizemode")
 #define TILED_ATTRIBUTE NS_LITERAL_STRING("gtktiledwindow")
 #define ZLEVEL_ATTRIBUTE NS_LITERAL_STRING("zlevel")
 
+#define SIZE_PERSISTENCE_TIMEOUT 500  // msec
+
 //*****************************************************************************
 //***    nsXULWindow: Object Management
 //*****************************************************************************
 
 nsXULWindow::nsXULWindow(uint32_t aChromeFlags)
     : mChromeTreeOwner(nullptr),
       mContentTreeOwner(nullptr),
       mPrimaryContentTreeOwner(nullptr),
@@ -106,36 +122,213 @@ nsXULWindow::nsXULWindow(uint32_t aChrom
       mIgnoreXULPosition(false),
       mChromeFlagsFrozen(false),
       mIgnoreXULSizeMode(false),
       mDestroying(false),
       mRegistered(false),
       mPersistentAttributesDirty(0),
       mPersistentAttributesMask(0),
       mChromeFlags(aChromeFlags),
-      mNextRemoteTabId(0) {}
-
-nsXULWindow::~nsXULWindow() { Destroy(); }
+      mNextRemoteTabId(0),
+      mSPTimerLock("nsXULWindow.mSPTimerLock"),
+      mWidgetListenerDelegate(this) {}
+
+nsXULWindow::~nsXULWindow() {
+  {
+    MutexAutoLock lock(mSPTimerLock);
+    if (mSPTimer) mSPTimer->Cancel();
+  }
+  Destroy();
+}
 
 //*****************************************************************************
 // nsXULWindow::nsISupports
 //*****************************************************************************
 
 NS_IMPL_ADDREF(nsXULWindow)
 NS_IMPL_RELEASE(nsXULWindow)
 
 NS_INTERFACE_MAP_BEGIN(nsXULWindow)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULWindow)
   NS_INTERFACE_MAP_ENTRY(nsIXULWindow)
   NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+  NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
   NS_INTERFACE_MAP_ENTRY_CONCRETE(nsXULWindow)
 NS_INTERFACE_MAP_END
 
+nsresult nsXULWindow::Initialize(nsIXULWindow* aParent, nsIXULWindow* aOpener,
+                                 nsIURI* aUrl, int32_t aInitialWidth,
+                                 int32_t aInitialHeight, bool aIsHiddenWindow,
+                                 nsIRemoteTab* aOpeningTab,
+                                 mozIDOMWindowProxy* aOpenerWindow,
+                                 nsWidgetInitData& widgetInitData) {
+  nsresult rv;
+  nsCOMPtr<nsIWidget> parentWidget;
+
+  mIsHiddenWindow = aIsHiddenWindow;
+
+  int32_t initialX = 0, initialY = 0;
+  nsCOMPtr<nsIBaseWindow> base(do_QueryInterface(aOpener));
+  if (base) {
+    int32_t x, y, width, height;
+    rv = base->GetPositionAndSize(&x, &y, &width, &height);
+    if (NS_FAILED(rv)) {
+      mOpenerScreenRect.SetEmpty();
+    } else {
+      double scale;
+      if (NS_SUCCEEDED(base->GetUnscaledDevicePixelsPerCSSPixel(&scale))) {
+        mOpenerScreenRect.SetRect(
+            NSToIntRound(x / scale), NSToIntRound(y / scale),
+            NSToIntRound(width / scale), NSToIntRound(height / scale));
+      } else {
+        mOpenerScreenRect.SetRect(x, y, width, height);
+      }
+      initialX = mOpenerScreenRect.X();
+      initialY = mOpenerScreenRect.Y();
+      ConstrainToOpenerScreen(&initialX, &initialY);
+    }
+  }
+
+  // XXX: need to get the default window size from prefs...
+  // Doesn't come from prefs... will come from CSS/XUL/RDF
+  DesktopIntRect deskRect(initialX, initialY, aInitialWidth, aInitialHeight);
+
+  // Create top level window
+  if (gfxPlatform::IsHeadless()) {
+    mWindow = nsIWidget::CreateHeadlessWidget();
+  } else {
+    mWindow = nsIWidget::CreateTopLevelWindow();
+  }
+  if (!mWindow) {
+    return NS_ERROR_FAILURE;
+  }
+
+  /* This next bit is troublesome. We carry two different versions of a pointer
+     to our parent window. One is the parent window's widget, which is passed
+     to our own widget. The other is a weak reference we keep here to our
+     parent nsXULWindow. The former is useful to the widget, and we can't
+     trust its treatment of the parent reference because they're platform-
+     specific. The latter is useful to this class.
+       A better implementation would be one in which the parent keeps strong
+     references to its children and closes them before it allows itself
+     to be closed. This would mimic the behaviour of OSes that support
+     top-level child windows in OSes that do not. Later.
+  */
+  nsCOMPtr<nsIBaseWindow> parentAsWin(do_QueryInterface(aParent));
+  if (parentAsWin) {
+    parentAsWin->GetMainWidget(getter_AddRefs(parentWidget));
+    mParentWindow = do_GetWeakReference(aParent);
+  }
+
+  mWindow->SetWidgetListener(&mWidgetListenerDelegate);
+  rv = mWindow->Create((nsIWidget*)parentWidget,  // Parent nsIWidget
+                       nullptr,                   // Native parent widget
+                       deskRect,                  // Widget dimensions
+                       &widgetInitData);          // Widget initialization data
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  LayoutDeviceIntRect r = mWindow->GetClientBounds();
+  // Match the default background color of content. Important on windows
+  // since we no longer use content child widgets.
+  mWindow->SetBackgroundColor(NS_RGB(255, 255, 255));
+
+  // Create web shell
+  RefPtr<BrowsingContext> openerContext =
+      aOpenerWindow
+          ? nsPIDOMWindowOuter::From(aOpenerWindow)->GetBrowsingContext()
+          : nullptr;
+  RefPtr<BrowsingContext> browsingContext =
+      BrowsingContext::Create(/* aParent */ nullptr, openerContext,
+                              EmptyString(), BrowsingContext::Type::Chrome);
+  mDocShell = nsDocShell::Create(browsingContext);
+  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
+
+  // XXX(nika): This is used to handle propagating opener across remote tab
+  // creation. We should come up with a better system for doing this (probably
+  // based on BrowsingContext).
+  mDocShell->SetOpener(aOpeningTab);
+
+  // Make sure to set the item type on the docshell _before_ calling
+  // Create() so it knows what type it is.
+  nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(mDocShell);
+  NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
+  NS_ENSURE_SUCCESS(EnsureChromeTreeOwner(), NS_ERROR_FAILURE);
+
+  docShellAsItem->SetTreeOwner(mChromeTreeOwner);
+
+  r.MoveTo(0, 0);
+  nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
+  NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nullptr, mWindow, r.X(), r.Y(),
+                                              r.Width(), r.Height()),
+                    NS_ERROR_FAILURE);
+  NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE);
+
+  // Attach a WebProgress listener.during initialization...
+  nsCOMPtr<nsIWebProgress> webProgress(do_GetInterface(mDocShell, &rv));
+  if (webProgress) {
+    webProgress->AddProgressListener(this,
+                                     nsIWebProgress::NOTIFY_STATE_NETWORK);
+  }
+
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  if (aOpenerWindow) {
+    BrowsingContext* bc = mDocShell->GetBrowsingContext();
+    BrowsingContext* openerBC =
+        nsPIDOMWindowOuter::From(aOpenerWindow)->GetBrowsingContext();
+    MOZ_DIAGNOSTIC_ASSERT(bc->GetOpenerId() == openerBC->Id());
+    MOZ_DIAGNOSTIC_ASSERT(bc->HadOriginalOpener());
+  }
+#endif
+
+  // Eagerly create an about:blank content viewer with the right principal here,
+  // rather than letting it happening in the upcoming call to
+  // SetInitialPrincipalToSubject. This avoids creating the about:blank document
+  // and then blowing it away with a second one, which can cause problems for
+  // the top-level chrome window case. See bug 789773. Note that we don't accept
+  // expanded principals here, similar to SetInitialPrincipalToSubject.
+  if (nsContentUtils::IsInitialized()) {  // Sometimes this happens really early
+                                          // See bug 793370.
+    MOZ_ASSERT(mDocShell->ItemType() == nsIDocShellTreeItem::typeChrome);
+    nsCOMPtr<nsIPrincipal> principal =
+        nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
+    if (nsContentUtils::IsExpandedPrincipal(principal)) {
+      principal = nullptr;
+    }
+    // Use the subject (or system) principal as the storage principal too until
+    // the new window finishes navigating and gets a real storage principal.
+    rv = mDocShell->CreateAboutBlankContentViewer(principal, principal,
+                                                  /* aCsp = */ nullptr);
+    NS_ENSURE_SUCCESS(rv, rv);
+    RefPtr<Document> doc = mDocShell->GetDocument();
+    NS_ENSURE_TRUE(!!doc, NS_ERROR_FAILURE);
+    doc->SetIsInitialDocument(true);
+  }
+
+  if (nullptr != aUrl) {
+    nsCString tmpStr;
+
+    rv = aUrl->GetSpec(tmpStr);
+    if (NS_FAILED(rv)) return rv;
+
+    NS_ConvertUTF8toUTF16 urlString(tmpStr);
+    nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
+    NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
+
+    LoadURIOptions loadURIOptions;
+    loadURIOptions.mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
+
+    rv = webNav->LoadURI(urlString, loadURIOptions);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  return rv;
+}
+
 //*****************************************************************************
 // nsXULWindow::nsIIntefaceRequestor
 //*****************************************************************************
 
 NS_IMETHODIMP nsXULWindow::GetInterface(const nsIID& aIID, void** aSink) {
   nsresult rv;
 
   NS_ENSURE_ARG_POINTER(aSink);
@@ -416,16 +609,32 @@ NS_IMETHODIMP nsXULWindow::InitWindow(na
 
 NS_IMETHODIMP nsXULWindow::Create() {
   // XXX First Check In
   NS_ASSERTION(false, "Not Yet Implemented");
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULWindow::Destroy() {
+  nsresult rv;
+  nsCOMPtr<nsIWebProgress> webProgress(do_GetInterface(mDocShell, &rv));
+  if (webProgress) {
+    webProgress->RemoveProgressListener(this);
+  }
+
+  nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
+  {
+    MutexAutoLock lock(mSPTimerLock);
+    if (mSPTimer) {
+      mSPTimer->Cancel();
+      SavePersistentAttributes();
+      mSPTimer = nullptr;
+    }
+  }
+
   if (!mWindow) return NS_OK;
 
   // Ensure we don't reenter this code
   if (mDestroying) return NS_OK;
 
   mozilla::AutoRestore<bool> guard(mDestroying);
   mDestroying = true;
 
@@ -2491,8 +2700,535 @@ nsresult nsXULWindow::GetTabCount(uint32
   return NS_OK;
 }
 
 nsresult nsXULWindow::GetNextRemoteTabId(uint64_t* aNextRemoteTabId) {
   NS_ENSURE_ARG_POINTER(aNextRemoteTabId);
   *aNextRemoteTabId = mNextRemoteTabId;
   return NS_OK;
 }
+
+PresShell* nsXULWindow::GetPresShell() {
+  if (!mDocShell) {
+    return nullptr;
+  }
+  return mDocShell->GetPresShell();
+}
+
+bool nsXULWindow::WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) {
+  nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
+  if (pm) {
+    nsCOMPtr<nsPIDOMWindowOuter> window =
+        mDocShell ? mDocShell->GetWindow() : nullptr;
+    pm->AdjustPopupsOnWindowChange(window);
+  }
+
+  // Notify all tabs that the widget moved.
+  if (mDocShell && mDocShell->GetWindow()) {
+    nsCOMPtr<EventTarget> eventTarget =
+        mDocShell->GetWindow()->GetTopWindowRoot();
+    nsContentUtils::DispatchChromeEvent(mDocShell->GetDocument(), eventTarget,
+                                        NS_LITERAL_STRING("MozUpdateWindowPos"),
+                                        CanBubble::eNo, Cancelable::eNo,
+                                        nullptr);
+  }
+
+  // Persist position, but not immediately, in case this OS is firing
+  // repeated move events as the user drags the window
+  SetPersistenceTimer(PAD_POSITION);
+  return false;
+}
+
+bool nsXULWindow::WindowResized(nsIWidget* aWidget, int32_t aWidth,
+                                int32_t aHeight) {
+  nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(mDocShell));
+  if (shellAsWin) {
+    shellAsWin->SetPositionAndSize(0, 0, aWidth, aHeight, 0);
+  }
+  // Persist size, but not immediately, in case this OS is firing
+  // repeated size events as the user drags the sizing handle
+  if (!IsLocked()) SetPersistenceTimer(PAD_POSITION | PAD_SIZE | PAD_MISC);
+  return true;
+}
+
+bool nsXULWindow::RequestWindowClose(nsIWidget* aWidget) {
+  // Maintain a reference to this as it is about to get destroyed.
+  nsCOMPtr<nsIXULWindow> xulWindow(this);
+
+  nsCOMPtr<nsPIDOMWindowOuter> window(mDocShell ? mDocShell->GetWindow()
+                                                : nullptr);
+  nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(window);
+
+  RefPtr<PresShell> presShell = mDocShell->GetPresShell();
+  if (!presShell) {
+    mozilla::DebugOnly<bool> dying;
+    MOZ_ASSERT(NS_SUCCEEDED(mDocShell->IsBeingDestroyed(&dying)) && dying,
+               "No presShell, but window is not being destroyed");
+  } else if (eventTarget) {
+    RefPtr<nsPresContext> presContext = presShell->GetPresContext();
+
+    nsEventStatus status = nsEventStatus_eIgnore;
+    WidgetMouseEvent event(true, eClose, nullptr, WidgetMouseEvent::eReal);
+    if (NS_SUCCEEDED(EventDispatcher::Dispatch(eventTarget, presContext, &event,
+                                               nullptr, &status)) &&
+        status == nsEventStatus_eConsumeNoDefault)
+      return false;
+  }
+
+  Destroy();
+  return false;
+}
+
+void nsXULWindow::SizeModeChanged(nsSizeMode sizeMode) {
+  // An alwaysRaised (or higher) window will hide any newly opened normal
+  // browser windows, so here we just drop a raised window to the normal
+  // zlevel if it's maximized. We make no provision for automatically
+  // re-raising it when restored.
+  if (sizeMode == nsSizeMode_Maximized || sizeMode == nsSizeMode_Fullscreen) {
+    uint32_t zLevel;
+    GetZLevel(&zLevel);
+    if (zLevel > nsIXULWindow::normalZ) SetZLevel(nsIXULWindow::normalZ);
+  }
+  mWindow->SetSizeMode(sizeMode);
+
+  // Persist mode, but not immediately, because in many (all?)
+  // cases this will merge with the similar call in NS_SIZE and
+  // write the attribute values only once.
+  SetPersistenceTimer(PAD_MISC);
+  nsCOMPtr<nsPIDOMWindowOuter> ourWindow =
+      mDocShell ? mDocShell->GetWindow() : nullptr;
+  if (ourWindow) {
+    // Ensure that the fullscreen state is synchronized between
+    // the widget and the outer window object.
+    if (sizeMode == nsSizeMode_Fullscreen) {
+      ourWindow->SetFullScreen(true);
+    } else if (sizeMode != nsSizeMode_Minimized) {
+      if (ourWindow->GetFullScreen()) {
+        // The first SetFullscreenInternal call below ensures that we do
+        // not trigger any fullscreen transition even if the window was
+        // put in fullscreen only for the Fullscreen API. The second
+        // SetFullScreen call ensures that the window really exit from
+        // fullscreen even if it entered fullscreen for both Fullscreen
+        // Mode and Fullscreen API.
+        ourWindow->SetFullscreenInternal(
+            FullscreenReason::ForForceExitFullscreen, false);
+        ourWindow->SetFullScreen(false);
+      }
+    }
+
+    // And always fire a user-defined sizemodechange event on the window
+    ourWindow->DispatchCustomEvent(NS_LITERAL_STRING("sizemodechange"));
+  }
+
+  if (PresShell* presShell = GetPresShell()) {
+    presShell->GetPresContext()->SizeModeChanged(sizeMode);
+  }
+
+  // Note the current implementation of SetSizeMode just stores
+  // the new state; it doesn't actually resize. So here we store
+  // the state and pass the event on to the OS. The day is coming
+  // when we'll handle the event here, and the return result will
+  // then need to be different.
+}
+
+void nsXULWindow::UIResolutionChanged() {
+  nsCOMPtr<nsPIDOMWindowOuter> ourWindow =
+      mDocShell ? mDocShell->GetWindow() : nullptr;
+  if (ourWindow) {
+    ourWindow->DispatchCustomEvent(NS_LITERAL_STRING("resolutionchange"));
+  }
+}
+
+void nsXULWindow::FullscreenWillChange(bool aInFullscreen) {
+  if (mDocShell) {
+    if (nsCOMPtr<nsPIDOMWindowOuter> ourWindow = mDocShell->GetWindow()) {
+      ourWindow->FullscreenWillChange(aInFullscreen);
+    }
+  }
+}
+
+void nsXULWindow::FullscreenChanged(bool aInFullscreen) {
+  if (mDocShell) {
+    if (nsCOMPtr<nsPIDOMWindowOuter> ourWindow = mDocShell->GetWindow()) {
+      ourWindow->FinishFullscreenChange(aInFullscreen);
+    }
+  }
+}
+
+void nsXULWindow::OcclusionStateChanged(bool aIsFullyOccluded) {
+  nsCOMPtr<nsPIDOMWindowOuter> ourWindow =
+      mDocShell ? mDocShell->GetWindow() : nullptr;
+  if (ourWindow) {
+    // And always fire a user-defined occlusionstatechange event on the window
+    ourWindow->DispatchCustomEvent(NS_LITERAL_STRING("occlusionstatechange"));
+  }
+}
+
+void nsXULWindow::OSToolbarButtonPressed() {
+  // Keep a reference as setting the chrome flags can fire events.
+  nsCOMPtr<nsIXULWindow> xulWindow(this);
+
+  // rjc: don't use "nsIWebBrowserChrome::CHROME_EXTRA"
+  //      due to components with multiple sidebar components
+  //      (such as Mail/News, Addressbook, etc)... and frankly,
+  //      Mac IE, OmniWeb, and other Mac OS X apps all work this way
+  uint32_t chromeMask = (nsIWebBrowserChrome::CHROME_TOOLBAR |
+                         nsIWebBrowserChrome::CHROME_LOCATIONBAR |
+                         nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR);
+
+  nsCOMPtr<nsIWebBrowserChrome> wbc(do_GetInterface(xulWindow));
+  if (!wbc) return;
+
+  uint32_t chromeFlags, newChromeFlags = 0;
+  wbc->GetChromeFlags(&chromeFlags);
+  newChromeFlags = chromeFlags & chromeMask;
+  if (!newChromeFlags)
+    chromeFlags |= chromeMask;
+  else
+    chromeFlags &= (~newChromeFlags);
+  wbc->SetChromeFlags(chromeFlags);
+}
+
+bool nsXULWindow::ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement,
+                                nsIWidget* aRequestBelow,
+                                nsIWidget** aActualBelow) {
+  if (aActualBelow) *aActualBelow = nullptr;
+
+  return ConstrainToZLevel(aImmediate, aPlacement, aRequestBelow, aActualBelow);
+}
+
+void nsXULWindow::WindowActivated() {
+  nsCOMPtr<nsIXULWindow> xulWindow(this);
+
+  // focusing the window could cause it to close, so keep a reference to it
+  nsCOMPtr<nsPIDOMWindowOuter> window =
+      mDocShell ? mDocShell->GetWindow() : nullptr;
+  nsFocusManager* fm = nsFocusManager::GetFocusManager();
+  if (fm && window) fm->WindowRaised(window);
+
+  if (mChromeLoaded) {
+    PersistentAttributesDirty(PAD_POSITION | PAD_SIZE | PAD_MISC);
+    SavePersistentAttributes();
+  }
+}
+
+void nsXULWindow::WindowDeactivated() {
+  nsCOMPtr<nsIXULWindow> xulWindow(this);
+
+  nsCOMPtr<nsPIDOMWindowOuter> window =
+      mDocShell ? mDocShell->GetWindow() : nullptr;
+  nsFocusManager* fm = nsFocusManager::GetFocusManager();
+  if (fm && window && !fm->IsTestMode()) fm->WindowLowered(window);
+}
+
+#ifdef USE_NATIVE_MENUS
+static void LoadNativeMenus(Document* aDoc, nsIWidget* aParentWindow) {
+  if (gfxPlatform::IsHeadless()) {
+    return;
+  }
+  nsCOMPtr<nsINativeMenuService> nms =
+      do_GetService("@mozilla.org/widget/nativemenuservice;1");
+  if (!nms) {
+    return;
+  }
+
+  // Find the menubar tag (if there is more than one, we ignore all but
+  // the first).
+  nsCOMPtr<nsINodeList> menubarElements = aDoc->GetElementsByTagNameNS(
+      NS_LITERAL_STRING(
+          "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"),
+      NS_LITERAL_STRING("menubar"));
+
+  nsCOMPtr<nsINode> menubarNode;
+  if (menubarElements) {
+    menubarNode = menubarElements->Item(0);
+  }
+
+  if (menubarNode) {
+    nsCOMPtr<Element> menubarContent(do_QueryInterface(menubarNode));
+    nms->CreateNativeMenuBar(aParentWindow, menubarContent);
+  } else {
+    nms->CreateNativeMenuBar(aParentWindow, nullptr);
+  }
+}
+#endif
+
+namespace mozilla {
+
+class nsXULWindowTimerCallback final : public nsITimerCallback,
+                                       public nsINamed {
+ public:
+  explicit nsXULWindowTimerCallback(nsXULWindow* aWindow) : mWindow(aWindow) {}
+
+  NS_DECL_THREADSAFE_ISUPPORTS
+
+  NS_IMETHOD Notify(nsITimer* aTimer) override {
+    // Although this object participates in a refcount cycle (this -> mWindow
+    // -> mSPTimer -> this), mSPTimer is a one-shot timer and releases this
+    // after it fires.  So we don't need to release mWindow here.
+
+    mWindow->FirePersistenceTimer();
+    return NS_OK;
+  }
+
+  NS_IMETHOD GetName(nsACString& aName) override {
+    aName.AssignLiteral("nsXULWindowTimerCallback");
+    return NS_OK;
+  }
+
+ private:
+  ~nsXULWindowTimerCallback() {}
+
+  RefPtr<nsXULWindow> mWindow;
+};
+
+NS_IMPL_ISUPPORTS(nsXULWindowTimerCallback, nsITimerCallback, nsINamed)
+
+}  // namespace mozilla
+
+void nsXULWindow::SetPersistenceTimer(uint32_t aDirtyFlags) {
+  MutexAutoLock lock(mSPTimerLock);
+  if (!mSPTimer) {
+    mSPTimer = NS_NewTimer();
+    if (!mSPTimer) {
+      NS_WARNING("Couldn't create @mozilla.org/timer;1 instance?");
+      return;
+    }
+  }
+
+  RefPtr<nsXULWindowTimerCallback> callback =
+      new nsXULWindowTimerCallback(this);
+  mSPTimer->InitWithCallback(callback, SIZE_PERSISTENCE_TIMEOUT,
+                             nsITimer::TYPE_ONE_SHOT);
+
+  PersistentAttributesDirty(aDirtyFlags);
+}
+
+void nsXULWindow::FirePersistenceTimer() {
+  MutexAutoLock lock(mSPTimerLock);
+  SavePersistentAttributes();
+}
+
+//----------------------------------------
+// nsIWebProgessListener implementation
+//----------------------------------------
+NS_IMETHODIMP
+nsXULWindow::OnProgressChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
+                              int32_t aCurSelfProgress,
+                              int32_t aMaxSelfProgress,
+                              int32_t aCurTotalProgress,
+                              int32_t aMaxTotalProgress) {
+  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULWindow::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
+                           uint32_t aStateFlags, nsresult aStatus) {
+  // If the notification is not about a document finishing, then just
+  // ignore it...
+  if (!(aStateFlags & nsIWebProgressListener::STATE_STOP) ||
+      !(aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK)) {
+    return NS_OK;
+  }
+
+  if (mChromeLoaded) return NS_OK;
+
+  // If this document notification is for a frame then ignore it...
+  nsCOMPtr<mozIDOMWindowProxy> eventWin;
+  aProgress->GetDOMWindow(getter_AddRefs(eventWin));
+  auto* eventPWin = nsPIDOMWindowOuter::From(eventWin);
+  if (eventPWin) {
+    nsPIDOMWindowOuter* rootPWin = eventPWin->GetPrivateRoot();
+    if (eventPWin != rootPWin) return NS_OK;
+  }
+
+  mChromeLoaded = true;
+  mLockedUntilChromeLoad = false;
+
+#ifdef USE_NATIVE_MENUS
+  ///////////////////////////////
+  // Find the Menubar DOM  and Load the menus, hooking them up to the loaded
+  // commands
+  ///////////////////////////////
+  nsCOMPtr<nsIContentViewer> cv;
+  mDocShell->GetContentViewer(getter_AddRefs(cv));
+  if (cv) {
+    RefPtr<Document> menubarDoc = cv->GetDocument();
+    if (menubarDoc) LoadNativeMenus(menubarDoc, mWindow);
+  }
+#endif  // USE_NATIVE_MENUS
+
+  OnChromeLoaded();
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULWindow::OnLocationChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
+                              nsIURI* aURI, uint32_t aFlags) {
+  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULWindow::OnStatusChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
+                            nsresult aStatus, const char16_t* aMessage) {
+  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULWindow::OnSecurityChange(nsIWebProgress* aWebProgress,
+                              nsIRequest* aRequest, uint32_t aState) {
+  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULWindow::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
+                                    nsIRequest* aRequest, uint32_t aEvent) {
+  MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
+  return NS_OK;
+}
+
+/**
+ * ExecuteCloseHandler - Run the close handler, if any.
+ * @return true iff we found a close handler to run.
+ */
+bool nsXULWindow::ExecuteCloseHandler() {
+  /* If the event handler closes this window -- a likely scenario --
+     things get deleted out of order without this death grip.
+     (The problem may be the death grip in nsWindow::windowProc,
+     which forces this window's widget to remain alive longer
+     than it otherwise would.) */
+  nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
+
+  nsCOMPtr<EventTarget> eventTarget;
+  if (mDocShell) {
+    eventTarget = do_QueryInterface(mDocShell->GetWindow());
+  }
+
+  if (eventTarget) {
+    nsCOMPtr<nsIContentViewer> contentViewer;
+    mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
+    if (contentViewer) {
+      RefPtr<nsPresContext> presContext = contentViewer->GetPresContext();
+
+      nsEventStatus status = nsEventStatus_eIgnore;
+      WidgetMouseEvent event(true, eClose, nullptr, WidgetMouseEvent::eReal);
+
+      nsresult rv = EventDispatcher::Dispatch(eventTarget, presContext, &event,
+                                              nullptr, &status);
+      if (NS_SUCCEEDED(rv) && status == nsEventStatus_eConsumeNoDefault)
+        return true;
+      // else fall through and return false
+    }
+  }
+
+  return false;
+}  // ExecuteCloseHandler
+
+void nsXULWindow::ConstrainToOpenerScreen(int32_t* aX, int32_t* aY) {
+  if (mOpenerScreenRect.IsEmpty()) {
+    *aX = *aY = 0;
+    return;
+  }
+
+  int32_t left, top, width, height;
+  // Constrain initial positions to the same screen as opener
+  nsCOMPtr<nsIScreenManager> screenmgr =
+      do_GetService("@mozilla.org/gfx/screenmanager;1");
+  if (screenmgr) {
+    nsCOMPtr<nsIScreen> screen;
+    screenmgr->ScreenForRect(
+        mOpenerScreenRect.X(), mOpenerScreenRect.Y(), mOpenerScreenRect.Width(),
+        mOpenerScreenRect.Height(), getter_AddRefs(screen));
+    if (screen) {
+      screen->GetAvailRectDisplayPix(&left, &top, &width, &height);
+      if (*aX < left || *aX > left + width) {
+        *aX = left;
+      }
+      if (*aY < top || *aY > top + height) {
+        *aY = top;
+      }
+    }
+  }
+}
+
+nsIXULWindow* nsXULWindow::WidgetListenerDelegate::GetXULWindow() {
+  return mXULWindow->GetXULWindow();
+}
+
+PresShell* nsXULWindow::WidgetListenerDelegate::GetPresShell() {
+  return mXULWindow->GetPresShell();
+}
+
+bool nsXULWindow::WidgetListenerDelegate::WindowMoved(nsIWidget* aWidget,
+                                                      int32_t aX, int32_t aY) {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  return holder->WindowMoved(aWidget, aX, aY);
+}
+
+bool nsXULWindow::WidgetListenerDelegate::WindowResized(nsIWidget* aWidget,
+                                                        int32_t aWidth,
+                                                        int32_t aHeight) {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  return holder->WindowResized(aWidget, aWidth, aHeight);
+}
+
+bool nsXULWindow::WidgetListenerDelegate::RequestWindowClose(
+    nsIWidget* aWidget) {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  return holder->RequestWindowClose(aWidget);
+}
+
+void nsXULWindow::WidgetListenerDelegate::SizeModeChanged(
+    nsSizeMode aSizeMode) {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  holder->SizeModeChanged(aSizeMode);
+}
+
+void nsXULWindow::WidgetListenerDelegate::UIResolutionChanged() {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  holder->UIResolutionChanged();
+}
+
+void nsXULWindow::WidgetListenerDelegate::FullscreenWillChange(
+    bool aInFullscreen) {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  holder->FullscreenWillChange(aInFullscreen);
+}
+
+void nsXULWindow::WidgetListenerDelegate::FullscreenChanged(
+    bool aInFullscreen) {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  holder->FullscreenChanged(aInFullscreen);
+}
+
+void nsXULWindow::WidgetListenerDelegate::OcclusionStateChanged(
+    bool aIsFullyOccluded) {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  holder->OcclusionStateChanged(aIsFullyOccluded);
+}
+
+void nsXULWindow::WidgetListenerDelegate::OSToolbarButtonPressed() {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  holder->OSToolbarButtonPressed();
+}
+
+bool nsXULWindow::WidgetListenerDelegate::ZLevelChanged(
+    bool aImmediate, nsWindowZ* aPlacement, nsIWidget* aRequestBelow,
+    nsIWidget** aActualBelow) {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  return holder->ZLevelChanged(aImmediate, aPlacement, aRequestBelow,
+                               aActualBelow);
+}
+
+void nsXULWindow::WidgetListenerDelegate::WindowActivated() {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  holder->WindowActivated();
+}
+
+void nsXULWindow::WidgetListenerDelegate::WindowDeactivated() {
+  RefPtr<nsXULWindow> holder = mXULWindow;
+  holder->WindowDeactivated();
+}
--- a/xpfe/appshell/nsXULWindow.h
+++ b/xpfe/appshell/nsXULWindow.h
@@ -14,85 +14,183 @@
 // Helper classes
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
 #include "nsWeakReference.h"
 #include "nsCOMArray.h"
 #include "nsRect.h"
 #include "Units.h"
+#include "mozilla/Mutex.h"
 
 // Interfaces needed
 #include "nsIBaseWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIXULWindow.h"
 #include "nsIPrompt.h"
 #include "nsIAuthPrompt.h"
 #include "nsIXULBrowserWindow.h"
 #include "nsIWidgetListener.h"
 #include "nsIRemoteTab.h"
+#include "nsIWebProgressListener.h"
+#include "nsITimer.h"
 
 #ifndef MOZ_NEW_XULSTORE
 #  include "nsIXULStore.h"
 #endif
 
 namespace mozilla {
 namespace dom {
 class Element;
 }  // namespace dom
 }  // namespace mozilla
 
 class nsAtom;
 class nsXULTooltipListener;
+struct nsWidgetInitData;
+
+namespace mozilla {
+class PresShell;
+class nsXULWindowTimerCallback;
+}  // namespace mozilla
 
 // nsXULWindow
 
 #define NS_XULWINDOW_IMPL_CID                        \
   { /* 8eaec2f3-ed02-4be2-8e0f-342798477298 */       \
     0x8eaec2f3, 0xed02, 0x4be2, {                    \
       0x8e, 0x0f, 0x34, 0x27, 0x98, 0x47, 0x72, 0x98 \
     }                                                \
   }
 
 class nsContentShellInfo;
 
-class nsXULWindow : public nsIBaseWindow,
-                    public nsIInterfaceRequestor,
-                    public nsIXULWindow,
-                    public nsSupportsWeakReference {
+class nsXULWindow final : public nsIBaseWindow,
+                          public nsIInterfaceRequestor,
+                          public nsIXULWindow,
+                          public nsSupportsWeakReference,
+                          public nsIWebProgressListener {
   friend class nsChromeTreeOwner;
   friend class nsContentTreeOwner;
 
  public:
+  // The implementation of non-refcounted nsIWidgetListener, which would hold a
+  // strong reference on stack before calling nsXULWindow's
+  // MOZ_CAN_RUN_SCRIPT methods.
+  class WidgetListenerDelegate : public nsIWidgetListener {
+   public:
+    explicit WidgetListenerDelegate(nsXULWindow* aXULWindow)
+        : mXULWindow(aXULWindow) {}
+
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual nsIXULWindow* GetXULWindow() override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual mozilla::PresShell* GetPresShell() override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual bool WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth,
+                               int32_t aHeight) override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual bool RequestWindowClose(nsIWidget* aWidget) override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual void SizeModeChanged(nsSizeMode sizeMode) override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual void UIResolutionChanged() override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual void FullscreenWillChange(bool aInFullscreen) override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual void FullscreenChanged(bool aInFullscreen) override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual void OcclusionStateChanged(bool aIsFullyOccluded) override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual void OSToolbarButtonPressed() override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual bool ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement,
+                               nsIWidget* aRequestBelow,
+                               nsIWidget** aActualBelow) override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual void WindowActivated() override;
+    MOZ_CAN_RUN_SCRIPT_BOUNDARY
+    virtual void WindowDeactivated() override;
+
+   private:
+    // The lifetime of WidgetListenerDelegate is bound to nsXULWindow so
+    // we just use a raw pointer here.
+    nsXULWindow* mXULWindow;
+  };
+
   NS_DECL_THREADSAFE_ISUPPORTS
 
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSIXULWINDOW
   NS_DECL_NSIBASEWINDOW
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULWINDOW_IMPL_CID)
 
   void LockUntilChromeLoad() { mLockedUntilChromeLoad = true; }
   bool IsLocked() const { return mLockedUntilChromeLoad; }
   void IgnoreXULSizeMode(bool aEnable) { mIgnoreXULSizeMode = aEnable; }
   void WasRegistered() { mRegistered = true; }
 
+  // nsXULWindow methods...
+  nsresult Initialize(nsIXULWindow* aParent, nsIXULWindow* aOpener,
+                      nsIURI* aUrl, int32_t aInitialWidth,
+                      int32_t aInitialHeight, bool aIsHiddenWindow,
+                      nsIRemoteTab* aOpeningTab,
+                      mozIDOMWindowProxy* aOpenerWIndow,
+                      nsWidgetInitData& widgetInitData);
+
+  nsresult Toolbar();
+
+  // nsIWebProgressListener
+  NS_DECL_NSIWEBPROGRESSLISTENER
+
+  // nsIWidgetListener methods for WidgetListenerDelegate.
+  nsIXULWindow* GetXULWindow() { return this; }
+  mozilla::PresShell* GetPresShell();
+  MOZ_CAN_RUN_SCRIPT
+  bool WindowMoved(nsIWidget* aWidget, int32_t aX, int32_t aY);
+  MOZ_CAN_RUN_SCRIPT
+  bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight);
+  MOZ_CAN_RUN_SCRIPT bool RequestWindowClose(nsIWidget* aWidget);
+  MOZ_CAN_RUN_SCRIPT void SizeModeChanged(nsSizeMode aSizeMode);
+  MOZ_CAN_RUN_SCRIPT void UIResolutionChanged();
+  MOZ_CAN_RUN_SCRIPT void FullscreenWillChange(bool aInFullscreen);
+  MOZ_CAN_RUN_SCRIPT void FullscreenChanged(bool aInFullscreen);
+  MOZ_CAN_RUN_SCRIPT void OcclusionStateChanged(bool aIsFullyOccluded);
+  MOZ_CAN_RUN_SCRIPT void OSToolbarButtonPressed();
+  MOZ_CAN_RUN_SCRIPT
+  bool ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement,
+                     nsIWidget* aRequestBelow, nsIWidget** aActualBelow);
+  MOZ_CAN_RUN_SCRIPT void WindowActivated();
+  MOZ_CAN_RUN_SCRIPT void WindowDeactivated();
+
+  explicit nsXULWindow(uint32_t aChromeFlags);
+
  protected:
   enum persistentAttributes {
     PAD_MISC = 0x1,
     PAD_POSITION = 0x2,
     PAD_SIZE = 0x4
   };
 
-  explicit nsXULWindow(uint32_t aChromeFlags);
   virtual ~nsXULWindow();
 
+  friend class mozilla::nsXULWindowTimerCallback;
+
+  bool ExecuteCloseHandler();
+  void ConstrainToOpenerScreen(int32_t* aX, int32_t* aY);
+
+  void SetPersistenceTimer(uint32_t aDirtyFlags);
+  void FirePersistenceTimer();
+
   NS_IMETHOD EnsureChromeTreeOwner();
   NS_IMETHOD EnsureContentTreeOwner();
   NS_IMETHOD EnsurePrimaryContentTreeOwner();
   NS_IMETHOD EnsurePrompter();
   NS_IMETHOD EnsureAuthPrompter();
   NS_IMETHOD ForceRoundedDimensions();
   NS_IMETHOD GetAvailScreenSize(int32_t* aAvailWidth, int32_t* aAvailHeight);
 
@@ -184,16 +282,20 @@ class nsXULWindow : public nsIBaseWindow
   uint32_t mPersistentAttributesMask;
   uint32_t mChromeFlags;
   uint64_t mNextRemoteTabId;
   nsString mTitle;
   nsIntRect mOpenerScreenRect;  // the screen rect of the opener
 
   nsCOMPtr<nsIRemoteTab> mPrimaryBrowserParent;
 
+  nsCOMPtr<nsITimer> mSPTimer;
+  mozilla::Mutex mSPTimerLock;
+  WidgetListenerDelegate mWidgetListenerDelegate;
+
  private:
   // GetPrimaryBrowserParentSize is called from xpidl methods and we don't have
   // a good way to annotate those with MOZ_CAN_RUN_SCRIPT yet.  It takes no
   // refcounted args other than "this", and the "this" uses seem ok.
   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
   GetPrimaryRemoteTabSize(int32_t* aWidth, int32_t* aHeight);
   nsresult GetPrimaryContentShellSize(int32_t* aWidth, int32_t* aHeight);
   nsresult SetPrimaryRemoteTabSize(int32_t aWidth, int32_t aHeight);