diff options
-rw-r--r-- | cocoa/ScintillaCocoa.h | 2 | ||||
-rw-r--r-- | cocoa/ScintillaCocoa.mm | 56 | ||||
-rw-r--r-- | cocoa/ScintillaView.mm | 25 |
3 files changed, 83 insertions, 0 deletions
diff --git a/cocoa/ScintillaCocoa.h b/cocoa/ScintillaCocoa.h index d07ffe758..f99c39770 100644 --- a/cocoa/ScintillaCocoa.h +++ b/cocoa/ScintillaCocoa.h @@ -247,6 +247,8 @@ public: void SetFirstResponder(bool isFirstResponder_); void ActiveStateChanged(bool isActive_); void SetFocusActiveState(); + void UpdateBaseElements() override; + void WindowWillMove(); // Find indicator diff --git a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm index c4569144e..602ca30d6 100644 --- a/cocoa/ScintillaCocoa.mm +++ b/cocoa/ScintillaCocoa.mm @@ -2525,6 +2525,62 @@ void ScintillaCocoa::SetFocusActiveState() { //-------------------------------------------------------------------------------------------------- +namespace { + +/** + * Convert from an NSColor into a ColourAlpha + */ +ColourAlpha ColourFromNSColor(NSColor *value) { + return ColourAlpha(static_cast<unsigned int>(value.redComponent * componentMaximum), + static_cast<unsigned int>(value.greenComponent * componentMaximum), + static_cast<unsigned int>(value.blueComponent * componentMaximum), + static_cast<unsigned int>(value.alphaComponent * componentMaximum)); +} + +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Update ViewStyle::elementBaseColours to match system preferences. + */ +void ScintillaCocoa::UpdateBaseElements() { + NSView *content = ContentView(); + NSAppearance *saved = [NSAppearance currentAppearance]; + [NSAppearance setCurrentAppearance:content.effectiveAppearance]; + + bool changed = false; + if (@available(macOS 10.14, *)) { + NSColor *textBack = [NSColor.textBackgroundColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + NSColor *noFocusBack = [NSColor.unemphasizedSelectedTextBackgroundColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + if (vs.selection.layer == Layer::base) { + NSColor *selBack = [NSColor.selectedTextBackgroundColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + // Additional selection: blend with text background to make weaker version. + NSColor *modified = [selBack blendedColorWithFraction:0.5 ofColor:textBack]; + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_BACK, ColourFromNSColor(selBack)); + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_ADDITIONAL_BACK, ColourFromNSColor(modified)) || changed; + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_NO_FOCUS_BACK, ColourFromNSColor(noFocusBack)) || changed; + } else { + // Less translucent colour used in dark mode as otherwise less visible + const int alpha = textBack.brightnessComponent > 0.5 ? 0x40 : 0x60; + // Make a translucent colour that approximates selectedTextBackgroundColor + NSColor *accent = [NSColor.controlAccentColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + const ColourAlpha colourAccent = ColourFromNSColor(accent); + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_BACK, ColourAlpha(colourAccent, alpha)); + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_ADDITIONAL_BACK, ColourAlpha(colourAccent, alpha/2)) || changed; + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_NO_FOCUS_BACK, ColourAlpha(ColourFromNSColor(noFocusBack), alpha)) || changed; + + } + } + if (changed) { + Redraw(); + } + + [NSAppearance setCurrentAppearance:saved]; +} + +//-------------------------------------------------------------------------------------------------- + /** * When the window is about to move, the calltip and autcoimpletion stay in the same spot, * so cancel them. diff --git a/cocoa/ScintillaView.mm b/cocoa/ScintillaView.mm index 593722c1e..f878a7a6b 100644 --- a/cocoa/ScintillaView.mm +++ b/cocoa/ScintillaView.mm @@ -338,6 +338,17 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) { //-------------------------------------------------------------------------------------------------- /** + * Gets called by the runtime when the effective appearance changes. + */ +- (void) viewDidChangeEffectiveAppearance { + if (mOwner.backend) { + mOwner.backend->UpdateBaseElements(); + } +} + +//-------------------------------------------------------------------------------------------------- + +/** * Gets called by the runtime when the view needs repainting. */ - (void) drawRect: (NSRect) rect { @@ -1454,11 +1465,18 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) { name: NSWindowWillMoveNotification object: self.window]; + [center addObserver: self + selector: @selector(defaultsDidChange:) + name: NSSystemColorsDidChangeNotification + object: self.window]; + [scrollView.contentView setPostsBoundsChangedNotifications: YES]; [center addObserver: self selector: @selector(scrollerAction:) name: NSViewBoundsDidChangeNotification object: scrollView.contentView]; + + mBackend->UpdateBaseElements(); } return self; } @@ -1498,6 +1516,13 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) { //-------------------------------------------------------------------------------------------------- +- (void) defaultsDidChange: (NSNotification *) note { +#pragma unused(note) + mBackend->UpdateBaseElements(); +} + +//-------------------------------------------------------------------------------------------------- + - (void) viewDidMoveToWindow { [super viewDidMoveToWindow]; |