Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dark mode improve docs for v:os_appearance and add tests #1511

Merged
merged 1 commit into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading