I came up with a workaround that seems to achieve the desired outcome. In addition to the buttons not drawing their backgrounds, there's a problematic line that appears after the 2nd button, presumably to set it apart from the cancel button. As a quick fix I just hide it, along with undoing the "draws only while mouse inside" setting that the frameworks have set:
class HackAlert: NSAlert {
@objc override func layout() {
super.layout()
for button in self.buttons {
button.showsBorderOnlyWhileMouseInside = false
}
if let containerView = self.buttons.first?.superview {
let boxes = containerView.subviews.compactMap { $0 as? NSBox }
boxes.forEach { $0.isHidden = true }
}
}
}
Putting aside the question of whether it's right or wrong to work around this glitch, I do think this looks better, and it seems like a pretty safe way to achieve the desired outcome. It's important to make the tweaks in a subclass override of layout because that is where NSAlert seems to do all of its customizing of the UI before presentation.