Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
Does anyone know how to set an NSMenuItem to show the diamond icon used to denote a minimised window? I've worked out how to use -setState: to set the "tick" (NSOnState) and the "dash" (NSMixedState), but that diamond seems curiously elusive...
 

wittegijt

macrumors member
Feb 18, 2007
31
0
Eindhoven
Does anyone know how to set an NSMenuItem to show the diamond icon used to denote a minimised window? I've worked out how to use -setState: to set the "tick" (NSOnState) and the "dash" (NSMixedState), but that diamond seems curiously elusive...

Isn't the diamond set automatically by Cocoa?

Wittegijt.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
You'll have to use Carbon it seems. It looks like you might be able to do something with SetMenuItemKeyGlyph and kMenuDiamondGlyph, but I'm not sure. There is a method for disabling that column where the diamond would go (SetMenuExcludesMarkColumn) but I didn't see any related methods to that for setting the actual diamond (SetMenuItemKeyGlyph seems to set the glyph on the right side).
 

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
Thanks kainjow, I'll have a sniff around.

Wittegijt, Cocoa does automatically set the diamond mark for items it adds to the Window menu itself. However, I'm placing a menu item for my window in the menu manually, as I want it to be there whether or not the window is open.

I'm pretty amazed that I can't seem to find anything at all about this by searching the web. Nobody even seems to have asked the question before. This page on CocoaDev mentions tracking and setting the window's minimization state, but maddeningly it doesn't say how!
 

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
This seems to be possible using the Menu Manager function SetItemMark() with the constant diamondMark. But that takes a MenuRef.

How does one get a MenuRef from an NSMenu instance? With the undocumented function _NSGetCarbonMenu(). Of course.

I might try it if I am desperate. :)
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
I would just not worry about it. In Safari, when you select Window > Downloads, the downloads window that appears has its own menu in Window, just like a normal window. I would suggest going that route.
 

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
Yeah, that's probably sensible. I just think that, since my app will only have one window, having it listed twice in the Windows menu will look a bit silly. Not that anyone ever looks in the Windows menu...

... and it's a good thing they don't, because the inconsistency between apps is shocking. The one-window apps that Apple ships with the OS all seem to display only one item for the main window, but some of them put it above "Bring All to Front" and others put it below, none of them bother with the diamond mark when the window is minimized, and many of them don't even display the tick when the window is active. Except for iTunes, which displays both tick and diamond, but unlike the other apps hides/unhides the window when you select it from the menu. What a mess!
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
If you run the onStateImage method for each menu item in the Window menu, the menu items that correspond to a window will return a 12x12 diamond image: View attachment 74269 - however, "Changing state images is currently unsupported in Mac OS X."

But for fun I tried to write a hack category method but it didn't seem to work :)

Code:
interface NSMenuItem (Hacks)
- (void)setOnStateImageHack:(NSImage *)image;
@end
@implementation NSMenuItem (Hacks)
- (void)setOnStateImageHack:(NSImage *)image
{
	[_onStateImage release];
	_onStateImage = [image retain]; 
}
@end
 

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
Haha. You would have thought someone would get around to deprecating that at some point in the last six years.

Here's a quick way to do it:

Code:
extern MenuRef _NSGetCarbonMenu(NSMenu *);
SetItemMark(_NSGetCarbonMenu([NSApp windowsMenu]), [[NSApp windowsMenu] indexOfItemWithTag:someTag] + 1, diamondMark);

I will post back when I have worked out how to do this without using an unsupported, undocumented private function.
 

Nutter

macrumors 6502
Original poster
Mar 31, 2005
432
0
London, England
Hmmm, not as easy as I thought. I don't think it can be done without knowing the menu ID of the Windows menu, and I don't know how to get that.

On second thoughts, this might be a little safer:

Code:
extern MenuRef _NSGetCarbonMenu(NSMenu *);
MenuRef windowsMenuRef = _NSGetCarbonMenu([NSApp windowsMenu]);
if (windowsMenuRef != NULL)
	SetItemMark(windowsMenuRef, [[NSApp windowsMenu] indexOfItemWithTag:someTag] + 1, diamondMark);
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.