How can I set [NSTextView selectedTextAttributes] on a background window?

cocoa, nstextview, objective-c

Solution

You can override the colour by overriding drawing method of `NSLayoutManager`.

final class LayoutManager1: NSLayoutManager {
    override func fillBackgroundRectArray(rectArray: UnsafePointer<NSRect>, count rectCount: Int, forCharacterRange charRange: NSRange, color: NSColor) {
        let color1 = color == NSColor.secondarySelectedControlColor() ? NSColor.redColor() : color
        color1.setFill()
        super.fillBackgroundRectArray(rectArray, count: rectCount, forCharacterRange: charRange, color: color1)
        color.setFill()
    }
}

And replace `NSTextView`'s layout manager to it.

textView.textContainer!.replaceLayoutManager(layoutManager1)

Here's full working example.

As @Kyle asks for reason of `setFill`, I add some update.

From Apple manual:

... the charRange and color parameters are passed in merely for informational purposes; the color is already set in the graphics state. If for any reason you modify it, you must restore it before returning from this method. ...

Which means passing-in other color into `super` call has no effect, and you just need to `NSColor.setFill` to make it work with `super` call. Also, the manual requires to set it back to original one.

Problem

The default value for `[NSTextView selectedTextAttributes]` is unusable in my app, because i allow the user to select colors (syntax highlighting) that are almost exactly the same as the background color. I have written some math to determine a suitable color and can use this to set it: ``` textView.selectedTextAttributes = @{ NSBackgroundColorAttributeName: [NSColor yellowColor], NSForegroundColorAttributeName: [NSColor redColor] }; ``` But when the window is in the background, it still uses the system default light grey. I've attached screenshots of the above code with active vs inactive window. — how can I change the selected text background colour of the inactive window?

Original source