Custom NSWindow in 10.9 Doesn't show shadow when SetOpaque:NO - macos

So I have created an NSWindow (with rounded corners), and in 10.10, it has a shadow around it. However when I tested in 10.9, the shadow disappeared. I have set breakpoints at every possible point, and [window hasShadow] is always YES.
If I set [self setOpaque:YES] in the initWithContentRect method of the window, the shadow comes back.
Has anybody seen this before? Or know what could possibly cause this?
It appears the hasShadow property doesn't do anything because if I set it to YES/NO it doesn't change anything. Just setting it opaque/transparent makes the shadow appear/disappear
Thanks in advance!

Here is how I finally managed this.
First of all, this will happen only if you are using layered back views (and this is our case if we want to easily implement rounded corners), in the RoundTransparentWindow Apple sample you can test it, until you not make the CutomView layered you will see the window shadow on 10.9 too, adding [self setWantsLayer:YES]; will kill your shadow.
The key for the solution here is adding all the layered views to a view that has no layer at all and making that view to the window contentView. That new contentView should reimplement only the drawRect: method on the following way:
- (void)drawRect:(NSRect)dirtyRect
{
[NSGraphicsContext saveGraphicsState];
[[NSColor clearColor] set];
NSRectFill(dirtyRect);
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:[self bounds]
xRadius:cCornerRadius
yRadius:cCornerRadius];
[[NSColor whiteColor] set];
[path fill];
[NSGraphicsContext restoreGraphicsState];
}
"Pre drawing" the rounded corners filled with any NONE transparent color is the key here, it will make the window server use the shadow again even if [self setOpaque:NO]; self.backgroundColor = [NSColor clearColor]; set during the window construction, that, as you found it earlier, made the server to think the window is transparent and does not need shadow.

Related

Why are my layer-backed NSViews flashing?

I have a basic drawing app. I decided I wanted to have a CALayer backed NSView because, as I understand it, Layer Backed Views have performance benefits. Also, I noticed that it took care of redrawing the window during live window resizes. Either way, it sounded like a win-win. Here is my drawRect: method, which is triggered by, among other things, mouseDragged:
- (void)drawRect:(NSRect)rect
{
if (firstDraw) { //Sets the background to white
[[NSColor whiteColor]set];
NSRectFill(rect);
firstDraw = NO;
}
//strokeDict contains all the variable settings needed to stroke the path.
[(NSColor *)([self->strokeDict objectForKey:#"lineColor"]) set];
NSBezierPath *strokingPath = [[self->strokeDict objectForKey:#"bezierPath"] copy];
[strokingPath setLineWidth:[[self->strokeDict objectForKey:#"lineWidth"]floatValue]];
//setupPath sets the lineJoinStyle & Cap
[setupPath(strokingPath) stroke];
}
However, when run, I get the results shown below (albeit much faster). What on earth is going on?

NSImageView disappears when the parent NSView wants layer (setWantsLayer:YES)

I have a simple custom NSView that has a label and an image. Currently the view works quite well (all the thumbs are instances of my custom view):
However, I want to set the opacity of these thumbnails. Setting viewInstance.layer.opacity doesn't work as the layer is nil. When I use [viewInstance setWantsLayer:YES] first somewhere, and I set the opacity, the opacity of the text changes (it is displayed correctly), but the image view disappears altogether:
I've tried creating a layer first, assigning it, and then calling setWantsLayer: after reading this question: How to add a CALayer to an NSView on Mac OS X but nothing changed:
CALayer *selfLayer = [[CALayer alloc] init];
[selfLayer setFrame:CGRectMake(0, 0, 100, 100)];
[self setLayer:selfLayer];
[self setWantsLayer:YES];
I've tried all combinations of creating a layer and displaying it for the image view too (just calling setWantsLayer:, creating layer and then assigning it, calling display method of it), but still nothing changes:
[self addSubview:self.imageView];
CALayer *imageLayer = [[CALayer alloc] init];
[imageLayer setFrame:CGRectMake(0, 0, 100, 100)];
[self.imageView setLayer:imageLayer];
[self.imageView setWantsLayer:YES];
I've tried adding the image view's layer as a sublayer of the main view and then displaying it:
[self.layer addSublayer:self.imageView.layer];
[self.imageView.layer display];
[self.layer display];
But still, the images won't display, whereas the text always displays correctly. When I comment out the code about assigning and wanting layers, images display again, but obviously, I can't use the layer opacity. I am on OS X Mavericks with OS X SDK 10.8. What am I doing wrong?
UPDATE: I ended up getting rid of NSImageView completely and drawing the NSImage directly into the layer by setting the layer's contents property. However, this is just another approach which solved my problem for this project, it still doesn't answer the original question.
I ended up getting rid of NSImageView completely and drawing the NSImage directly into the layer by setting the layer's contents property. However, this is just another approach which solved my problem for this project, it still doesn't answer the original question.

NSWindow, strange corner when using Core Animation

In my project there is a view with a custom drawRect: method which draws a dark background. When I call [view setWantsLayer:YES] the corner of the window (where view is placed) appears less smooth (image 2) than usual (image 1).
How can I solve this?
You need to set cornerRadius: and enable maskToBounds: for layer like this:
[view setWantsLayer:YES];
[[view layer] setMasksToBounds:YES];
[[view layer] setCornerRadius:10.0];
Result:

Setting different backgrounds for nsview

I'm trying to set custom background for an NSView. I need different backgrounds to be set based on some action. So i created 2 CAlayers for this view and trying to fill it using colorWithPatternImage.Is this a right method? If not, how can i do it?
Regards,
LS Developer
You could subclass the view that you want, and in its drawRect: method do something like
- (void)drawRect:(NSRect)dirtyRect
{
// Colour the background
[[NSColor orangeColor] set];
NSFillRect (dirtyRect);
// Now draw the parent
[super drawRect:dirtyRect];
}

Gray border when using NSBorderlessWindowMask

Whenever I try to create a custom window using NSBorderlessWindowMask and set an NSView (for example an NSImageView) as its contentView, I get a 1px gray border around the NSView and I don't seem to be able to get rid of it.
I have followed several approaches including Apple's RoundTransparentWindow sample code as well as several suggestions on StackOverflow.
I suspect the gray border is either coming from the window itself or the NSView.
Have any of you experienced this problem or do you have a possible solution?
The code is fairly straightforward. This is the init method of the custom window:
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
if (self != nil) {
[self setAlphaValue:1.0];
[self setBackgroundColor:[NSColor clearColor]];
[self setOpaque:NO];
}
return self;
}
To test this, in IB I place an NSImageView in that custom window WITHOUT border and yet the image in the NSImageView has a border. The same goes for other NSView subclasses, such as NSTextField, NSTableView.
In addition, I also noticed that the same is happening with the sample application (RoundTransparentWindow) of Apple. Is it even possible to draw an NSView in a custom window without a 1px border?
Thanks
Are you sure this happens when you use a regular NSView with no drawing? I bet not. Other controls (like NSImageView)have borders. Maybe you should double check to make sure they're turned off whe possible.
Update - How do you get your view into your window? You don't include that code. I created a basic test project (download it here) with an image well and it works just fine. See for yourself.

Resources