| Index: ui/base/cocoa/underlay_opengl_hosting_window.mm | 
| diff --git a/ui/base/cocoa/underlay_opengl_hosting_window.mm b/ui/base/cocoa/underlay_opengl_hosting_window.mm | 
| index 95f36af0476b239db0318c4b15cec907344143ea..6ed0624a6a3652537d10205c4d4b5240d1c53604 100644 | 
| --- a/ui/base/cocoa/underlay_opengl_hosting_window.mm | 
| +++ b/ui/base/cocoa/underlay_opengl_hosting_window.mm | 
| @@ -4,26 +4,125 @@ | 
|  | 
| #import "ui/base/cocoa/underlay_opengl_hosting_window.h" | 
|  | 
| +#import <objc/runtime.h> | 
| + | 
| #include "base/logging.h" | 
| +#include "base/mac/mac_util.h" | 
| +#include "base/mac/scoped_nsautorelease_pool.h" | 
| +#include "base/memory/scoped_nsobject.h" | 
| + | 
| +@interface NSWindow (UndocumentedAPI) | 
| +// Normally, punching a hole in a window by painting a subview with a | 
| +// transparent color causes the shadow for that area to also not be present. | 
| +// That feature is "content has shadow", which means that shadows are effective | 
| +// even in the content area of the window. If, however, "content has shadow" is | 
| +// turned off, then the transparent area of the content casts a shadow. The one | 
| +// tricky part is that even if "content has shadow" is turned off, "the content" | 
| +// is defined as being the scanline from the leftmost opaque part to the | 
| +// rightmost opaque part.  Therefore, to force the entire window to have a | 
| +// shadow, make sure that for the entire content region, there is an opaque area | 
| +// on the right and left edge of the window. | 
| +- (void)_setContentHasShadow:(BOOL)shadow; | 
| +@end | 
| + | 
| +@interface OpaqueView : NSView | 
| +@end | 
| + | 
| +@implementation OpaqueView | 
| +- (void)drawRect:(NSRect)r { | 
| +  [[NSColor blackColor] set]; | 
| +  NSRectFill(r); | 
| +} | 
| +@end | 
| + | 
| +namespace { | 
| + | 
| +NSComparisonResult OpaqueViewsOnTop(id view1, id view2, void* context) { | 
| +  BOOL view_1_is_opaque_view = [view1 isKindOfClass:[OpaqueView class]]; | 
| +  BOOL view_2_is_opaque_view = [view2 isKindOfClass:[OpaqueView class]]; | 
| +  if (view_1_is_opaque_view && view_2_is_opaque_view) | 
| +    return NSOrderedSame; | 
| +  if (view_1_is_opaque_view) | 
| +    return NSOrderedDescending; | 
| +  if (view_2_is_opaque_view) | 
| +    return NSOrderedAscending; | 
| +  return NSOrderedSame; | 
| +} | 
| + | 
| +void RootDidAddSubview(id self, SEL _cmd, NSView* subview) { | 
| +  if (![[self window] isKindOfClass:[UnderlayOpenGLHostingWindow class]]) | 
| +    return; | 
| + | 
| +  // Make sure the opaques are on top. | 
| +  [self sortSubviewsUsingFunction:OpaqueViewsOnTop context:NULL]; | 
| +} | 
| + | 
| +}  // namespace | 
|  | 
| @implementation UnderlayOpenGLHostingWindow | 
|  | 
| -- (void)underlaySurfaceAdded { | 
| -  DCHECK_GE(underlaySurfaceCount_, 0); | 
| -  ++underlaySurfaceCount_; | 
| ++ (void)load { | 
| +  base::mac::ScopedNSAutoreleasePool pool; | 
|  | 
| -  // We're having the OpenGL surface render under the window, so the window | 
| -  // needs to be not opaque. | 
| -  if (underlaySurfaceCount_ == 1) | 
| -    [self setOpaque:NO]; | 
| +  // On 10.8+ the background for textured windows are no longer drawn by | 
| +  // NSGrayFrame, and NSThemeFrame is used instead <http://crbug.com/114745>. | 
| +  Class borderViewClass = NSClassFromString( | 
| +      base::mac::IsOSMountainLionOrLater() ? @"NSThemeFrame" : @"NSGrayFrame"); | 
| +  DCHECK(borderViewClass); | 
| +  if (!borderViewClass) return; | 
| + | 
| +  // Install callback for added views. | 
| +  Method m = class_getInstanceMethod([NSView class], @selector(didAddSubview:)); | 
| +  DCHECK(m); | 
| +  if (m) { | 
| +    BOOL didAdd = class_addMethod(borderViewClass, | 
| +                                  @selector(didAddSubview:), | 
| +                                  reinterpret_cast<IMP>(&RootDidAddSubview), | 
| +                                  method_getTypeEncoding(m)); | 
| +    DCHECK(didAdd); | 
| +  } | 
| } | 
|  | 
| -- (void)underlaySurfaceRemoved { | 
| -  --underlaySurfaceCount_; | 
| -  DCHECK_GE(underlaySurfaceCount_, 0); | 
| +- (id)initWithContentRect:(NSRect)contentRect | 
| +                styleMask:(NSUInteger)windowStyle | 
| +                  backing:(NSBackingStoreType)bufferingType | 
| +                    defer:(BOOL)deferCreation { | 
| +  if ((self = [super initWithContentRect:contentRect | 
| +                               styleMask:windowStyle | 
| +                                 backing:bufferingType | 
| +                                   defer:deferCreation])) { | 
| +    // The invisible opaque area technique only works > 10.5. Fortunately, hole | 
| +    // punching is used only when IOSurfaces are used to transport, and that's | 
| +    // also only on > 10.5. Also, don't mess around with things if it's not a | 
| +    // proper window with a title bar and all. | 
| +    if (base::mac::IsOSSnowLeopardOrLater() && | 
| +        windowStyle && NSTitledWindowMask) { | 
| +      [self setOpaque:NO]; | 
| +      [self _setContentHasShadow:NO]; | 
| + | 
| +      NSView* rootView = [[self contentView] superview]; | 
| +      const NSRect rootBounds = [rootView bounds]; | 
| + | 
| +      const CGFloat kEdgeInset = 16; | 
| +      const CGFloat kAlphaValueJustOpaqueEnough = 0.002; | 
| + | 
| +      scoped_nsobject<NSView> leftOpaque([[OpaqueView alloc] initWithFrame: | 
| +          NSMakeRect(NSMinX(rootBounds), NSMinY(rootBounds) + kEdgeInset, | 
| +                     1, NSHeight(rootBounds) - 2 * kEdgeInset)]); | 
| +      [leftOpaque setAutoresizingMask:NSViewMaxXMargin | NSViewHeightSizable]; | 
| +      [leftOpaque setAlphaValue:kAlphaValueJustOpaqueEnough]; | 
| +      [rootView addSubview:leftOpaque]; | 
| + | 
| +      scoped_nsobject<NSView> rightOpaque([[OpaqueView alloc] initWithFrame: | 
| +          NSMakeRect(NSMaxX(rootBounds) - 1, NSMinY(rootBounds) + kEdgeInset, | 
| +                     1, NSHeight(rootBounds) - 2 * kEdgeInset)]); | 
| +      [rightOpaque setAutoresizingMask:NSViewMinXMargin | NSViewHeightSizable]; | 
| +      [rightOpaque setAlphaValue:kAlphaValueJustOpaqueEnough]; | 
| +      [rootView addSubview:rightOpaque]; | 
| +    } | 
| +  } | 
|  | 
| -  if (underlaySurfaceCount_ == 0) | 
| -    [self setOpaque:YES]; | 
| +  return self; | 
| } | 
|  | 
| @end | 
|  |