Bug 1533562 - Do not move the TitlebarGradientView from a ToolbarWindow into a BorderlessWindow when hiding the window chrome. r=spohl
authorMarkus Stange <mstange@themasta.com>
Mon, 29 Apr 2019 17:00:31 +0000
changeset 471832 7b2d2da6fba84a364a07fc273a6447c5dfd22a06
parent 471831 382967c743c8bdbcb04f5bf369fee5a6f818ea6e
child 471833 7f757830df66f7dd2a865da304fbd45dee6921a9
push id35935
push usershindli@mozilla.com
push dateTue, 30 Apr 2019 03:46:04 +0000
treeherdermozilla-central@f3c2a7206699 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersspohl
bugs1533562
milestone68.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 1533562 - Do not move the TitlebarGradientView from a ToolbarWindow into a BorderlessWindow when hiding the window chrome. r=spohl Differential Revision: https://phabricator.services.mozilla.com/D25516
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -74,16 +74,25 @@ typedef struct _nsCocoaWindowList {
 - (void)mouseMoved:(NSEvent*)aEvent;
 - (void)updateTrackingArea;
 - (NSView*)trackingAreaView;
 
 - (void)setBeingShown:(BOOL)aValue;
 - (BOOL)isBeingShown;
 - (BOOL)isVisibleOrBeingShown;
 
+// Returns an autoreleased NSArray containing the NSViews that we consider the
+// "contents" of this window. All views in the returned array are subviews of
+// this window's content view. However, the array may not include all of the
+// content view's subviews; concretely, the ToolbarWindow implementation will
+// exclude its TitlebarGradientView from the array that is returned here.
+// In the vast majority of cases, the array will only have a single element:
+// this window's mainChildView.
+- (NSArray<NSView*>*)contentViewContents;
+
 - (ChildView*)mainChildView;
 
 - (NSArray*)titlebarControls;
 
 - (void)setWantsTitleDrawn:(BOOL)aDrawTitle;
 - (BOOL)wantsTitleDrawn;
 
 - (void)setUseBrightTitlebarForeground:(BOOL)aBrightForeground;
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -1204,36 +1204,39 @@ void nsCocoaWindow::HideWindowChrome(boo
   // Remove child windows.
   NSArray* childWindows = [mWindow childWindows];
   NSEnumerator* enumerator = [childWindows objectEnumerator];
   NSWindow* child = nil;
   while ((child = [enumerator nextObject])) {
     [mWindow removeChildWindow:child];
   }
 
-  // Remove the content view.
-  NSView* contentView = [mWindow contentView];
-  [contentView retain];
-  [contentView removeFromSuperviewWithoutNeedingDisplay];
+  // Remove the views in the old window's content view.
+  // The NSArray is autoreleased and retains its NSViews.
+  NSArray<NSView*>* contentViewContents = [mWindow contentViewContents];
+  for (NSView* view in contentViewContents) {
+    [view 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);
   NS_ENSURE_SUCCESS_VOID(rv);
 
   // Re-import state.
   [mWindow importState:state];
 
-  // Reparent the content view.
-  [mWindow setContentView:contentView];
-  [contentView release];
+  // Add the old content view subviews to the new window's content view.
+  for (NSView* view in contentViewContents) {
+    [[mWindow contentView] addSubview:view];
+  }
 
   // Reparent child windows.
   enumerator = [childWindows objectEnumerator];
   while ((child = [enumerator nextObject])) {
     [mWindow addChildWindow:child ordered:NSWindowAbove];
   }
 
   // Show the new window.
@@ -2901,16 +2904,20 @@ static const NSString* kStateCollectionB
   return mBrightTitlebarForeground;
 }
 
 - (NSView*)trackingAreaView {
   NSView* contentView = [self contentView];
   return [contentView superview] ? [contentView superview] : contentView;
 }
 
+- (NSArray<NSView*>*)contentViewContents {
+  return [[[[self contentView] subviews] copy] autorelease];
+}
+
 - (ChildView*)mainChildView {
   NSView* contentView = [self contentView];
   NSView* lastView = [[contentView subviews] lastObject];
   if ([lastView isKindOfClass:[ChildView class]]) {
     return (ChildView*)lastView;
   }
   return nil;
 }
@@ -3219,16 +3226,25 @@ static const NSString* kStateCollectionB
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (void)dealloc {
   [mTitlebarGradientView release];
   [super dealloc];
 }
 
+- (NSArray<NSView*>*)contentViewContents {
+  NSMutableArray<NSView*>* contents = [[[self contentView] subviews] mutableCopy];
+  if (mTitlebarGradientView) {
+    // Do not include the titlebar gradient view in the returned array.
+    [contents removeObject:mTitlebarGradientView];
+  }
+  return [contents autorelease];
+}
+
 - (void)updateTitlebarGradientViewPresence {
   BOOL needTitlebarView = ![self drawsContentsIntoWindowFrame];
   if (needTitlebarView && !mTitlebarGradientView) {
     mTitlebarGradientView = [[TitlebarGradientView alloc] initWithFrame:[self titlebarRect]];
     mTitlebarGradientView.autoresizingMask = NSViewWidthSizable | NSViewMinYMargin;
     [self.contentView addSubview:mTitlebarGradientView];
   } else if (!needTitlebarView && mTitlebarGradientView) {
     [mTitlebarGradientView removeFromSuperview];