| 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)ensureContentsVisibleInSuperview:(NSView*)superview { |
| 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; |
| 233 NSView* contentsContainer = [self view]; | 225 NSView* contentsContainer = [self view]; |
| 234 NSArray* subviews = [contentsContainer subviews]; | 226 NSArray* subviews = [contentsContainer subviews]; |
| 235 NSView* contentsNativeView; | 227 NSView* contentsNativeView; |
| 236 content::RenderWidgetHostView* const fullscreenView = | 228 content::RenderWidgetHostView* const fullscreenView = |
| 237 isEmbeddingFullscreenWidget_ ? | 229 isEmbeddingFullscreenWidget_ ? |
| 238 contents_->GetFullscreenRenderWidgetHostView() : NULL; | 230 contents_->GetFullscreenRenderWidgetHostView() : NULL; |
| 239 if (fullscreenView) { | 231 if (fullscreenView) { |
| 240 contentsNativeView = fullscreenView->GetNativeView(); | 232 contentsNativeView = fullscreenView->GetNativeView(); |
| 241 } else { | 233 } else { |
| 242 isEmbeddingFullscreenWidget_ = NO; | 234 isEmbeddingFullscreenWidget_ = NO; |
| 243 contentsNativeView = contents_->GetNativeView(); | 235 contentsNativeView = contents_->GetNativeView(); |
| 244 } | 236 } |
| 245 | 237 |
| 246 if ([self shouldResizeContentView]) | 238 if ([self shouldResizeContentView]) |
| 247 [contentsNativeView setFrame:[self frameForContentsView]]; | 239 [contentsNativeView setFrame:[self frameForContentsViewIn:superview]]; |
| 248 | 240 |
| 249 if ([subviews count] == 0) { | 241 if ([subviews count] == 0) { |
| 250 [contentsContainer addSubview:contentsNativeView]; | 242 [contentsContainer addSubview:contentsNativeView]; |
| 251 } else if ([subviews objectAtIndex:0] != contentsNativeView) { | 243 } else if ([subviews objectAtIndex:0] != contentsNativeView) { |
| 252 [contentsContainer replaceSubview:[subviews objectAtIndex:0] | 244 [contentsContainer replaceSubview:[subviews objectAtIndex:0] |
| 253 with:contentsNativeView]; | 245 with:contentsNativeView]; |
| 254 } | 246 } |
| 247 |
| 248 [contentsNativeView setAutoresizingMask:NSViewNotSizable]; |
| 249 [contentsContainer setFrame:[superview bounds]]; |
| 250 [superview addSubview:contentsContainer]; |
| 255 [contentsNativeView setAutoresizingMask:NSViewWidthSizable| | 251 [contentsNativeView setAutoresizingMask:NSViewWidthSizable| |
| 256 NSViewHeightSizable]; | 252 NSViewHeightSizable]; |
| 257 | 253 |
| 258 [contentsContainer setNeedsDisplay:YES]; | 254 [contentsContainer setNeedsDisplay:YES]; |
| 259 | 255 |
| 260 // Push the background color down to the RenderWidgetHostView, so that if | 256 // 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, | 257 // there is a flash between contents appearing, it will be the theme's color, |
| 262 // not white. | 258 // not white. |
| 263 SkColor skBackgroundColor = SK_ColorWHITE; | 259 SkColor skBackgroundColor = SK_ColorWHITE; |
| 264 const ThemeProvider* theme = [[[self view] window] themeProvider]; | 260 const ThemeProvider* theme = [[[self view] window] themeProvider]; |
| 265 if (theme) | 261 if (theme) |
| 266 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); | 262 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); |
| 267 content::RenderWidgetHostView* rwhv = contents_->GetRenderWidgetHostView(); | 263 content::RenderWidgetHostView* rwhv = contents_->GetRenderWidgetHostView(); |
| 268 if (rwhv) | 264 if (rwhv) |
| 269 rwhv->SetBackgroundColor(skBackgroundColor); | 265 rwhv->SetBackgroundColor(skBackgroundColor); |
| 270 } | 266 } |
| 271 | 267 |
| 272 - (void)updateFullscreenWidgetFrame { | 268 - (void)updateFullscreenWidgetFrame { |
| 273 // This should only apply if a fullscreen widget is embedded. | 269 // This should only apply if a fullscreen widget is embedded. |
| 274 if (!isEmbeddingFullscreenWidget_ || blockFullscreenResize_) | 270 if (!isEmbeddingFullscreenWidget_ || blockFullscreenResize_) |
| 275 return; | 271 return; |
| 276 | 272 |
| 277 content::RenderWidgetHostView* const fullscreenView = | 273 content::RenderWidgetHostView* const fullscreenView = |
| 278 contents_->GetFullscreenRenderWidgetHostView(); | 274 contents_->GetFullscreenRenderWidgetHostView(); |
| 279 if (fullscreenView) | 275 if (fullscreenView) { |
| 280 [fullscreenView->GetNativeView() setFrame:[self frameForContentsView]]; | 276 [fullscreenView->GetNativeView() |
| 277 setFrame:[self frameForContentsViewIn:[self view]]]; |
| 278 } |
| 281 } | 279 } |
| 282 | 280 |
| 283 - (void)changeWebContents:(WebContents*)newContents { | 281 - (void)changeWebContents:(WebContents*)newContents { |
| 284 contents_ = newContents; | 282 contents_ = newContents; |
| 285 fullscreenObserver_->Observe(contents_); | 283 fullscreenObserver_->Observe(contents_); |
| 286 isEmbeddingFullscreenWidget_ = | 284 isEmbeddingFullscreenWidget_ = |
| 287 contents_ && contents_->GetFullscreenRenderWidgetHostView(); | 285 contents_ && contents_->GetFullscreenRenderWidgetHostView(); |
| 288 } | 286 } |
| 289 | 287 |
| 290 // Returns YES if the tab represented by this controller is the front-most. | 288 // 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 | 320 // focus (for example, if the omnibox has focus instead). The WebContents |
| 323 // logic will restore focus to the appropriate view. | 321 // logic will restore focus to the appropriate view. |
| 324 } | 322 } |
| 325 | 323 |
| 326 - (void)tabDidChange:(WebContents*)updatedContents { | 324 - (void)tabDidChange:(WebContents*)updatedContents { |
| 327 // Calling setContentView: here removes any first responder status | 325 // Calling setContentView: here removes any first responder status |
| 328 // the view may have, so avoid changing the view hierarchy unless | 326 // the view may have, so avoid changing the view hierarchy unless |
| 329 // the view is different. | 327 // the view is different. |
| 330 if ([self webContents] != updatedContents) { | 328 if ([self webContents] != updatedContents) { |
| 331 [self changeWebContents:updatedContents]; | 329 [self changeWebContents:updatedContents]; |
| 332 [self ensureContentsVisible]; | 330 [self ensureContentsVisibleInSuperview:[[self view] superview]]; |
| 333 } | 331 } |
| 334 } | 332 } |
| 335 | 333 |
| 336 - (void)toggleFullscreenWidget:(BOOL)enterFullscreen { | 334 - (void)toggleFullscreenWidget:(BOOL)enterFullscreen { |
| 337 isEmbeddingFullscreenWidget_ = enterFullscreen && | 335 isEmbeddingFullscreenWidget_ = enterFullscreen && |
| 338 contents_ && contents_->GetFullscreenRenderWidgetHostView(); | 336 contents_ && contents_->GetFullscreenRenderWidgetHostView(); |
| 339 [self ensureContentsVisible]; | 337 [self ensureContentsVisibleInSuperview:[[self view] superview]]; |
| 340 } | 338 } |
| 341 | 339 |
| 342 - (BOOL)contentsInFullscreenCaptureMode { | 340 - (BOOL)contentsInFullscreenCaptureMode { |
| 343 // Note: Grab a known-valid WebContents pointer from |fullscreenObserver_|. | 341 // Note: Grab a known-valid WebContents pointer from |fullscreenObserver_|. |
| 344 content::WebContents* const wc = fullscreenObserver_->web_contents(); | 342 content::WebContents* const wc = fullscreenObserver_->web_contents(); |
| 345 if (!wc || | 343 if (!wc || |
| 346 wc->GetCapturerCount() == 0 || | 344 wc->GetCapturerCount() == 0 || |
| 347 wc->GetPreferredSize().IsEmpty() || | 345 wc->GetPreferredSize().IsEmpty() || |
| 348 !(isEmbeddingFullscreenWidget_ || | 346 !(isEmbeddingFullscreenWidget_ || |
| 349 (wc->GetDelegate() && | 347 (wc->GetDelegate() && |
| 350 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) { | 348 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) { |
| 351 return NO; | 349 return NO; |
| 352 } | 350 } |
| 353 return YES; | 351 return YES; |
| 354 } | 352 } |
| 355 | 353 |
| 356 - (NSRect)frameForContentsView { | 354 - (NSRect)frameForContentsViewIn:(NSView*)container { |
| 357 const NSSize containerSize = [[self view] frame].size; | 355 gfx::Rect rect([container bounds]); |
| 358 gfx::Rect rect; | |
| 359 rect.set_width(containerSize.width); | |
| 360 rect.set_height(containerSize.height); | |
| 361 | 356 |
| 362 // In most cases, the contents view is simply sized to fill the container | 357 // 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 | 358 // view's bounds. Only WebContentses that are in fullscreen mode and being |
| 364 // screen-captured will engage the special layout/sizing behavior. | 359 // screen-captured will engage the special layout/sizing behavior. |
| 365 if (![self contentsInFullscreenCaptureMode]) | 360 if (![self contentsInFullscreenCaptureMode]) |
| 366 return NSRectFromCGRect(rect.ToCGRect()); | 361 return NSRectFromCGRect(rect.ToCGRect()); |
| 367 | 362 |
| 368 // Size the contents view to the capture video resolution and center it. If | 363 // 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, | 364 // the container view is not large enough to fit it at the preferred size, |
| 370 // scale down to fit (preserving aspect ratio). | 365 // scale down to fit (preserving aspect ratio). |
| (...skipping 24 matching lines...) Expand all Loading... |
| 395 | 390 |
| 396 - (BOOL)shouldResizeContentView { | 391 - (BOOL)shouldResizeContentView { |
| 397 return !isEmbeddingFullscreenWidget_ || !blockFullscreenResize_; | 392 return !isEmbeddingFullscreenWidget_ || !blockFullscreenResize_; |
| 398 } | 393 } |
| 399 | 394 |
| 400 - (BOOL)isPopup { | 395 - (BOOL)isPopup { |
| 401 return isPopup_; | 396 return isPopup_; |
| 402 } | 397 } |
| 403 | 398 |
| 404 @end | 399 @end |
| OLD | NEW |