extension NSMenuItem { /// Disables all icons in all regular menu items. /// /// Call `NSMenuItem.disableIcons` early (from AppDelegate.init is good). public static func disableIcons() { let originalSelector = #selector(getter: image) let nilImageSelector = #selector(returnNilInsteadOfImage) guard let originalMethod = class_getInstanceMethod(NSMenuItem.self, originalSelector), let newMethod = class_getInstanceMethod(NSMenuItem.self, nilImageSelector) else { return } method_exchangeImplementations(originalMethod, newMethod) } @objc private func returnNilInsteadOfImage() -> NSImage? { // In a palette menu, as appears for example in the "zoom" button of a window, // we want the icons to appear because labels are hidden. if let menu, case .palette = menu.presentationStyle { // Because the method implementations are swapped, this will return the original image. return self.returnNilInsteadOfImage() } else { return nil } } }