Skip to content

Commit 53dc316

Browse files
committed
Fix non-native full screen misc background color and transparency issues
Fixed misc bugs: - Previously, setting a colorscheme while in non-native full screen would override the background color specified in 'fuoptions' (default is black). It also wouldn't update the specified color if it's specified to a highlight group (e.g. `set fuopts=background:Normal`). - Transparency and background colors and setting colorscheme also didn't work well togehter. Changing a background color while in fullscreen would reset transparency back to 0. Also, 'fuoptions' can now specify background color in 6-digit hex number now, in addition to the old 8-digit format. Also update docs to elaborate that when using 8-digit, the alpha component is ignored (since we use the 'transparency' setting instead). Add new tests to test 'fuoptions' work.
1 parent 2b136db commit 53dc316

File tree

7 files changed

+161
-22
lines changed

7 files changed

+161
-22
lines changed

runtime/doc/options.txt

+10-6
Original file line numberDiff line numberDiff line change
@@ -3981,15 +3981,19 @@ A jump table for the options with a short description can be found at |Q_op|.
39813981
of columns fitting on the screen in fullscreen mode. If unset,
39823982
'columns' will be unchanged when entering fullscreen mode.
39833983
background:color
3984-
When entering fullscreen, 'color' defines the color of the part
3985-
of the screen that is not occupied by the Vim control. If
3986-
'color' is an 8-digit hexadecimal number preceded by '#',
3987-
it is interpreted as an explicit color value '#aarrggbb', with
3988-
one byte each for the alpha, red, green, and blue values.
3989-
Otherwise, 'color' is interpreted as a highlight group name,
3984+
When entering fullscreen, "color" defines the color of the part
3985+
of the screen that is not occupied by the Vim control,
3986+
including the "notch" area for MacBook laptops.
3987+
If "color" is a 6 or 8-digit hexadecimal number preceded by
3988+
'#', it is interpreted as an explicit color value '#rrggbb' /
3989+
'#aarrggbb', with one byte each for the alpha, red, green, and
3990+
blue values. The alpha value is ignored (use 'transparency'
3991+
instead for a translucent window).
3992+
Otherwise, "color" is interpreted as a highlight group name,
39903993
and the fullscreen background is filled with that highlight
39913994
group's background color, as defined by the current color
39923995
scheme.
3996+
If unset, the default value is black (#FF000000).
39933997

39943998
Examples:
39953999
Don't change size when entering fullscreen: >

src/MacVim/MMBackend.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ - (void)leaveFullScreen
11881188
- (void)setFullScreenBackgroundColor:(int)color
11891189
{
11901190
NSMutableData *data = [NSMutableData data];
1191-
color = MM_COLOR(color);
1191+
color = MM_COLOR_WITH_TRANSP(color,p_transp);
11921192
[data appendBytes:&color length:sizeof(int)];
11931193

11941194
[self queueMessage:SetFullScreenColorMsgID data:data];

src/MacVim/MMVimController.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,7 @@ - (void)handleMessage:(int)msgid data:(NSData *)data
11291129
case SetFullScreenColorMsgID:
11301130
{
11311131
const int *bg = (const int*)[data bytes];
1132-
NSColor *color = [NSColor colorWithRgbInt:*bg];
1132+
NSColor *color = [NSColor colorWithArgbInt:*bg];
11331133

11341134
[windowController setFullScreenBackgroundColor:color];
11351135
}

src/MacVim/MMWindowController.m

+25-10
Original file line numberDiff line numberDiff line change
@@ -699,25 +699,32 @@ - (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore
699699
// window, so we need to set a transparency color here to make the
700700
// transparency show through.
701701
if ([back alphaComponent] == 1) {
702-
// Here, any solid color would do, but setting it with "back" has an
703-
// interesting effect where the title bar gets subtly tinted by it
704-
// as well, so do that. (Note that this won't play well in <=10.12
705-
// since we are using the deprecated
706-
// NSWindowStyleMaskTexturedBackground which makes the titlebars
707-
// transparent in those. Consider not using textured background.)
702+
// The window's background color affects the title bar tint and
703+
// if we are using a transparent title bar this color will show
704+
// up as well.
705+
// (Note that this won't play well in <=10.12 since we are using
706+
// the deprecated NSWindowStyleMaskTexturedBackground which makes
707+
// the titlebars transparent in those. Consider not using textured
708+
// background.)
708709
[decoratedWindow setBackgroundColor:back];
710+
711+
// Note: We leave the full screen window's background color alone
712+
// because it is affected by 'fuoptions' instead. We just change the
713+
// alpha back to 1 in case it was changed previously because transparency
714+
// was set.
709715
if (fullScreenWindow) {
710-
[fullScreenWindow setBackgroundColor:back];
716+
[fullScreenWindow setBackgroundColor:
717+
[fullScreenWindow.backgroundColor colorWithAlphaComponent:1]];
711718
}
712719
} else {
713720
// HACK! We really want a transparent background color to avoid
714721
// double blending the transparency, but setting alpha=0 leads to
715722
// the window border disappearing and also drag-to-resize becomes a
716723
// lot slower. So hack around it by making it virtually transparent.
717-
NSColor *clearColor = [back colorWithAlphaComponent:0.001];
718-
[decoratedWindow setBackgroundColor:clearColor];
724+
[decoratedWindow setBackgroundColor:[back colorWithAlphaComponent:0.001]];
719725
if (fullScreenWindow) {
720-
[fullScreenWindow setBackgroundColor:clearColor];
726+
[fullScreenWindow setBackgroundColor:
727+
[fullScreenWindow.backgroundColor colorWithAlphaComponent:0.001]];
721728
}
722729
}
723730
}
@@ -1046,9 +1053,17 @@ - (void)leaveFullScreen
10461053
}
10471054
}
10481055

1056+
/// Called when the window is in non-native full-screen mode and the user has
1057+
/// updated the background color.
10491058
- (void)setFullScreenBackgroundColor:(NSColor *)back
10501059
{
10511060
if (fullScreenWindow)
1061+
// See setDefaultColorsBackground: for why set a transparent
1062+
// background color, and why 0.001 instead of 0.
1063+
if ([back alphaComponent] != 1) {
1064+
back = [back colorWithAlphaComponent:0.001];
1065+
}
1066+
10521067
[fullScreenWindow setBackgroundColor:back];
10531068
}
10541069

src/MacVim/MacVimTests/MacVimTests.m

+112
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,8 @@ - (void) testWindowResize {
737737
[self waitForVimClose];
738738
}
739739

740+
#pragma mark Full screen tests
741+
740742
- (void)waitForNativeFullscreenEnter {
741743
XCTestExpectation *expectation = [self expectationWithDescription:@"NativeFullscreenEnter"];
742744

@@ -862,4 +864,114 @@ - (void) testFullScreenNative {
862864
[self fullScreenTestWithNative:YES];
863865
}
864866

867+
- (void) testFullScreenNonNativeOptions {
868+
MMAppController *app = MMAppController.sharedInstance;
869+
870+
// Cache test defaults
871+
NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;
872+
NSDictionary<NSString *, id> *defaults = [ud volatileDomainForName:NSArgumentDomain];
873+
NSMutableDictionary<NSString *, id> *newDefaults = [defaults mutableCopy];
874+
875+
// Change native full screen setting
876+
newDefaults[MMNativeFullScreenKey] = @NO;
877+
[ud setVolatileDomain:newDefaults forName:NSArgumentDomain];
878+
879+
[app openNewWindow:NewWindowClean activate:YES];
880+
[self waitForVimOpenAndMessages];
881+
882+
MMWindowController *winController = app.keyVimController.windowController;
883+
MMTextView *textView = [[winController vimView] textView];
884+
885+
// Test maxvert/maxhorz
886+
[self sendStringToVim:@":set lines=10\n" withMods:0];
887+
[self sendStringToVim:@":set columns=30\n" withMods:0];
888+
[self sendStringToVim:@":set fuoptions=\n" withMods:0];
889+
[self waitForVimProcess];
890+
891+
[self sendStringToVim:@":set fu\n" withMods:0];
892+
[self waitForEventHandlingAndVimProcess];
893+
[self waitForEventHandlingAndVimProcess];
894+
XCTAssertEqual(textView.maxRows, 10);
895+
XCTAssertEqual(textView.maxColumns, 30);
896+
[self sendStringToVim:@":set nofu\n" withMods:0];
897+
[self sendStringToVim:@":set fuoptions=maxvert\n" withMods:0];
898+
[self sendStringToVim:@":set fu\n" withMods:0];
899+
[self waitForEventHandlingAndVimProcess];
900+
[self waitForEventHandlingAndVimProcess];
901+
XCTAssertGreaterThan(textView.maxRows, 10);
902+
XCTAssertEqual(textView.maxColumns, 30);
903+
[self sendStringToVim:@":set nofu\n" withMods:0];
904+
[self sendStringToVim:@":set fuoptions=maxhorz\n" withMods:0];
905+
[self sendStringToVim:@":set fu\n" withMods:0];
906+
[self waitForEventHandlingAndVimProcess];
907+
[self waitForEventHandlingAndVimProcess];
908+
XCTAssertEqual(textView.maxRows, 10);
909+
XCTAssertGreaterThan(textView.maxColumns, 30);
910+
[self sendStringToVim:@":set nofu\n" withMods:0];
911+
[self sendStringToVim:@":set fuoptions=maxhorz,maxvert\n" withMods:0];
912+
[self sendStringToVim:@":set fu\n" withMods:0];
913+
[self waitForEventHandlingAndVimProcess];
914+
[self waitForEventHandlingAndVimProcess];
915+
XCTAssertGreaterThan(textView.maxRows, 10);
916+
XCTAssertGreaterThan(textView.maxColumns, 30);
917+
918+
// Test background color
919+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithArgbInt:0xff000000]); // default is black
920+
921+
// Make sure changing colorscheme doesn't override the background color unlike in non-full screen mode
922+
[self sendStringToVim:@":color desert\n" withMods:0];
923+
[self waitForEventHandlingAndVimProcess];
924+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithArgbInt:0xff000000]);
925+
926+
// Changing fuoptions should update the background color immediately
927+
[self sendStringToVim:@":set fuoptions=background:Normal\n" withMods:0];
928+
[self waitForEventHandlingAndVimProcess];
929+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithArgbInt:0xff333333]);
930+
931+
// And switching colorscheme should also update the color as well
932+
[self sendStringToVim:@":color blue\n" withMods:0];
933+
[self waitForEventHandlingAndVimProcess];
934+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithArgbInt:0xff000087]);
935+
936+
// Test parsing manual colors in both 8-digit mode (alpha is ignored) and 6-digit mode
937+
[self sendStringToVim:@":set fuoptions=background:#11234567\n" withMods:0];
938+
[self waitForEventHandlingAndVimProcess];
939+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithArgbInt:0xff234567]);
940+
[self sendStringToVim:@":set fuoptions=background:#abcdef\n" withMods:0];
941+
[self waitForEventHandlingAndVimProcess];
942+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithArgbInt:0xffabcdef]);
943+
944+
// Test setting transparency while in full screen. We always set the alpha of the background color to 0.001 when transparency is set.
945+
[self sendStringToVim:@":set fuoptions=background:#ffff00\n:set transparency=50\n" withMods:0];
946+
[self waitForEventHandlingAndVimProcess];
947+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithRed:1 green:1 blue:0 alpha:0.001]);
948+
949+
[self sendStringToVim:@":set fuoptions=background:#00ff00\n" withMods:0];
950+
[self waitForEventHandlingAndVimProcess];
951+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithRed:0 green:1 blue:0 alpha:0.001]);
952+
953+
[self sendStringToVim:@":set transparency=0\n" withMods:0];
954+
[self waitForEventHandlingAndVimProcess];
955+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithRed:0 green:1 blue:0 alpha:1]);
956+
957+
// Test setting transparency outside of full screen and make sure it still works
958+
[self sendStringToVim:@":set nofu\n" withMods:0];
959+
[self waitForEventHandlingAndVimProcess];
960+
[self waitForEventHandlingAndVimProcess];
961+
[self sendStringToVim:@":set transparency=50 fuoptions=background:#0000ff\n" withMods:0];
962+
[self sendStringToVim:@":set fu\n" withMods:0];
963+
[self waitForEventHandlingAndVimProcess];
964+
[self waitForEventHandlingAndVimProcess];
965+
XCTAssertEqualObjects(winController.window.backgroundColor, [NSColor colorWithRed:0 green:0 blue:1 alpha:0.001]);
966+
967+
// Clean up
968+
[[app keyVimController] sendMessage:VimShouldCloseMsgID data:nil];
969+
[self waitForVimClose];
970+
971+
XCTAssertEqual(0, [app vimControllers].count);
972+
973+
// Restore settings to test defaults
974+
[ud setVolatileDomain:defaults forName:NSArgumentDomain];
975+
}
976+
865977
@end

src/MacVim/gui_macvim.m

+8
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,14 @@
633633

634634
ASLogDebug(@"back=%ld norm=%ld", gui.def_back_pixel, gui.def_norm_pixel);
635635

636+
// If using a highlight group for fullscreen background color we need to
637+
// update the app when a new color scheme has been picked. This function
638+
// technically wouldn't be called if a user manually set the relevant
639+
// highlight group to another color but works in most use cases when they
640+
// just change the color scheme.
641+
if (fuoptions_flags & FUOPT_BGCOLOR_HLGROUP)
642+
gui_mch_fuopt_update();
643+
636644
[[MMBackend sharedInstance]
637645
setDefaultColorsBackground:gui.def_back_pixel
638646
foreground:gui.def_norm_pixel];

src/optionstr.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -4839,16 +4839,16 @@ check_fuoptions(void)
48394839
return FAIL;
48404840
if (p[i] == '#')
48414841
{
4842-
// explicit color (#aarrggbb)
4842+
// explicit color (#aarrggbb or #rrggbb)
48434843
i++;
48444844
for (j = i; j < i + 8 && vim_isxdigit(p[j]); ++j)
48454845
;
4846-
if (j < i + 8)
4847-
return FAIL; // less than 8 digits
4846+
if (j != (i + 8) && j != (i + 6))
4847+
return FAIL; // has to be either 6 or 8 digits
48484848
if (p[j] != NUL && p[j] != ',')
48494849
return FAIL;
48504850
new_fuoptions_bgcolor = 0;
4851-
for (k = 0; k < 8; ++k)
4851+
for (k = 0; k < (j - i); ++k)
48524852
new_fuoptions_bgcolor = new_fuoptions_bgcolor * 16
48534853
+ hex2nr(p[i + k]);
48544854
i = j;

0 commit comments

Comments
 (0)