Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Unified Diff: ui/base/cocoa/underlay_opengl_hosting_window.mm

Issue 10037008: Fix window shadows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed sort Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..e26291f10e5c593c486f43d354382be3cbe568c2 100644
--- a/ui/base/cocoa/underlay_opengl_hosting_window.mm
+++ b/ui/base/cocoa/underlay_opengl_hosting_window.mm
@@ -4,26 +4,120 @@
#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 view1IsOpaqueView = [view1 isKindOfClass:[OpaqueView class]];
Mark Mentovai 2012/04/10 19:08:30 Style nit: use_c_plus_plus_naming outside of @inte
Avi (use Gerrit) 2012/04/10 19:42:50 Done.
+ BOOL view2IsOpaqueView = [view2 isKindOfClass:[OpaqueView class]];
+ if (view1IsOpaqueView && view2IsOpaqueView)
+ return NSOrderedSame;
+ if (view1IsOpaqueView)
+ return NSOrderedDescending;
+ if (view2IsOpaqueView)
+ return NSOrderedAscending;
+ return NSOrderedSame;
+}
+
+void RootDidAddSubview(id self, SEL _cmd, NSView* subview) {
+ // 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;
+
+ // 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;
- // We're having the OpenGL surface render under the window, so the window
- // needs to be not opaque.
- if (underlaySurfaceCount_ == 1)
- [self setOpaque:NO];
+ // Install callback for added views.
+ Method m = class_getInstanceMethod([NSView class], @selector(didAddSubview:));
Mark Mentovai 2012/04/10 19:08:30 You can use borderViewClass here instead of [NSVie
+ DCHECK(m);
+ if (m) {
+ BOOL didAdd = class_addMethod(borderViewClass,
+ @selector(didAddSubview:),
+ reinterpret_cast<IMP>(&RootDidAddSubview),
+ method_getTypeEncoding(m));
Mark Mentovai 2012/04/10 19:08:30 If this is all you’re using m for, it seems like y
Avi (use Gerrit) 2012/04/10 19:42:50 I'm having trouble; how do you paste together the
Mark Mentovai 2012/04/10 19:48:29 Avi wrote:
Avi (use Gerrit) 2012/04/10 20:11:23 Well, sure, but I'm not sure I see the advantage t
Mark Mentovai 2012/04/10 20:19:11 Avi wrote:
+ 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.
+ if (base::mac::IsOSSnowLeopardOrLater()) {
+ [self setOpaque:NO];
+ [self _setContentHasShadow:NO];
+
+ NSView* rootView = [[self contentView] superview];
+ NSRect rootBounds = [rootView bounds];
+
+ const CGFloat kEdgeInset = 16;
+
+ scoped_nsobject<NSView> leftOpaque(
+ [[OpaqueView alloc] initWithFrame:
+ NSMakeRect(NSMinX(rootBounds), NSMinY(rootBounds) + kEdgeInset,
+ 1, NSHeight(rootBounds) - 2 * kEdgeInset)]);
+ [rootView addSubview:leftOpaque];
Mark Mentovai 2012/04/10 19:08:30 Can you wait to add it ’til after the resize mask
Avi (use Gerrit) 2012/04/10 19:42:50 Done.
+ [leftOpaque setAutoresizingMask:NSViewMaxXMargin|NSViewHeightSizable];
Mark Mentovai 2012/04/10 19:08:30 Tiny bit more readable with space around the “or”
Avi (use Gerrit) 2012/04/10 19:42:50 Done.
+ [leftOpaque setAlphaValue:0.002f];
Mark Mentovai 2012/04/10 19:08:30 Want a const CGFloat to store this so you can be s
Avi (use Gerrit) 2012/04/10 19:42:50 Done.
+
+ scoped_nsobject<NSView> rightOpaque([[OpaqueView alloc] initWithFrame:
+ NSMakeRect(NSMaxX(rootBounds) - 1, NSMinY(rootBounds) + kEdgeInset,
+ 1, NSHeight(rootBounds) - 2 * kEdgeInset)]);
Mark Mentovai 2012/04/10 19:08:30 Similarly, you can also keep consts for y and h.
Avi (use Gerrit) 2012/04/10 19:42:50 It's weird to have some of the values from the roo
Mark Mentovai 2012/04/10 19:48:29 Avi wrote:
+ [rootView addSubview:rightOpaque];
+ [rightOpaque setAutoresizingMask:NSViewMinXMargin|NSViewHeightSizable];
+ [rightOpaque setAlphaValue:0.002f];
+ }
+ }
- if (underlaySurfaceCount_ == 0)
- [self setOpaque:YES];
+ return self;
}
@end

Powered by Google App Engine
This is Rietveld 408576698