diff --git a/runtime/doc/gui_mac.txt b/runtime/doc/gui_mac.txt
index df2644f4e2..619c88a314 100644
--- a/runtime/doc/gui_mac.txt
+++ b/runtime/doc/gui_mac.txt
@@ -310,11 +310,6 @@ KEY VALUE ~
*MMScrollOneDirectionOnly* scroll along one axis only when using trackpad [bool]
*MMSmoothResize* allow smooth resizing of MacVim window [bool]
*MMShareFindPboard* share search text to Find Pasteboard [bool]
-*MMShowAddTabButton* enable "add tab" button on tabline [bool]
-*MMShowTabScrollButtons* enable tab scroll buttons on tabline [bool]
-*MMTabMinWidth* minimum width of a tab [int]
-*MMTabOptimumWidth* default width of a tab [int]
-*MMDefaultTablineColors* use default colors instead of colorscheme for tabs [bool]
*MMTextInsetBottom* text area offset in pixels [int]
*MMTextInsetLeft* text area offset in pixels [int]
*MMTextInsetRight* text area offset in pixels [int]
@@ -327,6 +322,14 @@ KEY VALUE ~
*MMUpdaterPrereleaseChannel* opt-in to pre-release software update [bool]
*MMShowWhatsNewOnStartup* show "What's New" after updating to new version [bool]
+Tabs ~
+*MMTabColorsMode* use default/auto/colorscheme for tab colors [int]
+*MMWindowUseTabBackgroundColor* use tabs background fill color as window color [bool]
+*MMShowAddTabButton* enable "add tab" button on tabline [bool]
+*MMShowTabScrollButtons* enable tab scroll buttons on tabline [bool]
+*MMTabMinWidth* minimum width of a tab [int]
+*MMTabOptimumWidth* default width of a tab [int]
+
As an example, if you have more than one mouse button and would wish to free
up Ctrl-click so you can bind it to something else, then the appropriate
command is: >
diff --git a/runtime/doc/tags b/runtime/doc/tags
index d8b5f59472..b55d15bddf 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -5645,7 +5645,6 @@ MMAllowForceClickLookUp gui_mac.txt /*MMAllowForceClickLookUp*
MMAppearanceModeSelection gui_mac.txt /*MMAppearanceModeSelection*
MMCellWidthMultiplier gui_mac.txt /*MMCellWidthMultiplier*
MMCmdLineAlignBottom gui_mac.txt /*MMCmdLineAlignBottom*
-MMDefaultTablineColors gui_mac.txt /*MMDefaultTablineColors*
MMDialogsTrackPwd gui_mac.txt /*MMDialogsTrackPwd*
MMDisableLaunchAnimation gui_mac.txt /*MMDisableLaunchAnimation*
MMDisableTablineAnimation gui_mac.txt /*MMDisableTablineAnimation*
@@ -5666,6 +5665,7 @@ MMShowAddTabButton gui_mac.txt /*MMShowAddTabButton*
MMShowTabScrollButtons gui_mac.txt /*MMShowTabScrollButtons*
MMShowWhatsNewOnStartup gui_mac.txt /*MMShowWhatsNewOnStartup*
MMSmoothResize gui_mac.txt /*MMSmoothResize*
+MMTabColorsMode gui_mac.txt /*MMTabColorsMode*
MMTabMinWidth gui_mac.txt /*MMTabMinWidth*
MMTabOptimumWidth gui_mac.txt /*MMTabOptimumWidth*
MMTextInsetBottom gui_mac.txt /*MMTextInsetBottom*
@@ -5678,6 +5678,7 @@ MMTranslateCtrlClick gui_mac.txt /*MMTranslateCtrlClick*
MMUpdaterPrereleaseChannel gui_mac.txt /*MMUpdaterPrereleaseChannel*
MMUseMouseTime gui_mac.txt /*MMUseMouseTime*
MMVerticalSplit gui_mac.txt /*MMVerticalSplit*
+MMWindowUseTabBackgroundColor gui_mac.txt /*MMWindowUseTabBackgroundColor*
MMZoomBoth gui_mac.txt /*MMZoomBoth*
MS-DOS os_msdos.txt /*MS-DOS*
MS-Windows os_win32.txt /*MS-Windows*
diff --git a/src/MacVim/Base.lproj/Preferences.xib b/src/MacVim/Base.lproj/Preferences.xib
index 1aa2e8057d..893ae01353 100644
--- a/src/MacVim/Base.lproj/Preferences.xib
+++ b/src/MacVim/Base.lproj/Preferences.xib
@@ -280,11 +280,11 @@
-
+
-
+
@@ -345,11 +345,11 @@
-
+
-
+
@@ -358,7 +358,7 @@
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
@@ -535,7 +569,7 @@
-
+
@@ -622,7 +656,7 @@
-
+
diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m
index 1dd4ac5a4e..89d347609e 100644
--- a/src/MacVim/MMAppController.m
+++ b/src/MacVim/MMAppController.m
@@ -178,6 +178,9 @@ + (void)registerDefaults
[NSNumber numberWithInt:210], MMTabOptimumWidthKey,
[NSNumber numberWithBool:YES], MMShowAddTabButtonKey,
[NSNumber numberWithBool:NO], MMShowTabScrollButtonsKey,
+ [NSNumber numberWithInt:MMTabColorsModeAutomatic],
+ MMTabColorsModeKey,
+ [NSNumber numberWithBool:NO], MMWindowUseTabBackgroundColorKey,
[NSNumber numberWithInt:2], MMTextInsetLeftKey,
[NSNumber numberWithInt:1], MMTextInsetRightKey,
[NSNumber numberWithInt:1], MMTextInsetTopKey,
@@ -1238,7 +1241,7 @@ - (void)refreshAllAppearances
- (void)refreshAllTabProperties
{
for (MMVimController *vc in vimControllers) {
- [vc.windowController.vimView refreshTabProperties];
+ [vc.windowController refreshTabProperties];
}
}
diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h
index 6a730a0f3f..e8271f2ded 100644
--- a/src/MacVim/MMBackend.h
+++ b/src/MacVim/MMBackend.h
@@ -62,6 +62,7 @@
- (void)setBackgroundColor:(int)color;
- (void)setForegroundColor:(int)color;
- (void)setSpecialColor:(int)color;
+- (void)setTablineColors:(int[6])colors;
- (void)setDefaultColorsBackground:(int)bg foreground:(int)fg;
- (NSConnection *)connection;
- (NSDictionary *)actionDict;
diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m
index 9f38769967..0d35f841a3 100644
--- a/src/MacVim/MMBackend.m
+++ b/src/MacVim/MMBackend.m
@@ -293,6 +293,17 @@ - (void)setSpecialColor:(int)color
specialColor = MM_COLOR(color);
}
+- (void)setTablineColors:(int[6])colors
+{
+ unsigned tabColors[6];
+ for (int i = 0; i < 6; i++) {
+ tabColors[i] = MM_COLOR(colors[i]);
+ }
+ NSMutableData *data = [NSMutableData data];
+ [data appendBytes:&tabColors length:sizeof(tabColors)];
+ [self queueMessage:SetTablineColorsMsgID data:data];
+}
+
- (void)setDefaultColorsBackground:(int)bg foreground:(int)fg
{
defaultBackgroundColor = MM_COLOR_WITH_TRANSP(bg,p_transp);
diff --git a/src/MacVim/MMTabline/MMTab.m b/src/MacVim/MMTabline/MMTab.m
index 1b6de407a9..235af717dc 100644
--- a/src/MacVim/MMTabline/MMTab.m
+++ b/src/MacVim/MMTabline/MMTab.m
@@ -3,9 +3,10 @@
#import "MMTabline.h"
#import "MMHoverButton.h"
-#import "MacVim.h" // for availability macros
+// Only imported for AVAILABLE_MAC_OS
+#import "MacVim.h"
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_13
+#if !defined(MAC_OS_X_VERSION_10_13) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_13
typedef NSString * NSAnimatablePropertyKey;
#endif
@@ -46,7 +47,7 @@ - (instancetype)initWithFrame:(NSRect)frameRect tabline:(MMTabline *)tabline
[self addSubview:_closeButton];
_titleLabel = [NSTextField new];
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11
+#if defined(MAC_OS_X_VERSION_10_11) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11
if (AVAILABLE_MAC_OS(10,11)) {
_titleLabel.font = [NSFont systemFontOfSize:NSFont.smallSystemFontSize weight:NSFontWeightSemibold];
} else
@@ -109,27 +110,29 @@ - (void)setFillColor:(NSColor *)fillColor
- (void)setState:(MMTabState)state
{
+ const BOOL hasFocus = (self.window == nil) || [self.window isKeyWindow];
+
// Transitions to and from MMTabStateSelected
// DO NOT animate so that UX feels snappier.
if (state == MMTabStateSelected) {
_closeButton.fgColor = _tabline.tablineSelFgColor;
- _titleLabel.textColor = _tabline.tablineSelFgColor;
+ _titleLabel.textColor = hasFocus ? _tabline.tablineSelFgColor : _tabline.tablineUnfocusedSelFgColor;
self.fillColor = _tabline.tablineSelBgColor;
}
else if (state == MMTabStateUnselected) {
if (_state == MMTabStateSelected) {
_closeButton.fgColor = _tabline.tablineFgColor;
- _titleLabel.textColor = _tabline.tablineFgColor;
+ _titleLabel.textColor = hasFocus ? _tabline.tablineFgColor : _tabline.tablineUnfocusedFgColor;
self.fillColor = _tabline.tablineBgColor;
} else {
_closeButton.animator.fgColor = _tabline.tablineFgColor;
- _titleLabel.animator.textColor = _tabline.tablineFgColor;
+ _titleLabel.animator.textColor = hasFocus ? _tabline.tablineFgColor : _tabline.tablineUnfocusedFgColor;
self.animator.fillColor = _tabline.tablineBgColor;
}
}
else { // state == MMTabStateUnselectedHover
_closeButton.animator.fgColor = _tabline.tablineSelFgColor;
- _titleLabel.animator.textColor = _tabline.tablineSelFgColor;
+ _titleLabel.animator.textColor = hasFocus ? _tabline.tablineSelFgColor : _tabline.tablineUnfocusedSelFgColor;
self.animator.fillColor = self.unselectedHoverColor;
}
_state = state;
@@ -164,6 +167,11 @@ - (void)drawRect:(NSRect)dirtyRect
[p transformUsingAffineTransform:transform];
}
[p fill];
+ NSColor *strokeColor = _tabline.tablineStrokeColor;
+ if (strokeColor != nil) {
+ [strokeColor set];
+ [p stroke];
+ }
}
@end
diff --git a/src/MacVim/MMTabline/MMTabline.h b/src/MacVim/MMTabline/MMTabline.h
index a43be7828b..98bef13bdf 100644
--- a/src/MacVim/MMTabline/MMTabline.h
+++ b/src/MacVim/MMTabline/MMTabline.h
@@ -19,11 +19,18 @@
@property (nonatomic) BOOL useAnimation;
@property (nonatomic, readonly) NSInteger numberOfTabs;
@property (nonatomic, retain, readonly) MMHoverButton *addTabButton;
+
@property (nonatomic, retain) NSColor *tablineBgColor;
@property (nonatomic, retain) NSColor *tablineFgColor;
@property (nonatomic, retain) NSColor *tablineSelBgColor;
@property (nonatomic, retain) NSColor *tablineSelFgColor;
@property (nonatomic, retain) NSColor *tablineFillFgColor;
+
+// Derived colors that cannot be set directly
+@property (nonatomic, readonly) NSColor *tablineUnfocusedFgColor;
+@property (nonatomic, readonly) NSColor *tablineUnfocusedSelFgColor;
+@property (nonatomic, readonly) NSColor *tablineStrokeColor;
+
@property (nonatomic, weak) id delegate;
/// Add a tab at the end. It's not selected automatically.
@@ -57,7 +64,16 @@
- (void)scrollTabToVisibleAtIndex:(NSInteger)index;
- (void)scrollBackwardOneTab;
- (void)scrollForwardOneTab;
-- (void)setTablineSelBackground:(NSColor *)back foreground:(NSColor *)fore;
+
+/// Sets the colors used by this tab bar explicitly. Pass nil to use default
+/// colors based on the system light/dark modes.
+- (void)setColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
+ selBg:(NSColor *)selBg selFg:(NSColor *)selFg
+ fill:(NSColor *)fill;
+
+/// Lets the tabline calculate best colors to use based on background and
+/// foreground colors of the selected tab. The colors cannot be nil.
+- (void)setAutoColorsSelBg:(NSColor *)back fg:(NSColor *)fore;
@end
diff --git a/src/MacVim/MMTabline/MMTabline.m b/src/MacVim/MMTabline/MMTabline.m
index ff90d46d01..dd237ec239 100644
--- a/src/MacVim/MMTabline/MMTabline.m
+++ b/src/MacVim/MMTabline/MMTabline.m
@@ -1,6 +1,8 @@
#import
#import
#import "MMTabline.h"
+
+// Only imported for getCurrentAppearance()
#import "Miscellaneous.h"
typedef struct TabWidth {
@@ -26,9 +28,20 @@
return button;
}
-static BOOL isDarkMode(NSAppearance *appearance) {
- int flags = getCurrentAppearance(appearance);
- return (flags == 1 || flags == 3);
+static CGFloat calculateBrightness(NSColor *color) {
+ if (color.colorSpace.colorSpaceModel == NSColorSpaceModelRGB) {
+ // Calculate brightness according to a formula from
+ // the W3C that gives brightness as the eye perceives it. Then lighten
+ // or darken the default colors based on whether brightness is greater
+ // than 50% to achieve good visual contrast.
+ // www.w3.org/WAI/ER/WD-AERT/#color-contrast
+ CGFloat r, g, b;
+ [color getRed:&r green:&g blue:&b alpha:NULL];
+ return r * 0.299 + g * 0.114 + b * 0.587;
+ } else if (color.colorSpace.colorSpaceModel == NSColorSpaceModelGray) {
+ return color.whiteComponent;
+ }
+ return 1;
}
@implementation MMTabline
@@ -47,6 +60,7 @@ @implementation MMTabline
MMHoverButton *_backwardScrollButton;
MMHoverButton *_forwardScrollButton;
id _scrollWheelEventMonitor;
+ AppearanceType _appearance; // cached appearance to avoid querying it every time
}
@synthesize tablineBgColor = _tablineBgColor;
@@ -54,6 +68,8 @@ @implementation MMTabline
@synthesize tablineSelBgColor = _tablineSelBgColor;
@synthesize tablineSelFgColor = _tablineSelFgColor;
@synthesize tablineFillFgColor = _tablineFillFgColor;
+@synthesize tablineUnfocusedFgColor = _tablineUnfocusedFgColor;
+@synthesize tablineUnfocusedSelFgColor = _tablineUnfocusedSelFgColor;
- (instancetype)initWithFrame:(NSRect)frameRect
{
@@ -111,11 +127,15 @@ - (instancetype)initWithFrame:(NSRect)frameRect
[self addConstraint:_addTabButtonTrailingConstraint];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didScroll:) name:NSViewBoundsDidChangeNotification object:_scrollView.contentView];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTabStates) name:NSWindowDidBecomeKeyNotification object:self.window];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTabStates) name:NSWindowDidResignKeyNotification object:self.window];
if ([self useRightToLeft]) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTabsContainerBoundsForRTL:) name:NSViewFrameDidChangeNotification object:_tabsContainer];
}
[self addScrollWheelMonitor];
+
+ _appearance = getCurrentAppearance(self.effectiveAppearance);
}
return self;
}
@@ -135,7 +155,8 @@ - (void)updateLayer
- (void)viewDidChangeEffectiveAppearance
{
- for (MMTab *tab in _tabs) tab.state = tab.state;
+ _appearance = getCurrentAppearance(self.effectiveAppearance);
+ [self updateTabStates];
}
- (void)viewDidHide
@@ -217,39 +238,50 @@ - (void)setShowsTabScrollButtons:(BOOL)showsTabScrollButtons
- (NSColor *)tablineBgColor
{
- return _tablineBgColor ?: isDarkMode(self.effectiveAppearance)
- ? [NSColor colorWithWhite:0.2 alpha:1]
- : [NSColor colorWithWhite:0.8 alpha:1];
+ if (_tablineBgColor != nil)
+ return _tablineBgColor;
+ switch (_appearance) {
+ case AppearanceLight:
+ default:
+ return [NSColor colorWithWhite:0.8 alpha:1];
+ case AppearanceDark:
+ return [NSColor colorWithWhite:0.2 alpha:1];
+ case AppearanceLightHighContrast:
+ return [NSColor colorWithWhite:0.7 alpha:1];
+ case AppearanceDarkHighContrast:
+ return [NSColor colorWithWhite:0.15 alpha:1];
+ }
}
- (void)setTablineBgColor:(NSColor *)color
{
_tablineBgColor = color;
- for (MMTab *tab in _tabs) tab.state = tab.state;
+ [self updateTabStates];
}
- (NSColor *)tablineFgColor
{
- return _tablineFgColor ?: NSColor.disabledControlTextColor;
+ return _tablineFgColor ?: NSColor.secondaryLabelColor;
}
- (void)setTablineFgColor:(NSColor *)color
{
_tablineFgColor = color;
- for (MMTab *tab in _tabs) tab.state = tab.state;
+ _tablineUnfocusedFgColor = nil;
+ [self updateTabStates];
}
- (NSColor *)tablineSelBgColor
{
- return _tablineSelBgColor ?: isDarkMode(self.effectiveAppearance)
- ? [NSColor colorWithWhite:0.4 alpha:1]
- : NSColor.whiteColor;
+ return _tablineSelBgColor ?: (_appearance == AppearanceLight || _appearance == AppearanceLightHighContrast)
+ ? [NSColor colorWithWhite:0.95 alpha:1]
+ : [NSColor colorWithWhite:0.4 alpha:1];
}
- (void)setTablineSelBgColor:(NSColor *)color
{
_tablineSelBgColor = color;
- for (MMTab *tab in _tabs) tab.state = tab.state;
+ [self updateTabStates];
}
- (NSColor *)tablineSelFgColor
@@ -260,17 +292,18 @@ - (NSColor *)tablineSelFgColor
- (void)setTablineSelFgColor:(NSColor *)color
{
_tablineSelFgColor = color;
+ _tablineUnfocusedSelFgColor = nil;
_addTabButton.fgColor = color;
_backwardScrollButton.fgColor = color;
_forwardScrollButton.fgColor = color;
- for (MMTab *tab in _tabs) tab.state = tab.state;
+ [self updateTabStates];
}
- (NSColor *)tablineFillFgColor
{
- return _tablineFillFgColor ?: isDarkMode(self.effectiveAppearance)
- ? [NSColor colorWithWhite:0.2 alpha:1]
- : [NSColor colorWithWhite:0.8 alpha:1];
+ return _tablineFillFgColor ?: (_appearance == AppearanceLight || _appearance == AppearanceLightHighContrast)
+ ? [NSColor colorWithWhite:0.9 alpha:1]
+ : [NSColor colorWithWhite:0.25 alpha:1];
}
- (void)setTablineFillFgColor:(NSColor *)color
@@ -279,6 +312,30 @@ - (void)setTablineFillFgColor:(NSColor *)color
self.needsDisplay = YES;
}
+- (NSColor *)tablineUnfocusedFgColor
+{
+ return _tablineUnfocusedFgColor ?: _tablineFgColor ?: NSColor.tertiaryLabelColor;
+}
+
+- (NSColor *)tablineUnfocusedSelFgColor
+{
+ return _tablineUnfocusedSelFgColor ?: _tablineSelFgColor ?: NSColor.tertiaryLabelColor;
+}
+
+- (NSColor *)tablineStrokeColor
+{
+ if (_appearance == AppearanceLight || _appearance == AppearanceDark)
+ return nil; // non-high-contrast modes
+
+ // High-contrast modes. Should stroke to make it easier to read.
+ NSColor *bgColor = self.tablineBgColor;
+ CGFloat brightness = calculateBrightness(bgColor);
+ if (brightness > 0.5)
+ return NSColor.blackColor;
+ else
+ return NSColor.whiteColor;
+}
+
- (NSInteger)addTabAtEnd
{
return [self addTabAtIndex:(_tabs.count ? _tabs.count : 0)];
@@ -511,43 +568,59 @@ - (MMTab *)tabAtIndex:(NSInteger)index
return _tabs[index];
}
-- (void)setTablineSelBackground:(NSColor *)back foreground:(NSColor *)fore
+- (void)setColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
+ selBg:(NSColor *)selBg selFg:(NSColor *)selFg
+ fill:(NSColor *)fill
{
- // Reset to default tabline colors if user doesn't want auto-generated ones.
- if ([NSUserDefaults.standardUserDefaults boolForKey:@"MMDefaultTablineColors"]) {
- self.tablineBgColor = nil;
- self.tablineFgColor = nil;
- self.tablineSelBgColor = nil;
- self.tablineSelFgColor = nil;
- self.tablineFillFgColor = nil;
- return;
- }
+ // Don't use the property mutators as we just want to update the states in
+ // one go at the end.
+ _tablineSelBgColor = selBg;
+ _tablineSelFgColor = selFg;
+ _tablineBgColor = tabBg;
+ _tablineFgColor = tabFg;
+ _tablineFillFgColor = fill;
+
+ _tablineUnfocusedFgColor = [_tablineFgColor blendedColorWithFraction:0.4 ofColor:_tablineBgColor];
+ _tablineUnfocusedSelFgColor = [_tablineSelFgColor blendedColorWithFraction:0.38 ofColor:_tablineSelBgColor];
+
+ _addTabButton.fgColor = _tablineSelFgColor;
+ _backwardScrollButton.fgColor = _tablineSelFgColor;
+ _forwardScrollButton.fgColor = _tablineSelFgColor;
+
+ [self updateTabStates];
+ self.needsDisplay = YES;
+}
+- (void)setAutoColorsSelBg:(NSColor *)back fg:(NSColor *)fore;
+{
// Set the colors for the tabline based on the default background and
- // foreground colors. Calculate brightness according to a formula from
- // the W3C that gives brightness as the eye perceives it. Then lighten
- // or darken the default colors based on whether brightness is greater
- // than 50% to achieve good visual contrast.
- // www.w3.org/WAI/ER/WD-AERT/#color-contrast
- CGFloat r, g, b, brightness;
- [back getRed:&r green:&g blue:&b alpha:NULL];
- brightness = r * 0.299 + g * 0.114 + b * 0.587;
-
- self.tablineSelBgColor = back;
+ // foreground colors.
+ const CGFloat brightness = calculateBrightness(back);
- self.tablineSelFgColor = (brightness > 0.5)
+ _tablineSelBgColor = back;
+
+ _tablineSelFgColor = (brightness > 0.5)
? [fore blendedColorWithFraction:0.6 ofColor:NSColor.blackColor]
: [fore blendedColorWithFraction:0.6 ofColor:NSColor.whiteColor];
+ _addTabButton.fgColor = _tablineSelFgColor;
+ _backwardScrollButton.fgColor = _tablineSelFgColor;
+ _forwardScrollButton.fgColor = _tablineSelFgColor;
- self.tablineBgColor = (brightness > 0.5)
+ _tablineBgColor = (brightness > 0.5)
? [back blendedColorWithFraction:0.16 ofColor:NSColor.blackColor]
: [back blendedColorWithFraction:0.13 ofColor:NSColor.whiteColor];
- self.tablineFgColor = [self.tablineSelFgColor blendedColorWithFraction:0.5 ofColor:self.tablineBgColor];
+ _tablineFgColor = [_tablineSelFgColor blendedColorWithFraction:0.5 ofColor:_tablineBgColor];
+
+ _tablineUnfocusedFgColor = [_tablineFgColor blendedColorWithFraction:0.4 ofColor:_tablineBgColor];
+ _tablineUnfocusedSelFgColor = [_tablineSelFgColor blendedColorWithFraction:0.38 ofColor:_tablineSelBgColor];
- self.tablineFillFgColor = (brightness > 0.5)
+ _tablineFillFgColor = (brightness > 0.5)
? [back blendedColorWithFraction:0.25 ofColor:NSColor.blackColor]
: [back blendedColorWithFraction:0.18 ofColor:NSColor.whiteColor];
+
+ [self updateTabStates];
+ self.needsDisplay = YES;
}
#pragma mark - Helpers
@@ -740,6 +813,11 @@ - (void)fixupLayoutWithAnimation:(BOOL)shouldAnimate
[self fixupLayoutWithAnimation:shouldAnimate delayResize:NO];
}
+- (void)updateTabStates
+{
+ for (MMTab *tab in _tabs) tab.state = tab.state;
+}
+
#pragma mark - Right-to-left (RTL) support
- (BOOL)useRightToLeft
@@ -943,7 +1021,7 @@ - (void)scrollTabToVisibleAtIndex:(NSInteger)index
// faster animations. For example, the user might hold down the tab
// scrolling buttons (causing them to repeatedly fire) or they might
// rapidly click them.
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
+#if defined(MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
static NSTimeInterval lastTime = 0;
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m
index df12bfa0f4..12fa382f12 100644
--- a/src/MacVim/MMVimController.m
+++ b/src/MacVim/MMVimController.m
@@ -968,6 +968,26 @@ - (void)handleMessage:(int)msgid data:(NSData *)data
}
}
break;
+ case SetTablineColorsMsgID:
+ {
+ const void *bytes = [data bytes];
+ unsigned argbTabBg = *((unsigned*)bytes); bytes += sizeof(unsigned);
+ unsigned argbTabFg = *((unsigned*)bytes); bytes += sizeof(unsigned);
+ unsigned argbFillBg = *((unsigned*)bytes); bytes += sizeof(unsigned);
+ unsigned argbFillFg = *((unsigned*)bytes); bytes += sizeof(unsigned);
+ unsigned argbSelBg = *((unsigned*)bytes); bytes += sizeof(unsigned);
+ unsigned argbSelFg = *((unsigned*)bytes); bytes += sizeof(unsigned);
+
+ NSColor *tabBg = [NSColor colorWithRgbInt:argbTabBg];
+ NSColor *tabFg = [NSColor colorWithRgbInt:argbTabFg];
+ NSColor *fillBg = [NSColor colorWithRgbInt:argbFillBg];
+ NSColor *fillFg = [NSColor colorWithRgbInt:argbFillFg];
+ NSColor *selBg = [NSColor colorWithRgbInt:argbSelBg];
+ NSColor *selFg = [NSColor colorWithRgbInt:argbSelFg];
+
+ [windowController setTablineColorsTabBg:tabBg tabFg:tabFg fillBg:fillBg fillFg:fillFg selBg:selBg selFg:selFg];
+ }
+ break;
case SetDefaultColorsMsgID:
{
const void *bytes = [data bytes];
diff --git a/src/MacVim/MMVimView.h b/src/MacVim/MMVimView.h
index d29b75c63c..f1a49009b3 100644
--- a/src/MacVim/MMVimView.h
+++ b/src/MacVim/MMVimView.h
@@ -60,6 +60,9 @@
- (void)finishPlaceScrollbars;
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore;
+- (void)setTablineColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
+ fillBg:(NSColor *)fillBg fillFg:(NSColor *)fillFg
+ selBg:(NSColor *)selBg selFg:(NSColor *)selFg;
- (void)viewWillStartLiveResize;
- (void)viewDidEndLiveResize;
diff --git a/src/MacVim/MMVimView.m b/src/MacVim/MMVimView.m
index 96c6273094..9a7a5a4781 100644
--- a/src/MacVim/MMVimView.m
+++ b/src/MacVim/MMVimView.m
@@ -35,6 +35,15 @@
MMScrollerTypeBottom
};
+typedef enum: NSInteger {
+ MMTabColorTypeTabBg = 0,
+ MMTabColorTypeTabFg,
+ MMTabColorTypeSelBg,
+ MMTabColorTypeSelFg,
+ MMTabColorTypeFill,
+ MMTabColorTypeCount
+} MMTabColorType;
+
// TODO: Move!
@interface MMScroller : NSScroller {
@@ -72,6 +81,9 @@ - (void)liveResizeDidEnd;
@implementation MMVimView
+{
+ NSColor *tabColors[MMTabColorTypeCount];
+}
- (MMVimView *)initWithFrame:(NSRect)frame
vimController:(MMVimController *)controller
@@ -133,6 +145,9 @@ - (void)dealloc
[tabline release];
[scrollbars release]; scrollbars = nil;
+ for (NSUInteger i = 0; i < MMTabColorTypeCount; i++)
+ [tabColors[i] release];
+
// HACK! The text storage is the principal owner of the text system, but we
// keep only a reference to the text view, so release the text storage
// first (unless we are using the CoreText renderer).
@@ -362,6 +377,7 @@ - (void)refreshTabProperties
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
tabline.showsTabScrollButtons = [ud boolForKey:MMShowTabScrollButtonsKey];
+ [self updateTablineColors];
}
- (void)createScrollbarWithIdentifier:(int32_t)ident type:(int)type
@@ -453,11 +469,36 @@ - (void)finishPlaceScrollbars
}
}
+- (void)updateTablineColors
+{
+ NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+ MMTabColorsMode tabColorsMode = [ud integerForKey:MMTabColorsModeKey];
+ if (tabColorsMode == MMTabColorsModeDefaultColors) {
+ [tabline setColorsTabBg:nil
+ tabFg:nil
+ selBg:nil
+ selFg:nil
+ fill:nil];
+ } else if (tabColorsMode == MMTabColorsModeVimColorscheme) {
+ [tabline setColorsTabBg:tabColors[MMTabColorTypeTabBg]
+ tabFg:tabColors[MMTabColorTypeTabFg]
+ selBg:tabColors[MMTabColorTypeSelBg]
+ selFg:tabColors[MMTabColorTypeSelFg]
+ fill:tabColors[MMTabColorTypeFill]];
+ } else {
+ // tabColorsMode == MMTabColorsModeAutomatic, but catch-all in case it's
+ // set to an out-of-range number.
+ NSColor *back = [[self textView] defaultBackgroundColor];
+ NSColor *fore = [[self textView] defaultForegroundColor];
+ [tabline setAutoColorsSelBg:back fg:fore];
+ }
+
+}
+
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore
{
[textView setDefaultColorsBackground:back foreground:fore];
-
- [tabline setTablineSelBackground:back foreground:fore];
+ [self updateTablineColors];
CALayer *backedLayer = [self layer];
if (backedLayer) {
@@ -476,6 +517,21 @@ - (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore
[self setNeedsDisplay:YES];
}
+- (void)setTablineColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
+ fillBg:(NSColor *)fillBg fillFg:(NSColor *)fillFg
+ selBg:(NSColor *)selBg selFg:(NSColor *)selFg
+{
+ for (NSUInteger i = 0; i < MMTabColorTypeCount; i++)
+ [tabColors[i] release];
+ tabColors[MMTabColorTypeTabBg] = [tabBg retain];
+ tabColors[MMTabColorTypeTabFg] = [tabFg retain];
+ tabColors[MMTabColorTypeSelBg] = [selBg retain];
+ tabColors[MMTabColorTypeSelFg] = [selFg retain];
+ tabColors[MMTabColorTypeFill] = [fillBg retain];
+ (void)fillFg; // We don't use fillFg as we don't draw anything in the empty area
+ [self updateTablineColors];
+}
+
// -- MMTablineDelegate ----------------------------------------------
@@ -594,6 +650,19 @@ - (void)setFrame:(NSRect)frame
- (void)viewDidChangeEffectiveAppearance
{
[vimController appearanceChanged:getCurrentAppearance(self.effectiveAppearance)];
+
+ NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+ if ([ud integerForKey:MMTabColorsModeKey] == MMTabColorsModeDefaultColors &&
+ [ud boolForKey:MMWindowUseTabBackgroundColorKey])
+ {
+ // Tab line default colors depends on system light/dark modes. We will
+ // need to notify the window as well if it is set up to use the tab bar
+ // colors. We need to schedule this for later because the tabline's
+ // effectAppearance gets changed *after* this method is called, so we
+ // need to delay the refresh or we would get stale data.
+ MMWindowController *winController = [vimController windowController];
+ [winController performSelectorOnMainThread:@selector(refreshTabProperties) withObject:nil waitUntilDone:NO];
+ }
}
@end // MMVimView
diff --git a/src/MacVim/MMWindowController.h b/src/MacVim/MMWindowController.h
index df932f0e98..544385f8c2 100644
--- a/src/MacVim/MMWindowController.h
+++ b/src/MacVim/MMWindowController.h
@@ -84,7 +84,10 @@
- (void)setBackgroundOption:(int)dark;
- (void)refreshApperanceMode;
- (void)updateResizeConstraints:(BOOL)resizeWindow;
-
+- (void)setTablineColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
+ fillBg:(NSColor *)fillBg fillFg:(NSColor *)fillFg
+ selBg:(NSColor *)selBg selFg:(NSColor *)selFg;
+- (void)refreshTabProperties;
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore;
- (void)setFont:(NSFont *)font;
- (void)setWideFont:(NSFont *)font;
diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m
index e062796052..a583aa395f 100644
--- a/src/MacVim/MMWindowController.m
+++ b/src/MacVim/MMWindowController.m
@@ -71,6 +71,7 @@
#import "MMWindow.h"
#import "MMWindowController.h"
#import "Miscellaneous.h"
+#import "MMTabline/MMTabline.h"
// These have to be the same as in option.h
@@ -672,11 +673,61 @@ - (void)refreshApperanceMode
#endif
}
+- (void)setTablineColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
+ fillBg:(NSColor *)fillBg fillFg:(NSColor *)fillFg
+ selBg:(NSColor *)selBg selFg:(NSColor *)selFg
+{
+ [vimView setTablineColorsTabBg:tabBg tabFg:tabFg fillBg:fillBg fillFg:fillFg selBg:selBg selFg:selFg];
+
+ if([[NSUserDefaults standardUserDefaults] boolForKey:MMWindowUseTabBackgroundColorKey]) {
+ if (!vimView.tabline.hidden) {
+ [self setWindowColorToTablineColor];
+ }
+ }
+}
+
+- (void)setWindowColorToTablineColor
+{
+ NSColor *defaultBg = vimView.textView.defaultBackgroundColor;
+ NSColor *tablineColor = vimView.tabline.tablineFillFgColor;
+ if (defaultBg.alphaComponent == 1.0) {
+ [self setWindowBackgroundColor:tablineColor];
+ } else {
+ // Make sure 'transparency' Vim setting is preserved
+ NSColor *colorWithAlpha = [tablineColor colorWithAlphaComponent:defaultBg.alphaComponent];
+ [self setWindowBackgroundColor:colorWithAlpha];
+ }
+}
+
+- (void)refreshTabProperties
+{
+ [vimView refreshTabProperties];
+ NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+ if([ud boolForKey:MMWindowUseTabBackgroundColorKey] && !vimView.tabline.hidden) {
+ [self setWindowColorToTablineColor];
+ } else {
+ [self setWindowBackgroundColor:vimView.textView.defaultBackgroundColor];
+ }
+}
+
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore
+{
+ [vimView setDefaultColorsBackground:back foreground:fore];
+ if([[NSUserDefaults standardUserDefaults] boolForKey:MMWindowUseTabBackgroundColorKey] &&
+ !vimView.tabline.hidden)
+ {
+ [self setWindowColorToTablineColor];
+ }
+ else {
+ [self setWindowBackgroundColor:back];
+ }
+}
+
+- (void)setWindowBackgroundColor:(NSColor *)back
{
// NOTE: This is called when the transparency changes so set the opacity
// flag on the window here (should be faster if the window is opaque).
- BOOL isOpaque = [back alphaComponent] == 1.0f;
+ const BOOL isOpaque = [back alphaComponent] == 1.0f;
[decoratedWindow setOpaque:isOpaque];
if (fullScreenWindow)
[fullScreenWindow setOpaque:isOpaque];
@@ -727,7 +778,7 @@ - (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore
// but if we are toggling the titlebar transparent option, we need to set
// the window background color in order the title bar to be tinted correctly.
if ([[NSUserDefaults standardUserDefaults]
- boolForKey:MMTitlebarAppearsTransparentKey]) {
+ boolForKey:MMTitlebarAppearsTransparentKey]) {
if ([back alphaComponent] != 0) {
[decoratedWindow setBackgroundColor:back];
} else {
@@ -739,8 +790,6 @@ - (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore
}
}
}
-
- [vimView setDefaultColorsBackground:back foreground:fore];
}
- (void)setFont:(NSFont *)font
@@ -871,6 +920,14 @@ - (void)showTabline:(BOOL)on
[vimView showTabline:on];
[self updateTablineSeparator];
shouldMaximizeWindow = YES;
+
+ if([[NSUserDefaults standardUserDefaults] boolForKey:MMWindowUseTabBackgroundColorKey]) {
+ if (on) {
+ [self setWindowColorToTablineColor];
+ } else {
+ [self setWindowBackgroundColor:vimView.textView.defaultBackgroundColor];
+ }
+ }
}
- (void)showToolbar:(BOOL)on size:(int)size mode:(int)mode
diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h
index 515ebe8355..aa12b8c575 100644
--- a/src/MacVim/MacVim.h
+++ b/src/MacVim/MacVim.h
@@ -301,6 +301,7 @@ extern const char * const MMVimMsgIDStrings[];
MSG(SetWideFontMsgID) \
MSG(VimShouldCloseMsgID) \
MSG(SetDefaultColorsMsgID) \
+ MSG(SetTablineColorsMsgID) \
MSG(ExecuteActionMsgID) \
MSG(DropFilesMsgID) \
MSG(DropStringMsgID) \
diff --git a/src/MacVim/Miscellaneous.h b/src/MacVim/Miscellaneous.h
index 0d297dd094..a247b3f647 100644
--- a/src/MacVim/Miscellaneous.h
+++ b/src/MacVim/Miscellaneous.h
@@ -23,6 +23,8 @@ extern NSString *MMTabMaxWidthKey;
extern NSString *MMTabOptimumWidthKey;
extern NSString *MMShowAddTabButtonKey;
extern NSString *MMShowTabScrollButtonsKey;
+extern NSString *MMTabColorsModeKey;
+extern NSString *MMWindowUseTabBackgroundColorKey;
extern NSString *MMTextInsetLeftKey;
extern NSString *MMTextInsetRightKey;
extern NSString *MMTextInsetTopKey;
@@ -104,6 +106,11 @@ enum MMAppearanceModeSelectionEnum {
MMAppearanceModeSelectionBackgroundOption = 3,
};
+typedef enum : NSInteger {
+ MMTabColorsModeDefaultColors = 0, ///< Use default colors based on macOS light/dark modes
+ MMTabColorsModeAutomatic, ///< Automatically derive tab colors based on foreground/background colors
+ MMTabColorsModeVimColorscheme, ///< Use Vim colorscheme TabLine/TabLineSel/TabLineFill colors
+} MMTabColorsMode;
enum {
// These values are chosen so that the min text view size is not too small
@@ -174,7 +181,13 @@ NSView *showHiddenFilesView(void);
NSString *normalizeFilename(NSString *filename);
NSArray *normalizeFilenames(NSArray *filenames);
-int getCurrentAppearance(NSAppearance *appearance);
+typedef enum : int {
+ AppearanceLight = 0,
+ AppearanceDark,
+ AppearanceLightHighContrast,
+ AppearanceDarkHighContrast,
+} AppearanceType;
+AppearanceType getCurrentAppearance(NSAppearance *appearance);
// Pasteboard helpers
NSPasteboardType getPasteboardFilenamesType(void);
diff --git a/src/MacVim/Miscellaneous.m b/src/MacVim/Miscellaneous.m
index 0b1e0523e2..17e9304238 100644
--- a/src/MacVim/Miscellaneous.m
+++ b/src/MacVim/Miscellaneous.m
@@ -19,6 +19,8 @@
NSString *MMTabOptimumWidthKey = @"MMTabOptimumWidth";
NSString *MMShowAddTabButtonKey = @"MMShowAddTabButton";
NSString *MMShowTabScrollButtonsKey = @"MMShowTabScrollButtons";
+NSString *MMTabColorsModeKey = @"MMTabColorsMode";
+NSString *MMWindowUseTabBackgroundColorKey = @"MMWindowUseTabBackgroundColor";
NSString *MMTextInsetLeftKey = @"MMTextInsetLeft";
NSString *MMTextInsetRightKey = @"MMTextInsetRight";
NSString *MMTextInsetTopKey = @"MMTextInsetTop";
@@ -305,9 +307,9 @@ - (NSInteger)tag
-int
+AppearanceType
getCurrentAppearance(NSAppearance *appearance){
- int flag = 0; // for macOS 10.13 or earlier always return 0;
+ int flag = AppearanceLight; // for macOS 10.13 or earlier always return 0;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14
if (@available(macOS 10.14, *)) {
NSAppearanceName appearanceName = [appearance bestMatchFromAppearancesWithNames:
@@ -316,11 +318,11 @@ - (NSInteger)tag
, NSAppearanceNameAccessibilityHighContrastAqua
, NSAppearanceNameAccessibilityHighContrastDarkAqua]];
if ([appearanceName isEqualToString:NSAppearanceNameDarkAqua]) {
- flag = 1;
+ flag = AppearanceDark;
} else if ([appearanceName isEqualToString:NSAppearanceNameAccessibilityHighContrastAqua]) {
- flag = 2;
+ flag = AppearanceLightHighContrast;
} else if ([appearanceName isEqualToString:NSAppearanceNameAccessibilityHighContrastDarkAqua]) {
- flag = 3;
+ flag = AppearanceDarkHighContrast;
}
}
#endif
diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m
index 3538acbbae..0d030f04ca 100644
--- a/src/MacVim/gui_macvim.m
+++ b/src/MacVim/gui_macvim.m
@@ -633,6 +633,17 @@
ASLogDebug(@"back=%ld norm=%ld", gui.def_back_pixel, gui.def_norm_pixel);
+ [[MMBackend sharedInstance]
+ setDefaultColorsBackground:gui.def_back_pixel
+ foreground:gui.def_norm_pixel];
+}
+
+/*
+ * Called when any highlight has been changed in general
+ */
+ void
+gui_mch_update_highlight(void)
+{
// If using a highlight group for fullscreen background color we need to
// update the app when a new color scheme has been picked. This function
// technically wouldn't be called if a user manually set the relevant
@@ -641,9 +652,34 @@
if (fuoptions_flags & FUOPT_BGCOLOR_HLGROUP)
gui_mch_fuopt_update();
- [[MMBackend sharedInstance]
- setDefaultColorsBackground:gui.def_back_pixel
- foreground:gui.def_norm_pixel];
+ // Update the GUI with tab colors
+ // We can cache the tabline syn IDs because they will never change.
+ static int tablineSynIds[3] = { 0 };
+ char *tablineSynNames[3] = {"TabLine", "TabLineFill", "TabLineSel"};
+
+ BOOL hasTablineColors = YES;
+ int tablineColors[6] = { 0 };
+ for (int i = 0; i < 3; i++) {
+ if (tablineSynIds[i] <= 0)
+ tablineSynIds[i] = syn_name2id((char_u *)tablineSynNames[i]);
+ if (tablineSynIds[i] > 0) {
+ guicolor_T bg, fg;
+ syn_id2colors(tablineSynIds[i], &fg, &bg);
+ tablineColors[i*2] = (int)bg;
+ tablineColors[i*2+1] = (int)fg;
+ } else {
+ hasTablineColors = NO;
+ }
+ }
+ if (hasTablineColors) {
+ // Cache the old colors just so we don't spam the IPC channel if the
+ // colors didn't actually change.
+ static int oldTablineColors[6] = { 0 };
+ if (memcmp(oldTablineColors, tablineColors, sizeof(oldTablineColors)) != 0) {
+ memcpy(oldTablineColors, tablineColors, sizeof(oldTablineColors));
+ [[MMBackend sharedInstance] setTablineColors:tablineColors];
+ }
+ }
}
/*
@@ -1995,6 +2031,8 @@
{
if (!gui.in_use)
return;
+ if (!p_fullscreen)
+ return;
guicolor_T fg, bg;
if (fuoptions_flags & FUOPT_BGCOLOR_HLGROUP) {
diff --git a/src/highlight.c b/src/highlight.c
index a04f158e09..0bf781ab9b 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -4069,6 +4069,12 @@ highlight_changed(void)
#endif // USER_HIGHLIGHT
+#if defined(FEAT_GUI) && defined(FEAT_GUI_MACVIM)
+ // MacVim needs to know about the other highlight colors other than just
+ // the default fg/bg colors.
+ if (gui.in_use)
+ gui_mch_update_highlight();
+#endif
return OK;
}
diff --git a/src/proto/gui_macvim.pro b/src/proto/gui_macvim.pro
index 869727d044..7d27521d5d 100644
--- a/src/proto/gui_macvim.pro
+++ b/src/proto/gui_macvim.pro
@@ -63,6 +63,7 @@ int gui_mch_haskey(char_u *name);
void gui_mch_iconify(void);
void gui_mch_invert_rectangle(int r, int c, int nr, int nc, int invert);
void gui_mch_new_colors(void);
+void gui_mch_update_highlight(void);
void gui_mch_set_bg_color(guicolor_T color);
int gui_mch_is_blinking(void);
int gui_mch_is_blink_off(void);