Dark menu bar and Dock on Big Sur

August 21 2021 by Jeff Johnson

On macOS High Sierra there was a system preference "Use dark menu bar and Dock":

System Preferences, General pane

This preference unfortunately disappeared when macOS Mojave introduced the system-wide dark appearance. However, there's still a hidden preference that allows you to get back the old appearance:

defaults write -globalDomain NSRequiresAquaSystemAppearance -boolean true

Enter the above command in Terminal, set your system preference to dark appearance, then logout and login again. The result is that the menu bar and Dock have the dark appearance, whereas all of your apps have the light appearance. I like it because the light menu bar in particular looks too bright for me, but I find it much easier to read text in apps with light mode. I've been using this trick since Mojave, and it still works after I updated to Big Sur.

There's one problem on Big Sur (and Catalina, I think) that wasn't a problem on Mojave: the display for changing the volume and brightness is messed up. Here's how it normally looks in light mode:

volume with level bars

Here's how it looks with dark mode and NSRequiresAquaSystemAppearance:

volume with level bars

And here's how it looks with dark mode, NSRequiresAquaSystemAppearance, and "Reduce transparency" enabled in Accessibility system preferences:

volume with no level bars

The volume level is gone!

I dislike the transparency that's now pervasive in macOS, so I would prefer to keep "Reduce transparency" enabled.

System Preferences, Accessibility pane

The good news is that there's a solution to the problem. The app that's responsible for displaying volume and brightness changes on macOS is named OSDUIHelper, and com.apple.OSDUIHelper is its bundle identifier. Thus, the first thing you might try is this:

defaults write com.apple.OSDUIHelper NSRequiresAquaSystemAppearance -boolean false

This is close to the solution, but it doesn't quite work. Why not? Two reasons. First, OSDUIHelper is sandboxed, as you can verify with the codesign command-line tool:

codesign --display --entitlements - /System/Library/CoreServices/OSDUIHelper.app

Sandboxed apps store their data in a container (within ~/Library/Containers/) and generally can't access files outside their container.

Second, the defaults command-line tool doesn't always work right with sandboxed apps. The OSDUIHelper app doesn't have any specific preferences, and thus it doesn't come with a preferences file. When you run the defaults write command above, it create a new ~/Library/Preferences/com.apple.OSDUIHelper.plist file, but that file isn't inside OSDUIHelper's sandbox, so the app doesn't have access to the file!

The solution here is to move the new preferences file from ~/Library/Preferences/ to ~/Library/Containers/com.apple.OSDUIHelper/Data/Library/Preferences/ so that the sandboxed app can access it. Note that in Finder, the folder ~/Library/Containers/com.apple.OSDUIHelper appears as simply "OSDUIHelper". Do not even get me started on how the container names are messed up on Big Sur. Do. not. even. get. me. started…

Anyway, after you move the plist file, logout, and login again, you finally have the sweet solution:

volume with dark appearance

Dark menu bar and Dock on Big Sur, with working volume and brightness controls. What a relief!

The funny thing is that defaults can successfully read and even write sandboxed preferences, as long as the preferences file already exists inside the app's container. It's just not smart enough to create a preferences file inside the app's container.

One more thing. I like to be able to switch between system appearances. During the day I prefer the light appearance with dark menu bar and Dock, but the system dark appearance is easier on my eyes late at night and early in the morning. So I created a few aliases in my ~/.bash_profile file that allow me to easily switch. (Yes I still use bash. Don't bash me!)

alias 'aquamode=defaults write -g NSRequiresAquaSystemAppearance -bool yes; osascript -e "tell application \"System Events\" to set dark mode of appearance preferences to true"'
alias 'darkmode=defaults delete -g NSRequiresAquaSystemAppearance; osascript -e "tell application \"System Events\" to set dark mode of appearance preferences to true"'
alias 'lightmode=defaults delete -g NSRequiresAquaSystemAppearance; osascript -e "tell application \"System Events\" to set dark mode of appearance preferences to false"'

You may need to give Terminal app special permissions in the Privacy pane of System Preferences to successfully perform all of the commands in this blog post. For instance, I always give Full Disk Access to Terminal. Who wouldn't?

Jeff Johnson (My apps, PayPal.Me)