diff --git a/Sources/CodeEditTextView/Extensions/NSColor+Greyscale.swift b/Sources/CodeEditTextView/Extensions/NSColor+Greyscale.swift new file mode 100644 index 00000000..4afd858a --- /dev/null +++ b/Sources/CodeEditTextView/Extensions/NSColor+Greyscale.swift @@ -0,0 +1,17 @@ +// +// NSColor+Greyscale.swift +// CodeEditTextView +// +// Created by Khan Winter on 2/2/24. +// + +import AppKit + +extension NSColor { + var grayscale: NSColor { + guard let color = self.usingColorSpace(.deviceRGB) else { return self } + // linear relative weights for grayscale: https://en.wikipedia.org/wiki/Grayscale + let gray = 0.299 * color.redComponent + 0.587 * color.greenComponent + 0.114 * color.blueComponent + return NSColor(white: gray, alpha: color.alphaComponent) + } +} diff --git a/Sources/CodeEditTextView/TextSelectionManager/TextSelectionManager.swift b/Sources/CodeEditTextView/TextSelectionManager/TextSelectionManager.swift index fb7cb4b0..c26b0e20 100644 --- a/Sources/CodeEditTextView/TextSelectionManager/TextSelectionManager.swift +++ b/Sources/CodeEditTextView/TextSelectionManager/TextSelectionManager.swift @@ -269,7 +269,12 @@ public class TextSelectionManager: NSObject { /// - context: The context to draw in. private func drawSelectedRange(in rect: NSRect, for textSelection: TextSelection, context: CGContext) { context.saveGState() - context.setFillColor(selectionBackgroundColor.cgColor) + + let fillColor = (textView?.isFirstResponder ?? false) + ? selectionBackgroundColor.cgColor + : selectionBackgroundColor.grayscale.cgColor + + context.setFillColor(fillColor) let fillRects = getFillRects(in: rect, for: textSelection) diff --git a/Sources/CodeEditTextView/TextView/TextView.swift b/Sources/CodeEditTextView/TextView/TextView.swift index c55ac58c..90285fd3 100644 --- a/Sources/CodeEditTextView/TextView/TextView.swift +++ b/Sources/CodeEditTextView/TextView/TextView.swift @@ -314,12 +314,14 @@ public class TextView: NSView, NSTextContent { open override func becomeFirstResponder() -> Bool { isFirstResponder = true selectionManager.cursorTimer.resetTimer() + needsDisplay = true return super.becomeFirstResponder() } open override func resignFirstResponder() -> Bool { isFirstResponder = false selectionManager.removeCursors() + needsDisplay = true return super.resignFirstResponder() }