4
votes

I'm writing an OS X app and have a problem with font smoothing in separate window.

I have a text field where you put text and suggestion window which pops up with a list of suggestions according to what you wrote. I'm using View-cell based NSTableView to display those suggestions and SFBPopoverWindowController to display it as a "popup" window (tried other classes with the same effect). When rows are first drawn they look fine but after I select them (keyboard or mouse) the font changes it's weight. It's only visual - like you would change smoothing method on the font, not it's bold setting.

Font smoothing problem within cell

"Music note" is the selected cell here

What's even more strange is that after I hide and show the window 3 times everything works fine from that point on.

Font smoothing problem after showing the window 3 times

Again - "Music note" is the selected cell.

The selection is done by overwriting NSTableRowView class and its drawSelectionInRect: method but I tried with drawing everything inside custom NSTableCellView class and it didn't help. The text is standard NSTextField - nothing's changed there.

The SFBPopoverWindow (and it's controller) are created once and reused with styleMask NSBorderlessWindowMask, backing NSBackingStoreBuffered, defer set to YES. The only change in SFBPopoverWindowController I made was to turn off window becoming key window but it doesn't change anything.

1
I have seen this problem myself with a custom view that lays out a lot of text. After redrawing some parts of the text with highlight (different background colour) the text would appear "jaggy". I didn't find an answer but it went away after I converted to using CALayers. I know this doesn't help, but I feel it's a bug in both 10.7 and 10.8.trojanfoe

1 Answers

3
votes

It might be related to the way a table view draws it's selected cells (setSelectionHightLightStyle:). Try to set the style to None/ NSTableViewSelectionHighlightStyleNone in your code or IB / Storyboard-file and draw the selection yourself (in a NSTableRowView subclass).

Background: When you use NSTableViewSelectionHighlightStyleRegular or NSTableViewSelectionHighlightStyleSourceList the table view assumes that you use the standard selection behaviour and appearance and does some magic to support that.

==========

UPDATE

==========

My previous answer is still valid but since it only describes the problem and hints at a workaround, I wanted to add a real solution. If you want to use NSTableViewSelectionHighlightStyleRegular for your table view (with custom font and colors), you need a way to 'disable' the system magic that comes into place once your row is highlighted. One proposed solution is to decline the first responder status. It has a lot of drawbacks and isn't a good solution at all.

So, let's have a closer look at the system 'magic' that kicks in as soon as the row will be highlighted: NSTableRowView has a property interiorBackgroundStyle that is – according to the documentation – 'an indication of how the subviews should draw'. Furthermore 'This value is dynamically computed based on the set of properties set for the NSTableRowView. Subclassers can override this value when they draw differently based on the currently displayed properties. This method can also be called to determine what color a subview should use, or alternatively, NSControls can have the -backgroundStyle set on their cell to this value.'

I assume that this style will be handed down the subview hierarchy and causes your text fields to look odd. The system assumes that a highlighted cell has a dark background and changes the interiorBackgroundStyle to dark. Other controls try to adapt accordingly.

I think there are two solutions to this problem:

1) Override interiorBackgroundStyle in your NSTableRowView subclass and return the style that fits your interface (in my case it's .light because my highlight color is a very bright blue). This worked for me.

2) If changing the whole style is a bit too much because you only want certain elements to not change their style, you may only need to adjust these subclasses. I haven't tried this yet.