Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/tabs/tab_window_controller.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_window_controller.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #import "base/mac/sdk_forward_declarations.h" | |
| 9 #import "chrome/browser/ui/cocoa/browser_window_layout.h" | 8 #import "chrome/browser/ui/cocoa/browser_window_layout.h" |
| 10 #import "chrome/browser/ui/cocoa/fast_resize_view.h" | 9 #import "chrome/browser/ui/cocoa/fast_resize_view.h" |
| 11 #import "chrome/browser/ui/cocoa/framed_browser_window.h" | 10 #import "chrome/browser/ui/cocoa/framed_browser_window.h" |
| 12 #import "chrome/browser/ui/cocoa/tabs/tab_strip_background_view.h" | 11 #import "chrome/browser/ui/cocoa/tabs/tab_strip_background_view.h" |
| 13 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" | 12 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" |
| 14 #import "chrome/browser/ui/cocoa/themed_window.h" | 13 #import "chrome/browser/ui/cocoa/themed_window.h" |
| 15 #import "ui/base/cocoa/focus_tracker.h" | 14 #import "ui/base/cocoa/focus_tracker.h" |
| 16 #include "ui/base/material_design/material_design_controller.h" | 15 #include "ui/base/material_design/material_design_controller.h" |
| 17 #include "ui/base/theme_provider.h" | 16 #include "ui/base/theme_provider.h" |
| 18 | 17 |
| 19 @interface TabWindowController () | 18 @interface NSWindow (TitlebarAppearsTransparent) |
|
Robert Sesek
2017/01/11 19:23:40
Is this a SPI or is this a forward declaration (in
Sidney San Martín
2017/01/13 00:10:07
It's a redeclaration of a partially-available prop
| |
| 20 - (void)setUseOverlay:(BOOL)useOverlay; | 19 @property BOOL titlebarAppearsTransparent; |
| 21 | |
| 22 // The tab strip background view should always be inserted as the back-most | |
| 23 // subview of the root view. It cannot be a subview of the contentView, as that | |
| 24 // would cause it to become layer backed, which would cause it to draw on top | |
| 25 // of non-layer backed content like the window controls. | |
| 26 - (void)insertTabStripBackgroundViewIntoWindow:(NSWindow*)window | |
| 27 titleBar:(BOOL)hasTitleBar; | |
| 28 | |
| 29 // Called when NSWindowWillEnterFullScreenNotification notification received. | |
| 30 // Makes visual effects view hidden as it should not be displayed in fullscreen. | |
| 31 - (void)windowWillEnterFullScreenNotification:(NSNotification*)notification; | |
| 32 | |
| 33 // Called when NSWindowWillExitFullScreenNotification notification received. | |
| 34 // Makes visual effects view visible since it was hidden in fullscreen. | |
| 35 - (void)windowWillExitFullScreenNotification:(NSNotification*)notification; | |
| 36 | |
| 37 @end | 20 @end |
| 38 | 21 |
| 39 @interface TabWindowOverlayWindow : NSWindow | 22 @interface TabWindowOverlayWindow : NSWindow |
| 40 @end | 23 @end |
| 41 | 24 |
| 42 @implementation TabWindowOverlayWindow | 25 @implementation TabWindowOverlayWindow |
| 43 | 26 |
| 44 - (const ui::ThemeProvider*)themeProvider { | 27 - (const ui::ThemeProvider*)themeProvider { |
| 45 return [[self parentWindow] themeProvider]; | 28 return [[self parentWindow] themeProvider]; |
| 46 } | 29 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 97 // When making a tab dragging window (setUseOverlay:), this view stays in | 80 // When making a tab dragging window (setUseOverlay:), this view stays in |
| 98 // the parent window so that it can be translucent, while the tab strip view | 81 // the parent window so that it can be translucent, while the tab strip view |
| 99 // moves to the child window and stays opaque. | 82 // moves to the child window and stays opaque. |
| 100 NSView* windowView = [window contentView]; | 83 NSView* windowView = [window contentView]; |
| 101 CGFloat paintHeight = [FramedBrowserWindow browserFrameViewPaintHeight]; | 84 CGFloat paintHeight = [FramedBrowserWindow browserFrameViewPaintHeight]; |
| 102 tabStripBackgroundView_.reset([[TabStripBackgroundView alloc] | 85 tabStripBackgroundView_.reset([[TabStripBackgroundView alloc] |
| 103 initWithFrame:NSMakeRect(0, NSMaxY([windowView bounds]) - paintHeight, | 86 initWithFrame:NSMakeRect(0, NSMaxY([windowView bounds]) - paintHeight, |
| 104 NSWidth([windowView bounds]), paintHeight)]); | 87 NSWidth([windowView bounds]), paintHeight)]); |
| 105 [tabStripBackgroundView_ | 88 [tabStripBackgroundView_ |
| 106 setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; | 89 setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; |
| 107 [self insertTabStripBackgroundViewIntoWindow:window titleBar:hasTitleBar]; | |
| 108 | 90 |
| 109 tabStripView_.reset([[TabStripView alloc] | 91 tabStripView_.reset([[TabStripView alloc] |
| 110 initWithFrame:NSMakeRect( | 92 initWithFrame:NSMakeRect( |
| 111 0, 0, kDefaultWidth, chrome::kTabStripHeight)]); | 93 0, 0, kDefaultWidth, chrome::kTabStripHeight)]); |
| 112 [tabStripView_ setAutoresizingMask:NSViewWidthSizable | | 94 [tabStripView_ setAutoresizingMask:NSViewWidthSizable | |
| 113 NSViewMinYMargin]; | 95 NSViewMinYMargin]; |
| 114 if (hasTabStrip) | 96 if (hasTabStrip) |
| 115 [windowView addSubview:tabStripView_]; | 97 [windowView addSubview:tabStripView_]; |
| 116 | 98 |
| 99 if ([window respondsToSelector:@selector(setTitlebarAppearsTransparent:)]) | |
| 100 [window setTitlebarAppearsTransparent:YES]; | |
| 101 | |
| 117 if (chrome::ShouldUseFullSizeContentView()) { | 102 if (chrome::ShouldUseFullSizeContentView()) { |
| 118 // |windowWillEnterFullScreen:| and |windowWillExitFullScreen:| are | 103 [[window contentView] addSubview:tabStripBackgroundView_]; |
| 119 // already called because self is a delegate for the window. However this | 104 } else { |
| 120 // class is designed for subclassing and can not implement | 105 NSView* rootView = [[self.window contentView] superview]; |
| 121 // NSWindowDelegate methods (because subclasses can do so as well and they | 106 [rootView addSubview:tabStripBackgroundView_ |
| 122 // should be able to). TODO(crbug.com/654656): Move |visualEffectView_| to | 107 positioned:NSWindowBelow |
| 123 // subclass. | 108 relativeTo:nil]; |
| 124 [[NSNotificationCenter defaultCenter] | |
| 125 addObserver:self | |
| 126 selector:@selector(windowWillEnterFullScreenNotification:) | |
| 127 name:NSWindowWillEnterFullScreenNotification | |
| 128 object:window]; | |
| 129 [[NSNotificationCenter defaultCenter] | |
| 130 addObserver:self | |
| 131 selector:@selector(windowWillExitFullScreenNotification:) | |
| 132 name:NSWindowWillExitFullScreenNotification | |
| 133 object:window]; | |
| 134 } | 109 } |
| 135 } | 110 } |
| 136 return self; | 111 return self; |
| 137 } | 112 } |
| 138 | 113 |
| 139 - (void)dealloc { | 114 - (void)dealloc { |
| 140 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 115 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 141 [super dealloc]; | 116 [super dealloc]; |
| 142 } | 117 } |
| 143 | 118 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 // followed by RenderWidgetHost::Blur(), which would result in an unexpected | 178 // followed by RenderWidgetHost::Blur(), which would result in an unexpected |
| 204 // loss of focus. | 179 // loss of focus. |
| 205 focusBeforeOverlay_.reset([[FocusTracker alloc] initWithWindow:window]); | 180 focusBeforeOverlay_.reset([[FocusTracker alloc] initWithWindow:window]); |
| 206 [window makeFirstResponder:nil]; | 181 [window makeFirstResponder:nil]; |
| 207 | 182 |
| 208 // Move the original window's tab strip view and content view to the overlay | 183 // Move the original window's tab strip view and content view to the overlay |
| 209 // window. The content view is added as a subview of the overlay window's | 184 // window. The content view is added as a subview of the overlay window's |
| 210 // content view (rather than using setContentView:) because the overlay | 185 // content view (rather than using setContentView:) because the overlay |
| 211 // window has a different content size (due to it being borderless). | 186 // window has a different content size (due to it being borderless). |
| 212 [[overlayWindow_ contentView] addSubview:[self tabStripView]]; | 187 [[overlayWindow_ contentView] addSubview:[self tabStripView]]; |
| 213 [[self tabStripView] setInATabDraggingOverlayWindow:YES]; | 188 tabStripBackgroundView_.get().inATabDraggingOverlayWindow = YES; |
|
Robert Sesek
2017/01/11 19:23:40
Dot notation is not really used in this method. Be
Sidney San Martín
2017/01/13 00:10:07
Done.
| |
| 214 [[overlayWindow_ contentView] addSubview:originalContentView_]; | 189 [[overlayWindow_ contentView] addSubview:originalContentView_]; |
| 215 | 190 |
| 216 [overlayWindow_ orderFront:nil]; | 191 [overlayWindow_ orderFront:nil]; |
| 217 } else if (!useOverlay && overlayWindow_) { | 192 } else if (!useOverlay && overlayWindow_) { |
| 218 DCHECK(originalContentView_); | 193 DCHECK(originalContentView_); |
| 219 | 194 |
| 220 // Return the original window's tab strip view and content view to their | 195 // Return the original window's tab strip view and content view to their |
| 221 // places. The TabStripView always needs to be in front of the window's | 196 // places. The TabStripView always needs to be in front of the window's |
| 222 // content view and therefore it should always be added after the content | 197 // content view and therefore it should always be added after the content |
| 223 // view is set. It needs to be positioned below the avatar button to ensure | 198 // view is set. It needs to be positioned below the avatar button to ensure |
| 224 // that its overlay will not overlap it. | 199 // that its overlay will not overlap it. |
| 225 [[window contentView] addSubview:originalContentView_ | 200 [[window contentView] addSubview:originalContentView_ |
| 226 positioned:NSWindowBelow | 201 positioned:NSWindowBelow |
| 227 relativeTo:nil]; | 202 relativeTo:nil]; |
| 228 originalContentView_.frame = [[window contentView] bounds]; | 203 originalContentView_.frame = [[window contentView] bounds]; |
| 229 [[window contentView] addSubview:[self tabStripView] | 204 [[window contentView] addSubview:[self tabStripView] |
| 230 positioned:NSWindowBelow | 205 positioned:NSWindowBelow |
| 231 relativeTo:[self avatarView]]; | 206 relativeTo:[self avatarView]]; |
| 232 [[self tabStripView] setInATabDraggingOverlayWindow:NO]; | 207 tabStripBackgroundView_.get().inATabDraggingOverlayWindow = NO; |
| 233 [[window contentView] updateTrackingAreas]; | 208 [[window contentView] updateTrackingAreas]; |
| 234 | 209 |
| 235 [focusBeforeOverlay_ restoreFocusInWindow:window]; | 210 [focusBeforeOverlay_ restoreFocusInWindow:window]; |
| 236 focusBeforeOverlay_.reset(); | 211 focusBeforeOverlay_.reset(); |
| 237 | 212 |
| 238 [window display]; | 213 [window display]; |
| 239 [window removeChildWindow:overlayWindow_]; | 214 [window removeChildWindow:overlayWindow_]; |
| 240 | 215 |
| 241 [overlayWindow_ orderOut:nil]; | 216 [overlayWindow_ orderOut:nil]; |
| 242 [overlayWindow_ release]; | 217 [overlayWindow_ release]; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 return YES; | 350 return YES; |
| 376 } | 351 } |
| 377 | 352 |
| 378 // Tell the window that it needs to call performClose: as soon as the current | 353 // Tell the window that it needs to call performClose: as soon as the current |
| 379 // drag is complete. This prevents a window (and its overlay) from going away | 354 // drag is complete. This prevents a window (and its overlay) from going away |
| 380 // during a drag. | 355 // during a drag. |
| 381 - (void)deferPerformClose { | 356 - (void)deferPerformClose { |
| 382 closeDeferred_ = YES; | 357 closeDeferred_ = YES; |
| 383 } | 358 } |
| 384 | 359 |
| 385 - (void)insertTabStripBackgroundViewIntoWindow:(NSWindow*)window | |
| 386 titleBar:(BOOL)hasTitleBar { | |
| 387 DCHECK(tabStripBackgroundView_); | |
| 388 NSView* rootView = [[window contentView] superview]; | |
| 389 | |
| 390 // In Material Design on 10.10 and higher, the top portion of the window is | |
| 391 // blurred using an NSVisualEffectView. | |
| 392 Class nsVisualEffectViewClass = NSClassFromString(@"NSVisualEffectView"); | |
| 393 if (!nsVisualEffectViewClass) { | |
| 394 DCHECK(!chrome::ShouldUseFullSizeContentView()); | |
| 395 [rootView addSubview:tabStripBackgroundView_ | |
| 396 positioned:NSWindowBelow | |
| 397 relativeTo:nil]; | |
| 398 return; | |
| 399 } | |
| 400 | |
| 401 [window setTitlebarAppearsTransparent:YES]; | |
| 402 | |
| 403 // If the window has a normal titlebar, then do not add NSVisualEffectView. | |
| 404 if (hasTitleBar) | |
| 405 return; | |
| 406 | |
| 407 visualEffectView_.reset( | |
| 408 [[nsVisualEffectViewClass alloc] | |
| 409 initWithFrame:[tabStripBackgroundView_ frame]]); | |
| 410 DCHECK(visualEffectView_); | |
| 411 | |
| 412 [visualEffectView_ setAutoresizingMask: | |
| 413 [tabStripBackgroundView_ autoresizingMask]]; | |
| 414 [tabStripBackgroundView_ | |
| 415 setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; | |
| 416 | |
| 417 // Set to a default appearance and material. If this is an Incognito window | |
| 418 // the material and vibrancy should be dark but this method gets called at | |
| 419 // the start of -[BrowserWindowController initWithBrowser:takeOwnership:], | |
| 420 // before the |browser_| ivar has been set. Without a browser object we | |
| 421 // can't check the window's theme. The final setup happens in | |
| 422 // -[TabStripView setController:], at which point we have access to the theme. | |
| 423 [visualEffectView_ setAppearance: | |
| 424 [NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]]; | |
| 425 [visualEffectView_ setMaterial:NSVisualEffectMaterialLight]; | |
| 426 [visualEffectView_ setBlendingMode:NSVisualEffectBlendingModeBehindWindow]; | |
| 427 [visualEffectView_ setState:NSVisualEffectStateFollowsWindowActiveState]; | |
| 428 | |
| 429 if (chrome::ShouldUseFullSizeContentView()) { | |
| 430 [[window contentView] addSubview:visualEffectView_]; | |
| 431 } else { | |
| 432 [rootView addSubview:visualEffectView_ | |
| 433 positioned:NSWindowBelow | |
| 434 relativeTo:nil]; | |
| 435 } | |
| 436 | |
| 437 // Make the |tabStripBackgroundView_| a child of the NSVisualEffectView. | |
| 438 [tabStripBackgroundView_ setFrame:[visualEffectView_ bounds]]; | |
| 439 [visualEffectView_ addSubview:tabStripBackgroundView_]; | |
| 440 } | |
| 441 | |
| 442 // Called when the size of the window content area has changed. Override to | 360 // Called when the size of the window content area has changed. Override to |
| 443 // position specific views. Base class implementation does nothing. | 361 // position specific views. Base class implementation does nothing. |
| 444 - (void)layoutSubviews { | 362 - (void)layoutSubviews { |
| 445 NOTIMPLEMENTED(); | 363 NOTIMPLEMENTED(); |
| 446 } | 364 } |
| 447 | 365 |
| 448 - (void)windowWillEnterFullScreenNotification:(NSNotification*)notification { | |
| 449 [[visualEffectView_ animator] setAlphaValue:0.0]; | |
| 450 } | |
| 451 | |
| 452 - (void)windowWillExitFullScreenNotification:(NSNotification*)notification { | |
| 453 [[visualEffectView_ animator] setAlphaValue:1.0]; | |
| 454 } | |
| 455 | |
| 456 @end | 366 @end |
| OLD | NEW |