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/tab_contents/tab_contents_controller.h" | 5 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 } | 64 } |
| 65 | 65 |
| 66 private: | 66 private: |
| 67 TabContentsController* const controller_; | 67 TabContentsController* const controller_; |
| 68 | 68 |
| 69 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver); | 69 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver); |
| 70 }; | 70 }; |
| 71 | 71 |
| 72 @interface TabContentsController (TabContentsContainerViewDelegate) | 72 @interface TabContentsController (TabContentsContainerViewDelegate) |
| 73 - (BOOL)contentsInFullscreenCaptureMode; | 73 - (BOOL)contentsInFullscreenCaptureMode; |
| 74 // Computes and returns the frame to use for the contents view within the | 74 // Computes and returns the frame to use for the contents view using the size of |
| 75 // container view. | 75 // |container| as the target size. |
| 76 - (NSRect)frameForContentsView; | 76 - (NSRect)frameForContentsViewIn:(NSView*)container; |
| 77 | 77 |
| 78 // Returns YES if the content view should be resized. | 78 // Returns YES if the content view should be resized. |
| 79 - (BOOL)shouldResizeContentView; | 79 - (BOOL)shouldResizeContentView; |
| 80 | 80 |
| 81 // Returns YES if the content view is inside a popup. | 81 // Returns YES if the content view is inside a popup. |
| 82 - (BOOL)isPopup; | 82 - (BOOL)isPopup; |
| 83 | 83 |
| 84 @end | 84 @end |
| 85 | 85 |
| 86 // An NSView with special-case handling for when the contents view does not | 86 // An NSView with special-case handling for when the contents view does not |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize { | 123 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize { |
| 124 NSView* const contentsView = | 124 NSView* const contentsView = |
| 125 [[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil; | 125 [[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil; |
| 126 if (!contentsView || [contentsView autoresizingMask] == NSViewNotSizable || | 126 if (!contentsView || [contentsView autoresizingMask] == NSViewNotSizable || |
| 127 !delegate_ || | 127 !delegate_ || |
| 128 (![delegate_ shouldResizeContentView] && [delegate_ isPopup])) { | 128 (![delegate_ shouldResizeContentView] && [delegate_ isPopup])) { |
| 129 return; | 129 return; |
| 130 } | 130 } |
| 131 | 131 |
| 132 ScopedCAActionDisabler disabler; | 132 ScopedCAActionDisabler disabler; |
| 133 [contentsView setFrame:[delegate_ frameForContentsView]]; | 133 [contentsView setFrame:[delegate_ frameForContentsViewIn:self]]; |
| 134 } | 134 } |
| 135 | 135 |
| 136 // Update the background layer's color whenever the view needs to repaint. | 136 // Update the background layer's color whenever the view needs to repaint. |
| 137 - (void)setNeedsDisplayInRect:(NSRect)rect { | 137 - (void)setNeedsDisplayInRect:(NSRect)rect { |
| 138 [super setNeedsDisplayInRect:rect]; | 138 [super setNeedsDisplayInRect:rect]; |
| 139 [self updateBackgroundColor]; | 139 [self updateBackgroundColor]; |
| 140 } | 140 } |
| 141 | 141 |
| 142 - (void)updateBackgroundColor { | 142 - (void)updateBackgroundColor { |
| 143 // This view is sometimes flashed into visibility (e.g, when closing | 143 // This view is sometimes flashed into visibility (e.g, when closing |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 [super dealloc]; | 210 [super dealloc]; |
| 211 } | 211 } |
| 212 | 212 |
| 213 - (void)loadView { | 213 - (void)loadView { |
| 214 base::scoped_nsobject<NSView> view( | 214 base::scoped_nsobject<NSView> view( |
| 215 [[TabContentsContainerView alloc] initWithDelegate:self]); | 215 [[TabContentsContainerView alloc] initWithDelegate:self]); |
| 216 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable]; | 216 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable]; |
| 217 [self setView:view]; | 217 [self setView:view]; |
| 218 } | 218 } |
| 219 | 219 |
| 220 - (void)ensureContentsSizeDoesNotChange { | 220 - (void)addContentsToView:(NSView*)superview { |
|
ccameron
2016/07/12 18:56:58
I'd prefer to avoid having the "nil defaults to so
tapted
2016/07/13 03:33:17
hehe - I actually started with this, but it made i
| |
| 221 NSView* contentsContainer = [self view]; | |
| 222 NSArray* subviews = [contentsContainer subviews]; | |
| 223 if ([subviews count] > 0) { | |
| 224 NSView* currentSubview = [subviews objectAtIndex:0]; | |
| 225 [currentSubview setAutoresizingMask:NSViewNotSizable]; | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 - (void)ensureContentsVisible { | |
| 230 if (!contents_) | 221 if (!contents_) |
| 231 return; | 222 return; |
| 223 | |
| 232 ScopedCAActionDisabler disabler; | 224 ScopedCAActionDisabler disabler; |
|
ccameron
2016/07/12 18:56:58
Would it be useful to have a "ScopedRWHViewActionD
tapted
2016/07/13 03:33:18
I'll keep it at the back of my mind - it does soun
| |
| 233 NSView* contentsContainer = [self view]; | 225 NSView* contentsContainer = [self view]; |
| 226 | |
| 227 // |superview| will be nil when toggling fullscreen or changing tabs via a | |
| 228 // notification, which preserves the current superview. Otherwise, [self view] | |
| 229 // should have been removed from the view hierarchy to suppress resizes. | |
| 230 DCHECK(!superview || ![contentsContainer superview]); | |
| 231 if (!superview) | |
| 232 superview = [contentsContainer superview]; | |
| 233 DCHECK(superview); | |
| 234 | |
| 234 NSArray* subviews = [contentsContainer subviews]; | 235 NSArray* subviews = [contentsContainer subviews]; |
| 235 NSView* contentsNativeView; | 236 NSView* contentsNativeView; |
| 236 content::RenderWidgetHostView* const fullscreenView = | 237 content::RenderWidgetHostView* const fullscreenView = |
| 237 isEmbeddingFullscreenWidget_ ? | 238 isEmbeddingFullscreenWidget_ ? |
| 238 contents_->GetFullscreenRenderWidgetHostView() : NULL; | 239 contents_->GetFullscreenRenderWidgetHostView() : NULL; |
| 239 if (fullscreenView) { | 240 if (fullscreenView) { |
| 240 contentsNativeView = fullscreenView->GetNativeView(); | 241 contentsNativeView = fullscreenView->GetNativeView(); |
| 241 } else { | 242 } else { |
| 242 isEmbeddingFullscreenWidget_ = NO; | 243 isEmbeddingFullscreenWidget_ = NO; |
| 243 contentsNativeView = contents_->GetNativeView(); | 244 contentsNativeView = contents_->GetNativeView(); |
| 244 } | 245 } |
| 245 | 246 |
| 246 if ([self shouldResizeContentView]) | 247 if ([self shouldResizeContentView]) |
| 247 [contentsNativeView setFrame:[self frameForContentsView]]; | 248 [contentsNativeView setFrame:[self frameForContentsViewIn:superview]]; |
| 248 | 249 |
| 249 if ([subviews count] == 0) { | 250 if ([subviews count] == 0) { |
| 250 [contentsContainer addSubview:contentsNativeView]; | 251 [contentsContainer addSubview:contentsNativeView]; |
| 251 } else if ([subviews objectAtIndex:0] != contentsNativeView) { | 252 } else if ([subviews objectAtIndex:0] != contentsNativeView) { |
| 252 [contentsContainer replaceSubview:[subviews objectAtIndex:0] | 253 [contentsContainer replaceSubview:[subviews objectAtIndex:0] |
| 253 with:contentsNativeView]; | 254 with:contentsNativeView]; |
| 254 } | 255 } |
| 256 | |
| 257 [contentsNativeView setAutoresizingMask:NSViewNotSizable]; | |
| 258 [contentsContainer setFrame:[superview bounds]]; | |
| 259 [superview addSubview:contentsContainer]; | |
| 255 [contentsNativeView setAutoresizingMask:NSViewWidthSizable| | 260 [contentsNativeView setAutoresizingMask:NSViewWidthSizable| |
| 256 NSViewHeightSizable]; | 261 NSViewHeightSizable]; |
| 257 | 262 |
| 258 [contentsContainer setNeedsDisplay:YES]; | 263 [contentsContainer setNeedsDisplay:YES]; |
| 259 | 264 |
| 260 // Push the background color down to the RenderWidgetHostView, so that if | 265 // Push the background color down to the RenderWidgetHostView, so that if |
| 261 // there is a flash between contents appearing, it will be the theme's color, | 266 // there is a flash between contents appearing, it will be the theme's color, |
| 262 // not white. | 267 // not white. |
| 263 SkColor skBackgroundColor = SK_ColorWHITE; | 268 SkColor skBackgroundColor = SK_ColorWHITE; |
| 264 const ThemeProvider* theme = [[[self view] window] themeProvider]; | 269 const ThemeProvider* theme = [[[self view] window] themeProvider]; |
| 265 if (theme) | 270 if (theme) |
| 266 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); | 271 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); |
| 267 content::RenderWidgetHostView* rwhv = contents_->GetRenderWidgetHostView(); | 272 content::RenderWidgetHostView* rwhv = contents_->GetRenderWidgetHostView(); |
| 268 if (rwhv) | 273 if (rwhv) |
| 269 rwhv->SetBackgroundColor(skBackgroundColor); | 274 rwhv->SetBackgroundColor(skBackgroundColor); |
| 270 } | 275 } |
| 271 | 276 |
| 272 - (void)updateFullscreenWidgetFrame { | 277 - (void)updateFullscreenWidgetFrame { |
| 273 // This should only apply if a fullscreen widget is embedded. | 278 // This should only apply if a fullscreen widget is embedded. |
| 274 if (!isEmbeddingFullscreenWidget_ || blockFullscreenResize_) | 279 if (!isEmbeddingFullscreenWidget_ || blockFullscreenResize_) |
| 275 return; | 280 return; |
| 276 | 281 |
| 277 content::RenderWidgetHostView* const fullscreenView = | 282 content::RenderWidgetHostView* const fullscreenView = |
| 278 contents_->GetFullscreenRenderWidgetHostView(); | 283 contents_->GetFullscreenRenderWidgetHostView(); |
| 279 if (fullscreenView) | 284 if (fullscreenView) { |
| 280 [fullscreenView->GetNativeView() setFrame:[self frameForContentsView]]; | 285 [fullscreenView->GetNativeView() |
| 286 setFrame:[self frameForContentsViewIn:[self view]]]; | |
| 287 } | |
| 281 } | 288 } |
| 282 | 289 |
| 283 - (void)changeWebContents:(WebContents*)newContents { | 290 - (void)changeWebContents:(WebContents*)newContents { |
| 284 contents_ = newContents; | 291 contents_ = newContents; |
| 285 fullscreenObserver_->Observe(contents_); | 292 fullscreenObserver_->Observe(contents_); |
| 286 isEmbeddingFullscreenWidget_ = | 293 isEmbeddingFullscreenWidget_ = |
| 287 contents_ && contents_->GetFullscreenRenderWidgetHostView(); | 294 contents_ && contents_->GetFullscreenRenderWidgetHostView(); |
| 288 } | 295 } |
| 289 | 296 |
| 290 // Returns YES if the tab represented by this controller is the front-most. | 297 // Returns YES if the tab represented by this controller is the front-most. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 // focus (for example, if the omnibox has focus instead). The WebContents | 329 // focus (for example, if the omnibox has focus instead). The WebContents |
| 323 // logic will restore focus to the appropriate view. | 330 // logic will restore focus to the appropriate view. |
| 324 } | 331 } |
| 325 | 332 |
| 326 - (void)tabDidChange:(WebContents*)updatedContents { | 333 - (void)tabDidChange:(WebContents*)updatedContents { |
| 327 // Calling setContentView: here removes any first responder status | 334 // Calling setContentView: here removes any first responder status |
| 328 // the view may have, so avoid changing the view hierarchy unless | 335 // the view may have, so avoid changing the view hierarchy unless |
| 329 // the view is different. | 336 // the view is different. |
| 330 if ([self webContents] != updatedContents) { | 337 if ([self webContents] != updatedContents) { |
| 331 [self changeWebContents:updatedContents]; | 338 [self changeWebContents:updatedContents]; |
| 332 [self ensureContentsVisible]; | 339 [self addContentsToView:nil]; |
|
ccameron
2016/07/12 18:56:58
[self ensureContentsVisibleWithSuperview:[[self vi
tapted
2016/07/13 03:33:18
Done.
| |
| 333 } | 340 } |
| 334 } | 341 } |
| 335 | 342 |
| 336 - (void)toggleFullscreenWidget:(BOOL)enterFullscreen { | 343 - (void)toggleFullscreenWidget:(BOOL)enterFullscreen { |
| 337 isEmbeddingFullscreenWidget_ = enterFullscreen && | 344 isEmbeddingFullscreenWidget_ = enterFullscreen && |
| 338 contents_ && contents_->GetFullscreenRenderWidgetHostView(); | 345 contents_ && contents_->GetFullscreenRenderWidgetHostView(); |
| 339 [self ensureContentsVisible]; | 346 [self addContentsToView:nil]; |
|
ccameron
2016/07/12 18:56:58
ditto.
tapted
2016/07/13 03:33:18
Done.
| |
| 340 } | 347 } |
| 341 | 348 |
| 342 - (BOOL)contentsInFullscreenCaptureMode { | 349 - (BOOL)contentsInFullscreenCaptureMode { |
| 343 // Note: Grab a known-valid WebContents pointer from |fullscreenObserver_|. | 350 // Note: Grab a known-valid WebContents pointer from |fullscreenObserver_|. |
| 344 content::WebContents* const wc = fullscreenObserver_->web_contents(); | 351 content::WebContents* const wc = fullscreenObserver_->web_contents(); |
| 345 if (!wc || | 352 if (!wc || |
| 346 wc->GetCapturerCount() == 0 || | 353 wc->GetCapturerCount() == 0 || |
| 347 wc->GetPreferredSize().IsEmpty() || | 354 wc->GetPreferredSize().IsEmpty() || |
| 348 !(isEmbeddingFullscreenWidget_ || | 355 !(isEmbeddingFullscreenWidget_ || |
| 349 (wc->GetDelegate() && | 356 (wc->GetDelegate() && |
| 350 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) { | 357 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) { |
| 351 return NO; | 358 return NO; |
| 352 } | 359 } |
| 353 return YES; | 360 return YES; |
| 354 } | 361 } |
| 355 | 362 |
| 356 - (NSRect)frameForContentsView { | 363 - (NSRect)frameForContentsViewIn:(NSView*)container { |
| 357 const NSSize containerSize = [[self view] frame].size; | 364 gfx::Rect rect([container bounds]); |
| 358 gfx::Rect rect; | |
| 359 rect.set_width(containerSize.width); | |
| 360 rect.set_height(containerSize.height); | |
| 361 | 365 |
| 362 // In most cases, the contents view is simply sized to fill the container | 366 // In most cases, the contents view is simply sized to fill the container |
| 363 // view's bounds. Only WebContentses that are in fullscreen mode and being | 367 // view's bounds. Only WebContentses that are in fullscreen mode and being |
| 364 // screen-captured will engage the special layout/sizing behavior. | 368 // screen-captured will engage the special layout/sizing behavior. |
| 365 if (![self contentsInFullscreenCaptureMode]) | 369 if (![self contentsInFullscreenCaptureMode]) |
| 366 return NSRectFromCGRect(rect.ToCGRect()); | 370 return NSRectFromCGRect(rect.ToCGRect()); |
| 367 | 371 |
| 368 // Size the contents view to the capture video resolution and center it. If | 372 // Size the contents view to the capture video resolution and center it. If |
| 369 // the container view is not large enough to fit it at the preferred size, | 373 // the container view is not large enough to fit it at the preferred size, |
| 370 // scale down to fit (preserving aspect ratio). | 374 // scale down to fit (preserving aspect ratio). |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 395 | 399 |
| 396 - (BOOL)shouldResizeContentView { | 400 - (BOOL)shouldResizeContentView { |
| 397 return !isEmbeddingFullscreenWidget_ || !blockFullscreenResize_; | 401 return !isEmbeddingFullscreenWidget_ || !blockFullscreenResize_; |
| 398 } | 402 } |
| 399 | 403 |
| 400 - (BOOL)isPopup { | 404 - (BOOL)isPopup { |
| 401 return isPopup_; | 405 return isPopup_; |
| 402 } | 406 } |
| 403 | 407 |
| 404 @end | 408 @end |
| OLD | NEW |