Bug 1405577: Restore the ability to open new windows in new spaces when a window is already in fullscreen mode on macOS. r=mstange
authorStephen A Pohl <spohl.mozilla.bugs@gmail.com>
Wed, 29 Nov 2017 23:14:11 -0500
changeset 446050 84bcb5742e0c0d8d49c8c9605405a5e1dce671e0
parent 446049 7cd350d42970616c0e8285fdaa06175fd500cd82
child 446051 84d925e10c0d939865fd9e92219bddfc9d4cd5c2
child 446131 d4fb75b8f858fc95c023fb81427ddc2004baa861
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1405577
milestone59.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 1405577: Restore the ability to open new windows in new spaces when a window is already in fullscreen mode on macOS. r=mstange
browser/app/macbuild/Contents/Info.plist.in
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/nsWidgetInitData.h
xpfe/appshell/nsAppShellService.cpp
--- a/browser/app/macbuild/Contents/Info.plist.in
+++ b/browser/app/macbuild/Contents/Info.plist.in
@@ -233,16 +233,14 @@
   <true/>
   <key>NSPrincipalClass</key>
   <string>GeckoNSApplication</string>
 	<key>SMPrivilegedExecutables</key>
 	<dict>
 		<key>org.mozilla.updater</key>
 		<string>identifier "org.mozilla.updater" and ((anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9]) or (anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = "43AQ936H96"))</string>
 	</dict>
-  <key>NSDisablePersistence</key>
-  <true/>
   <key>MozillaDeveloperRepoPath</key>
   <string>%MOZ_DEVELOPER_REPO_PATH%</string>
   <key>MozillaDeveloperObjPath</key>
   <string>%MOZ_DEVELOPER_OBJ_PATH%</string>
 </dict>
 </plist>
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -349,17 +349,18 @@ public:
 
     bool InFullScreenMode() const { return mInFullScreenMode; }
 
 protected:
   virtual ~nsCocoaWindow();
 
   nsresult             CreateNativeWindow(const NSRect &aRect,
                                           nsBorderStyle aBorderStyle,
-                                          bool aRectIsFrameRect);
+                                          bool aRectIsFrameRect,
+                                          bool aIsPrivateBrowsing);
   nsresult             CreatePopupContentView(const LayoutDeviceIntRect &aRect,
                                               nsWidgetInitData* aInitData);
   void                 DestroyNativeWindow();
   void                 AdjustWindowShadow();
   void                 SetWindowBackgroundBlur();
   void                 UpdateBounds();
 
   void                 DoResize(double aX, double aY, double aWidth, double aHeight,
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -323,17 +323,17 @@ nsCocoaWindow::Create(nsIWidget* aParent
   mAncestorLink = aParent;
 
   // Applications that use native popups don't want us to create popup windows.
   if ((mWindowType == eWindowType_popup) && UseNativePopupWindows())
     return NS_OK;
 
   nsresult rv =
     CreateNativeWindow(nsCocoaUtils::GeckoRectToCocoaRect(newBounds),
-                       mBorderStyle, false);
+                       mBorderStyle, false, aInitData->mIsPrivateBrowsing);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (mWindowType == eWindowType_popup) {
     if (aInitData->mMouseTransparent) {
       [mWindow setIgnoresMouseEvents:YES];
     }
     // now we can convert newBounds to device pixels for the window we created,
     // as the child view expects a rect expressed in the dev pix of its parent
@@ -385,17 +385,18 @@ static unsigned int WindowMaskForBorderS
 }
 
 // If aRectIsFrameRect, aRect specifies the frame rect of the new window.
 // Otherwise, aRect.x/y specify the position of the window's frame relative to
 // the bottom of the menubar and aRect.width/height specify the size of the
 // content rect.
 nsresult nsCocoaWindow::CreateNativeWindow(const NSRect &aRect,
                                            nsBorderStyle aBorderStyle,
-                                           bool aRectIsFrameRect)
+                                           bool aRectIsFrameRect,
+                                           bool aIsPrivateBrowsing)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   // We default to NSBorderlessWindowMask, add features if needed.
   unsigned int features = NSBorderlessWindowMask;
 
   // Configure the window we will create based on the window type.
   switch (mWindowType)
@@ -483,16 +484,23 @@ nsresult nsCocoaWindow::CreateNativeWind
   // BorderlessWindow class.
   else if (features == NSBorderlessWindowMask)
     windowClass = [BorderlessWindow class];
 
   // Create the window
   mWindow = [[windowClass alloc] initWithContentRect:contentRect styleMask:features 
                                  backing:NSBackingStoreBuffered defer:YES];
 
+  // Make sure that window titles don't leak to disk in private browsing mode
+  // due to macOS' resume feature.
+  [mWindow setRestorable:!aIsPrivateBrowsing];
+  if (aIsPrivateBrowsing) {
+    [mWindow disableSnapshotRestoration];
+  }
+
   // setup our notification delegate. Note that setDelegate: does NOT retain.
   mDelegate = [[WindowDelegate alloc] initWithGeckoWindow:this];
   [mWindow setDelegate:mDelegate];
 
   // Make sure that the content rect we gave has been honored.
   NSRect wantedFrame = [mWindow frameRectForContentRect:contentRect];
   if (!NSEqualRects([mWindow frame], wantedFrame)) {
     // This can happen when the window is not on the primary screen.
@@ -1359,17 +1367,21 @@ nsCocoaWindow::HideWindowChrome(bool aSh
   [contentView removeFromSuperviewWithoutNeedingDisplay];
 
   // Save state (like window title).
   NSMutableDictionary* state = [mWindow exportState];
 
   // Recreate the window with the right border style.
   NSRect frameRect = [mWindow frame];
   DestroyNativeWindow();
-  nsresult rv = CreateNativeWindow(frameRect, aShouldHide ? eBorderStyle_none : mBorderStyle, true);
+  nsresult rv = CreateNativeWindow(frameRect,
+                                   aShouldHide ? eBorderStyle_none :
+                                                 mBorderStyle,
+                                   true,
+                                   mWindow.restorable);
   NS_ENSURE_SUCCESS_VOID(rv);
 
   // Re-import state.
   [mWindow importState:state];
 
   // Reparent the content view.
   [mWindow setContentView:contentView];
   [contentView release];
--- a/widget/nsWidgetInitData.h
+++ b/widget/nsWidgetInitData.h
@@ -101,17 +101,18 @@ struct nsWidgetInitData {
       mListenForResizes(false),
       mUnicode(true),
       mRTL(false),
       mNoAutoHide(false),
       mIsDragPopup(false),
       mIsAnimationSuppressed(false),
       mSupportTranslucency(false),
       mMouseTransparent(false),
-      mHasRemoteContent(false)
+      mHasRemoteContent(false),
+      mIsPrivateBrowsing(false)
   {
   }
 
   nsWindowType  mWindowType;
   nsBorderStyle mBorderStyle;
   nsPopupType   mPopupHint;
   nsPopupLevel  mPopupLevel;
   // B2G multi-screen support. Screen ID is for differentiating screens of
@@ -128,11 +129,12 @@ struct nsWidgetInitData {
   // true if window creation animation is suppressed, e.g. for session restore
   bool          mIsAnimationSuppressed;
   // true if the window should support an alpha channel, if available.
   bool          mSupportTranslucency;
   // true if the window should be transparent to mouse events. Currently this is
   // only valid for eWindowType_popup widgets
   bool          mMouseTransparent;
   bool          mHasRemoteContent;
+  bool          mIsPrivateBrowsing;
 };
 
 #endif // nsWidgetInitData_h__
--- a/xpfe/appshell/nsAppShellService.cpp
+++ b/xpfe/appshell/nsAppShellService.cpp
@@ -728,57 +728,58 @@ nsAppShellService::JustCreateTopWindow(n
     aInitialHeight = 1;
     window->SetIntrinsicallySized(true);
   }
 
   bool center = aChromeMask & nsIWebBrowserChrome::CHROME_CENTER_SCREEN;
 
   widgetInitData.mRTL = LocaleService::GetInstance()->IsAppLocaleRTL();
 
-  nsresult rv = window->Initialize(parent, center ? aParent : nullptr,
-                                   aUrl, aInitialWidth, aInitialHeight,
-                                   aIsHiddenWindow, aOpeningTab,
-                                   aOpenerWindow, widgetInitData);
-
-  NS_ENSURE_SUCCESS(rv, rv);
+  bool isUsingRemoteTabs = mozilla::BrowserTabsRemoteAutostart();
+  if (aChromeMask & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW) {
+    isUsingRemoteTabs = true;
+  }
 
   // Enforce the Private Browsing autoStart pref first.
   bool isPrivateBrowsingWindow =
     Preferences::GetBool("browser.privatebrowsing.autostart");
-  bool isUsingRemoteTabs = mozilla::BrowserTabsRemoteAutostart();
-
   if (aChromeMask & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW) {
     // Caller requested a private window
     isPrivateBrowsingWindow = true;
   }
-  if (aChromeMask & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW) {
-    isUsingRemoteTabs = true;
-  }
+  widgetInitData.mIsPrivateBrowsing = isPrivateBrowsingWindow;
 
+  bool isParentPrivateBrowsingWindow = false;
   nsCOMPtr<mozIDOMWindowProxy> domWin = do_GetInterface(aParent);
   nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(domWin);
   nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(webNav);
-
   if (!isPrivateBrowsingWindow && parentContext) {
     // Ensure that we propagate any existing private browsing status
     // from the parent, even if it will not actually be used
     // as a parent value.
-    isPrivateBrowsingWindow = parentContext->UsePrivateBrowsing();
+    isParentPrivateBrowsingWindow = parentContext->UsePrivateBrowsing();
   }
 
+  nsresult rv = window->Initialize(parent, center ? aParent : nullptr,
+                                   aUrl, aInitialWidth, aInitialHeight,
+                                   aIsHiddenWindow, aOpeningTab,
+                                   aOpenerWindow, widgetInitData);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   if (parentContext) {
     isUsingRemoteTabs = parentContext->UseRemoteTabs();
   }
 
   nsCOMPtr<mozIDOMWindowProxy> newDomWin =
       do_GetInterface(NS_ISUPPORTS_CAST(nsIBaseWindow*, window));
   nsCOMPtr<nsIWebNavigation> newWebNav = do_GetInterface(newDomWin);
   nsCOMPtr<nsILoadContext> thisContext = do_GetInterface(newWebNav);
   if (thisContext) {
-    thisContext->SetPrivateBrowsing(isPrivateBrowsingWindow);
+    thisContext->SetPrivateBrowsing(isPrivateBrowsingWindow ||
+                                    isParentPrivateBrowsingWindow);
     thisContext->SetRemoteTabs(isUsingRemoteTabs);
   }
 
   window.forget(aResult);
   if (parent)
     parent->AddChildWindow(*aResult);
 
   if (center)