Search code examples
macoscocoansmenu

Can I remove the top and bottom padding of a custom NSMenu?


I want to make a custom pop-up menu that has light text on a dark background. I am aware of the setView: method of NSMenuItem, which I could use to make each item draw with light text on a dark background. However, NSMenu draws 4 pixel high strips at the top and bottom of the menu in a light color, which pretty much ruins the look. Since NSMenu doesn't have any public drawing methods I could override, I can't see how to get rid of those strips.

I see that the NSMenu header has private instance variables named noTopPadding and noBottomPadding. So tantalizing!


Solution

  • I found a solution using an undeclared method (not ideal, obviously). First declare it as follows:

    @interface NSMenu (secret)
    - (void) _setHasPadding: (BOOL) pad onEdge: (int) whatEdge;
    @end
    

    Then, sometime before showing the menu, do:

    if ([menu respondsToSelector: @selector(_setHasPadding:onEdge:)])
    {
        [menu _setHasPadding: NO onEdge: 1];
        [menu _setHasPadding: NO onEdge: 3];
    }
    

    My testing shows that this doesn't work on Snow Leopard, but does work on Lion, Mountain Lion, and Mavericks.