Update! This bug appears to be fixed in macOS Sonoma 14.5!
In the macOS AppKit framework, there’s an NSWorkspace API method for setting the current desktop image, scaling method, and fill color. The method is called setDesktopImageURL, and it accepts a file URL, a screen reference, and an options dictionary, including fillColor.

Here’s some sample code:
SetDesktopImageURL.swift
import AppKit
import Foundation
let workspace = NSWorkspace.shared
let screens = NSScreen.screens
// transparent Apache logo, part of the base macOS installation
let path = "/Library/WebServer/share/httpd/manual/images/feather.png"
let image = NSURL.fileURL(withPath: path)
// A nice blue green. This will show through any transparent areas of the desktop image
let color = NSColor(calibratedRed: 64/255, green: 116/255, blue: 112/255, alpha: 1.0)
// NSImageScaling options https://developer.apple.com/documentation/appkit/nsimagescaling
let center = NSImageScaling.scaleNone.rawValue
let options: [NSWorkspace.DesktopImageOptionKey: Any] = [
.allowClipping: false,
.imageScaling: center,
.fillColor: color,
]
for screen in screens {
try workspace.setDesktopImageURL(image, for: screen, options: options)
}We can read the values we’ve just set using a related API method, desktopImageOptions. This method returns a dictionary of the current desktop image options for the given screen.
More sample code:
DesktopImageOptions.swift
import AppKit
import Foundation
let screen = NSScreen.main!
let options = NSWorkspace.shared.desktopImageOptions(for: screen)!
print("imageScaling:", options[.imageScaling] as Any)
print("allowClipping:", options[.allowClipping] as Any)
print("fillColor:", options[.fillColor] as Any)This code works as expected in macOS Monterey (version 12.x) and macOS Ventura (version 13.x):
Monterey
macOS version: 12.4.0
imageScaling: Optional(3)
allowClipping: Optional(0)
fillColor: Optional(NSCalibratedRGBColorSpace ...) <-- good Ventura
macOS version: 13.6.0
imageScaling: Optional(3)
allowClipping: Optional(0)
fillColor: Optional(NSCalibratedRGBColorSpace ...) <-- good But in Sonoma (version 14.x), the fillColor key is missing from the returned dictionary:
Sonoma
macOS version: 14.4.1
imageScaling: Optional(3)
allowClipping: Optional(0)
fillColor: nil <-- bad Similarly, when calling setDesktopImageURL, Sonoma seems to ignore the fillColor option, and always sets the fill color to some default blue (even if I have previously set it to some other color manually.)
Keyboard Maestro
I also tested this in the popular macro utility Keyboard Maestro, which has a Set Desktop Image action that allows you to set the desktop image, scaling method, and fill color, likely using the same setDesktopImageURL API method. Keyboard Maestro is able to set the fill color in Monterey, but not in Sonoma.

So…
…at this point I’m pretty sure this is a regression in macOS Sonoma.
Next steps
If you have any experience with this API and know of a workaround, I’d love to hear it!
If you have Xcode installed, you can try out a minimal sample project on Github. Clone the repo and type
swift run. It will output the current desktop image settings in your console. Or you can copy the code above and save it to a file, and run it withswift filename.swift.I need to file a bug report with Apple, but I haven’t done that before and from what I’ve heard I’m not particularly hopeful that it will get me anywhere. But I’ll try anyway.
A cool thing I found along the way…
I discovered this amazing macOS virtualization tool, Tart.

It allows you to run different versions of macOS (and Linux) in virtual containers on your Mac. I used it to test the above code on Ventura, as I didn’t have a machine with that version running. The setup is dead-easy (if you already have homebrew installed). It does take a while to download an OS image, but once that’s done the container starts up incredibly quickly, and feels just as responsive as my actual Mac. Definitely worth a look if you do any macOS development.