How do I switch my whole app from Dark to Light Mode and vice versa with NSAppearanceMBS? The code of the NSAppearanceMBS:
dim t as string = NSAppearanceMBS.NSAppearanceNameVibrantDark
dim a as NSAppearanceMBS = NSAppearanceMBS.appearanceNamed(t)
if a = nil then
MsgBox "No Appearance with that name?"
else
NSAppearanceMBS.setCurrentAppearance a
NSAppearanceMBS.setAppearance(self, a) // apply to window
end if
produces very odd results in complex windows. And only one window is switched:
The main window in the background of the screenshot doesn’t switch modes at all. The window in the front of the screenshot uses custom colors so that the grey background is okay. But why do the listbox and the checkbox look okay while all the labels are not okay?
Declare Function NSClassFromString Lib "AppKit" (inClassName As CFStringRef) As Integer
Declare Sub setAppearance Lib "AppKit" Selector "setAppearance:" (NSApplicationInstance As Integer, NSAppearanceInstance As Integer)
Declare Function sharedApplication Lib "AppKit" Selector "sharedApplication" (classRef As Integer) As Integer
Declare Function NSAppearanceNamed Lib "AppKit" Selector "appearanceNamed:" (NSAppearanceClass As Integer, name As CFStringRef) As Integer
setAppearance(sharedApplication(NSClassFromString("NSApplication")), _
NSAppearanceNamed(NSClassFromString("NSAppearance"), _
"NSAppearanceNameVibrantLight"))
Both of these will produce weird results, as technically we’re not supposed to directly use these values, instead these are meant to read during the paint or updateLayer event (same for the High Contrast versions).
The ones we should use are
NSAppearanceNameAqua
and
NSAppearanceNameDarkAqua
However DarkAqua doesn’t exist on 10.13, so then you have to use “NSAppearanceNameVibrantDark” if you want any resemblance of a system dark theme.
If you need the light or dark mode of macOS in general, call NSAppearanceMBS.currentAppearance in your App.Opening Event and store the result in a property of the App Class, for later use.
Do the above assignment, before having your app logic switch it’s light or dark mode appearance.
Works for me. This allows me to provide three appearance options in an app, that can be changed at any time:
System Assigned
Light
Dark
Note: I am also using the MBS plugins to manage appearance changes.
But also in those events you can use effectiveAppearance on the control to determine appearance. Appearances can alter based upon their parent controls.
You can revert to the system default by setting the appearance of a control or the application object to nil and then it should adopt the current system appearance. Once you’ve set it to nil, you can then retrieve it and match it’s name against the constants.