Pushbutton layer shadow is clipped unless created from XIB

Originator:kusterer
Number:rdar://15770532 Date Originated:08-Jan-2014 09:25 AM
Status:Open Resolved:
Product:OS X Product Version:10.9.1 (13B42)
Classification:Serious Bug Reproducible:Always
 
Summary:
Creating a pushbutton in code and giving its layer a shadow causes the shadow to be clipped to view bounds (i.e. ugly, useless). Creating a pushbutton that has a shadow from a XIB and then changing its attributes works fine and causes the shadow to draw properly.

Steps to Reproduce:
Run the following code in a Cocoa application:
==== SNIP! ====
NSRect          wdBox = NSMakeRect(0,0,100,100);
NSWindow    *   theWindow = [[[NSWindow alloc] initWithContentRect: wdBox styleMask: NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask backing: NSBackingStoreBuffered defer: NO] autorelease];
NSView* cv = [[[NSView alloc] initWithFrame: wdBox] autorelease];
cv.wantsLayer = YES;
[cv setLayerUsesCoreImageFilters: YES];
theWindow.contentView = cv;
[theWindow setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary];
[theWindow setTitle: @"foo"];

NSButton* mView = [[NSButton alloc] initWithFrame: NSMakeRect(10, 10, 100, 80)];
[mView setLayerUsesCoreImageFilters: YES]; // *
[mView setWantsLayer: YES]; // *
mView.layer.masksToBounds = NO; // *
[mView.layer setShadowColor: [NSColor.redColor CGColor]];
[mView.layer setShadowOffset: CGSizeMake(4, 4)];
[mView.layer setShadowRadius: 8];
[mView.layer setShadowOpacity: 1.0];
[mView setBezelStyle: NSRoundRectBezelStyle];
[mView setTitle: @"bar"];
[theWindow.contentView addSubview: mView];
==== UNSNIP! ====

Expected Results:
A window containing a pushbutton with a red shadow below it.

Actual Results:
The shadow draws, but is clipped to the NSView's bounds.

Regression:
This used to work in 10.8 and earlier. The issue is new since 10.9.0.

Notes:
Here's my Stackoverflow thread on the issue: http://stackoverflow.com/questions/20962005/why-is-my-layer-shadow-clipped-to-my-nsviews-rect/

The workaround is to use the following code to create the button:

==== SNIP! ====
@interface WILDButtonOwner : NSViewController

@property (retain,nonatomic) IBOutlet NSButton* button;

@end


@implementation WILDButtonOwner

@end
==== UNSNIP ====

==== SNIP2 ====
WILDButtonOwner * mButtonOwner = [[WILDButtonOwner alloc] initWithNibName: @"WILDButtonOwner" bundle: nil];
[mButtonOwner view];
NSButton* mView = [mButtonOwner button];
==== UNSNIP2====

And a WILDButtonOwner.xib containing a pushbutton (type is irrelevant, it seems, I can change it afterwards), whose button already has a shadow offset, blur radius and color set. The button created from the XIB doesn't clip its shadow.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!