Directly read macOS theme preference instead of using defaults by BlackHoleFox · Pull Request #2442 · sharkdp/bat (original) (raw)

Follows on #2197 by improving the implementation of macos_dark_mode_active.

For reference there are a lot of ways to read preferences on macOS. Here's the 4 I know of:

  1. defaults CLI
  2. NSUserDefaults via Objective-C
  3. CFPreferences via CoreFoundation (C/C++)
  4. Directly reading and parsing the file from disk

Out of all of these, defaults is the slowest because it involves spawning and executing a whole separate executable to read one value. defaults is implemented via 2, which is implemented via 3 at the end. In order to speed this up, I just used option 4 as bat's needs are fairly simple. Using CFPreferences would have also worked but the use of #![deny(unsafe_code)] indicated that would have been in conflict with the crate's goals since calling C APIs requires unsafe by nature.

If bat wanted to do this 100% as-intended by Apple, and possibly take advantage of any OS-level caching, CFPreferences.framework would be the way. If you're good with the unsafe required, happy to swap out the implementation. Though I don't ever really expect the file reading method to break.

So this new implementation reads the hardcoded settings path and directly parses the plist data with the plist crate (already in the dependency tree from another crate, which was nice). As a result, in a release build, reading the theme is now 12x faster and pretty much imperceptible. The lowest time I saw with the old implementation was 4-5ms, while a release build call to macos_dark_mode_active now takes <500us on an M1 Max MacBook.