#include <utility>
+#include "base/command_line.h"
+#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsobject.h"
#include "chrome/browser/devtools/devtools_window.h"
#import "chrome/browser/themes/theme_properties.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
+#include "ui/base/cocoa/animation_utils.h"
+#include "ui/base/ui_base_switches.h"
#include "ui/gfx/geometry/rect.h"
using content::WebContents;
};
@interface TabContentsController (TabContentsContainerViewDelegate)
+- (BOOL)contentsInFullscreenCaptureMode;
// Computes and returns the frame to use for the contents view within the
// container view.
- (NSRect)frameForContentsView;
@private
TabContentsController* delegate_; // weak
}
+
+- (NSColor*)computeBackgroundColor;
@end
@implementation TabContentsContainerView
- (id)initWithDelegate:(TabContentsController*)delegate {
if ((self = [super initWithFrame:NSZeroRect])) {
delegate_ = delegate;
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableCoreAnimation)) {
+ ScopedCAActionDisabler disabler;
+ base::scoped_nsobject<CALayer> layer([[CALayer alloc] init]);
+ [layer setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
+ [self setLayer:layer];
+ [self setWantsLayer:YES];
+ }
}
return self;
}
delegate_ = nil;
}
+- (NSColor*)computeBackgroundColor {
+ // This view is sometimes flashed into visibility (e.g, when closing
+ // windows), so ensure that the flash be white in those cases.
+ if (![delegate_ contentsInFullscreenCaptureMode])
+ return [NSColor whiteColor];
+
+ // Fill with a dark tint of the new tab page's background color. This is
+ // only seen when the subview is sized specially for fullscreen tab capture.
+ NSColor* bgColor = nil;
+ ThemeService* const theme =
+ static_cast<ThemeService*>([[self window] themeProvider]);
+ if (theme)
+ bgColor = theme->GetNSColor(ThemeProperties::COLOR_NTP_BACKGROUND);
+ if (!bgColor)
+ bgColor = [[self window] backgroundColor];
+ const float kDarknessFraction = 0.80f;
+ return [bgColor blendedColorWithFraction:kDarknessFraction
+ ofColor:[NSColor blackColor]];
+}
+
// Override -drawRect to fill the view with a solid color outside of the
// subview's frame.
- (void)drawRect:(NSRect)dirtyRect {
NSView* const contentsView =
[[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil;
if (!contentsView || !NSContainsRect([contentsView frame], dirtyRect)) {
- // Fill with a dark tint of the new tab page's background color. This is
- // only seen when the subview is sized specially for fullscreen tab capture.
- NSColor* bgColor = nil;
- ThemeService* const theme =
- static_cast<ThemeService*>([[self window] themeProvider]);
- if (theme)
- bgColor = theme->GetNSColor(ThemeProperties::COLOR_NTP_BACKGROUND);
- if (!bgColor)
- bgColor = [[self window] backgroundColor];
- const float kDarknessFraction = 0.80f;
- [[bgColor blendedColorWithFraction:kDarknessFraction
- ofColor:[NSColor blackColor]] setFill];
+ [[self computeBackgroundColor] setFill];
NSRectFill(dirtyRect);
}
[super drawRect:dirtyRect];
!delegate_) {
return;
}
+
+ ScopedCAActionDisabler disabler;
[contentsView setFrame:[delegate_ frameForContentsView]];
}
+// Update the background layer's color whenever the view needs to repaint.
+- (void)setNeedsDisplayInRect:(NSRect)rect {
+ [super setNeedsDisplayInRect:rect];
+
+ // Convert from an NSColor to a CGColorRef.
+ NSColor* nsBackgroundColor = [self computeBackgroundColor];
+ NSColorSpace* nsColorSpace = [nsBackgroundColor colorSpace];
+ CGColorSpaceRef cgColorSpace = [nsColorSpace CGColorSpace];
+ const NSInteger numberOfComponents = [nsBackgroundColor numberOfComponents];
+ CGFloat components[numberOfComponents];
+ [nsBackgroundColor getComponents:components];
+ base::ScopedCFTypeRef<CGColorRef> cgBackgroundColor(
+ CGColorCreate(cgColorSpace, components));
+
+ ScopedCAActionDisabler disabler;
+ [[self layer] setBackgroundColor:cgBackgroundColor];
+}
+
@end // @implementation TabContentsContainerView
@implementation TabContentsController
- (void)ensureContentsVisible {
if (!contents_)
return;
+ ScopedCAActionDisabler disabler;
NSView* contentsContainer = [self view];
NSArray* subviews = [contentsContainer subviews];
NSView* contentsNativeView;
contentsNativeView = fullscreenView->GetNativeView();
} else {
isEmbeddingFullscreenWidget_ = NO;
- contentsNativeView = contents_->GetView()->GetNativeView();
+ contentsNativeView = contents_->GetNativeView();
}
[contentsNativeView setFrame:[self frameForContentsView]];
if ([subviews count] == 0) {
}
[contentsNativeView setAutoresizingMask:NSViewWidthSizable|
NSViewHeightSizable];
+
+ // TODO(miu): The following can be removed once we use a CALayer in
+ // TabContentsContainerView. http://crbug.com/354598
+ [contentsContainer setNeedsDisplay:YES];
+
// The rendering path with overlapping views disabled causes bugs when
// transitioning between composited and non-composited mode.
// http://crbug.com/279472
if (!fullscreenView)
- contents_->GetView()->SetAllowOverlappingViews(true);
+ contents_->SetAllowOverlappingViews(true);
}
- (void)changeWebContents:(WebContents*)newContents {
[self ensureContentsVisible];
}
-- (NSRect)frameForContentsView {
- const NSSize containerSize = [[self view] frame].size;
- gfx::Rect rect;
- rect.set_width(containerSize.width);
- rect.set_height(containerSize.height);
-
- // In most cases, the contents view is simply sized to fill the container
- // view's bounds. Only WebContentses that are in fullscreen mode and being
- // screen-captured will engage the special layout/sizing behavior.
+- (BOOL)contentsInFullscreenCaptureMode {
if (!fullscreenObserver_)
- return NSRectFromCGRect(rect.ToCGRect());
+ return NO;
// Note: Grab a known-valid WebContents pointer from |fullscreenObserver_|.
content::WebContents* const wc = fullscreenObserver_->web_contents();
if (!wc ||
!(isEmbeddingFullscreenWidget_ ||
(wc->GetDelegate() &&
wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) {
- return NSRectFromCGRect(rect.ToCGRect());
+ return NO;
}
+ return YES;
+}
+
+- (NSRect)frameForContentsView {
+ const NSSize containerSize = [[self view] frame].size;
+ gfx::Rect rect;
+ rect.set_width(containerSize.width);
+ rect.set_height(containerSize.height);
+
+ // In most cases, the contents view is simply sized to fill the container
+ // view's bounds. Only WebContentses that are in fullscreen mode and being
+ // screen-captured will engage the special layout/sizing behavior.
+ if (![self contentsInFullscreenCaptureMode])
+ return NSRectFromCGRect(rect.ToCGRect());
// Size the contents view to the capture video resolution and center it. If
// the container view is not large enough to fit it at the preferred size,
// scale down to fit (preserving aspect ratio).
+ content::WebContents* const wc = fullscreenObserver_->web_contents();
const gfx::Size captureSize = wc->GetPreferredSize();
if (captureSize.width() <= rect.width() &&
captureSize.height() <= rect.height()) {