Skip to content

Commit

Permalink
Dark mode improve docs for v:os_appearance and add tests
Browse files Browse the repository at this point in the history
Make sure docs for v:os_appearance make it clear that it is reflecting
MacVim's appearance, not the OS, which matters when not using
"automatic" in dark mode appearance.

Also add some unit tests to test this part of the functionality to add
test coverage.

Also see #1479
  • Loading branch information
ychin committed Nov 4, 2024
1 parent 52550fc commit 6ecd752
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 2 deletions.
7 changes: 5 additions & 2 deletions runtime/doc/eval.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2439,9 +2439,12 @@ v:operator The last operator given in Normal mode. This is a single
Read-only.

*v:os_appearance* *os-appearance-variable*
v:os_appearance The current OS appearance mode. Useful if you want to change
v:os_appearance The current OS appearance mode. Useful if you want to change
options |background| or |colorscheme| according to the
appearance of the GUI frontend. See also |OSAppearanceChanged|.
appearance of the GUI frontend. See also
|OSAppearanceChanged|. If the "Dark mode selection" setting
is not set to "Automatic", then this value will reflect that
setting instead.
value description ~
0 Light Mode (always 0 on unsupported platforms)
1 Dark Mode
Expand Down
77 changes: 77 additions & 0 deletions src/MacVim/MacVimTests/MacVimTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,83 @@ - (void) testGuifontSystemMonospace {
[self waitForVimClose];
}

/// Test that dark mode settings work and the corresponding Vim bindings are functional.
///
/// Note that `v:os_appearance` and OSAppearanceChanged respond to the view's appearance
/// rather than the OS setting. When using manual light/dark or "use background" settings,
/// they do not reflect the current OS dark mode setting.
- (void) testDarkMode {
NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;

MMAppController *app = MMAppController.sharedInstance;

[app openNewWindow:NewWindowClean activate:YES];
[self waitForVimOpenAndMessages];

MMVimView *vimView = [[[app keyVimController] windowController] vimView];

// We just use the system appearance to determine the initial state. Otherwise
// we have to change the system appearance to light mode first which we don't
// have permission to do.
const BOOL systemUsingDarkMode = [[ud stringForKey:@"AppleInterfaceStyle"] isEqualToString:@"Dark"];
const NSAppearance *systemAppearance = systemUsingDarkMode ?
[NSAppearance appearanceNamed: NSAppearanceNameDarkAqua] : [NSAppearance appearanceNamed: NSAppearanceNameAqua];

// Default setting uses system appearance
XCTAssertEqualObjects(vimView.effectiveAppearance, systemAppearance);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], systemUsingDarkMode ? @"1" : @"0");

// Cache original settings / set up setting overrides
NSDictionary<NSString *, id> *defaults = [ud volatileDomainForName:NSArgumentDomain];
NSMutableDictionary<NSString *, id> *newDefaults = [defaults mutableCopy];

// Manual Light / Dark mode setting
newDefaults[MMAppearanceModeSelectionKey] = [NSNumber numberWithInt:MMAppearanceModeSelectionLight];
[ud setVolatileDomain:newDefaults forName:NSArgumentDomain];
[app refreshAllAppearances];
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameAqua]);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"0");

// Set up a listener for OSAppearanceChanged event to make sure it's called
// when the view appearance changes.
[self sendStringToVim:@":let g:os_appearance_changed_called=0\n" withMods:0];
[self sendStringToVim:@":autocmd OSAppearanceChanged * let g:os_appearance_changed_called+=1\n" withMods:0];
[self waitForEventHandlingAndVimProcess];

newDefaults[MMAppearanceModeSelectionKey] = [NSNumber numberWithInt:MMAppearanceModeSelectionDark];
[ud setVolatileDomain:newDefaults forName:NSArgumentDomain];
[app refreshAllAppearances];
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"1");
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"g:os_appearance_changed_called"], @"1");

// "Use background" setting
[self sendStringToVim:@":set background=dark\n" withMods:0];
[self waitForEventHandlingAndVimProcess];

newDefaults[MMAppearanceModeSelectionKey] = [NSNumber numberWithInt:MMAppearanceModeSelectionBackgroundOption];
[NSUserDefaults.standardUserDefaults setVolatileDomain:newDefaults forName:NSArgumentDomain];
[app refreshAllAppearances];
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"1");
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"g:os_appearance_changed_called"], @"1"); // we stayed in dark mode, so OSAppearnceChanged didn't trigger

[self sendStringToVim:@":set background=light\n" withMods:0];
[self waitForEventHandlingAndVimProcess];
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameAqua]);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"0");
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"g:os_appearance_changed_called"], @"2");

// Restore original settings and make sure it's reset
[NSUserDefaults.standardUserDefaults setVolatileDomain:defaults forName:NSArgumentDomain];
[app refreshAllAppearances];
XCTAssertEqualObjects(vimView.effectiveAppearance, systemAppearance);

// Clean up
[[app keyVimController] sendMessage:VimShouldCloseMsgID data:nil];
[self waitForVimClose];
}

/// Test that document icon is shown in title bar when enabled.
- (void) testTitlebarDocumentIcon {
MMAppController *app = MMAppController.sharedInstance;
Expand Down

0 comments on commit 6ecd752

Please sign in to comment.