Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix focus ring's highlight being clipped when using CALayer?

The window's contentView has NSTextFields. (MacOS)

i'm using interface builder to setup the window and its features, so nothing in awakeFromNib except this:

[[self.window contentView] setWantsLayer:YES];
CALayer *layer = [[self.window contentView] layer];
CGColorRef lightGray = CGColorCreateGenericGray(0.93, 1.0);
[layer setBackgroundColor:lightGray];
CGColorRelease(lightGray);

However, the textField's focus ring is not visible outside the bounds of the textField.

With layer:

Without a layer:

i'm thinking that this display issue is something bigger than this, but i can't find an example of this problem, (and solution).

anyone?

like image 439
lulu Avatar asked Mar 06 '11 01:03

lulu


1 Answers

This is a long-known issue -- there's a mention on the Cocoa-dev mailing list back in 2008. The focus ring actually gets drawn outside its view's frame. NSView drawing is allowed to do this, but it doesn't work with CALayers. Despite a hopeful note in the Leopard AppKit release notes called Views, Focus Rings, and Drawing Performance, this has not changed.

In theory, it's possible to monkey around with the text fields' layers' frames and add some padding to allow the focus ring to show fully. However, I've just tried this and it seems that, for NSTextField at least, it won't draw neatly inside a changed frame. Give it a try, though -- I didn't fuss with it for too long. (The focus ring extends 4 pixels out from the frame in each direction.)

Just as a note, you are technically breaking the layer-backed rules, which may be part of why you are having difficulty. From NSView setWantsLayer: docs:

When using layer-backed views you should never interact directly with the layer.

You're using a layer-backed view and changing its background. You could get around this by making your own layer, but:

When using a layer-hosting view you should not rely on the view for drawing, nor should you add subviews to the layer-hosting view.

which rules out putting text fields in the view.

(Refer to this SO question if needed: Difference Between Layer-Backed and Layer-Hosting Views?)

like image 159
jscs Avatar answered Oct 11 '22 16:10

jscs