Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show icons in the dock contextual menus in OS X?

My question is quite simple :

To use a custom menu for the apps icon on the dock, - (NSMenu*) applicationDockMenu: (id) sender; of the NSApplicationDelegate has to return the menu that the dock will display.

Using setImage on a NSMenuItem, you can normaly add icons to the menu. They show up on the normal menu, but not on in contextual menu of the app's dock icon.

Then how did Apple manage QuickTime, XCode, Preview to show icons in the list of recent opened files accessible in their dock contextual menu ?

Thx.

like image 968
Matthieu Riegler Avatar asked Jul 08 '12 03:07

Matthieu Riegler


2 Answers

The recent files list is actually part of the standard Dock icon menu. To use it in your app, you should build an NSDocument-based application. By using NSDocument, you will get the recent files menu/behaviour for free.

If your application cannot be based on NSDocument, you can instruct Cocoa to maintain a recent documents list based on URLs:

NSDocumentController *docController = [NSDocumentController sharedDocumentController];
[docController noteNewRecentDocumentURL:locationOfMyRecentFile1];
[docController noteNewRecentDocumentURL:locationOfMyRecentFile2];
[docController noteNewRecentDocumentURL:locationOfMyRecentFile3];

Note that currently, -noteNewRecentDocumentURL: only supports file:// URLs (which you can create from a path with +[NSURL fileURLWithPath:].) In the future, its behaviour will presumably change to allow URLs with other schemes.

like image 114
Jonathan Grynspan Avatar answered Oct 17 '22 22:10

Jonathan Grynspan


Here's my understanding, which is partly conjectural and related to implementation details:

The Dock runs in a separate process, and you can't pass an arbitrary NSImage trivially across the process boundary from your application to the Dock. There are only two kinds of images that can be passed properly: standard system icons, and icons in your resource bundle. But I don't think NSImage does the necessary incantations for either of these to work.

So you're going to have to use Carbon. Specifically, you need to use SetMenuItemIconHandle with either kMenuSystemIconSelectorType (covers Carbon IconRefs, obtained with GetIconRef) or kMenuIconResourceType (CFStrings that refer to an .icns file in your application bundle's Resources folder).

The relevant headers are <HIToolbox/MacApplication.h> (for GetApplicationDockTileMenu), <HIToolbox/Menus.h> (for SetMenuItemIconHandle) and <HIServices/Icons.h>, (for GetIconRef, if you're using system icons).

Untested, but it should look something like this:

#include <Carbon/Carbon.h>

SetMenuItemIconHandle(
    GetApplicationDockTileMenu(),
    [dockMenu indexOfItem:dockMenuItem],
    kMenuIconResourceType,
    (Handle) CFSTR("icon.icns")
);

It may not be this simple; some of this may be 32-bit only.

like image 39
John Calsbeek Avatar answered Oct 17 '22 21:10

John Calsbeek