Add custom menu items to the Finder context menu - cocoa

How do I add custom menu items to the context menu for files in Finder?
Unfortunately, most of the information out on the Internet and on Stack Overflow doesn't work in 10.6 or are too limited. Automator, for example, doesn't allow you to create items dynamically or create submenus.
I know it's still possible to do this sort of thing because Dropbox and FolderGlance both do similar things. Does anyone know how they implemented this?
Thanks.

For what it's worth, Dropbox now uses mach_star for code injection. Obviously this is a fragile solution. If you look through their version history, many of their updates are to fix finder integration.

In macOS 10.10+, Finder Sync Extensions can be used to add items to the Finder context menu. This is how modern versions of Dropbox and similar apps customize the right-click menu.
For those just seeking to use the functionality, not develop their own app extension, I've released a Mac app that allows for arbitrary customization of a Finder Sync Extension:
Service Station - Mac App Store

I downloaded FolderGlance and it appears to use an osax (Scripting Addition) bundle to inject code into the Finder process. This is definitely fragile and unsupported.
As far as I am aware the only legit way to add items to the Finder contextual menu is to create a Service, but that doesn't solve your problem.

Up to to the OS X 10.9.x only injecting code to Finder process via mach_inject was a solution (and even Dropbox did that).
However since 10.10 there are Finder plugins, which can customize context menus, add buttons to Toolbar and put overlays over file icons.

They used CFPlugIn to add their menu items.
More on it here:
http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFPlugInRef/Reference/reference.html

Related

Collecting keyboard shortcuts for menu items of another application

I'm writing an application that allows access to other applications' menu items via the accessibility framework. I have no problem obtaining the list of menus, their menu items, etc..
As far as I can see, however, the accessibility framework does not give access to the keyboard shortcuts for each item.
More concretely, if my app presents the Finder's File -> New Finder Window menu item, I would like to annotate it on screen with Command-N, so the user can learn the shortcuts by heart.
At the moment I see no way of getting that information. If not via the AXUIElement accessibility framework, how else can one get that info?
Any help would be much appreciated.
I have managed to find AXMenuItemCmdChar and associated AXUIElement attributes that actually have the information I'm after. Unfortunately, the Swift framework that I use to bridge the C-level Carbon accessibility APIs defines a convenient enum for all the attributes.. only it's not quite all the attributes :-(

How to add Finder/Services menu items to own macOS contextual menu

When a file is right-clicked in the macOS Finder, a contextual menu like this shows up. It contains items at the bottom from macOS Services. I'm talking about services from third party such as (in this case) iTerm and Find Any File. How would I go about adding such items to a contextual menu in my own macOS app? Is there a documented API to do this?
I know this can be done, because it's implemented in at least one other application, see for example the following contextual menu in Find Any File:
macOS provides App Extensions for products to integrate with the OS. The programming guide lists the different extension points that can be utilised, along with a description of their purpose.
Based on the example you've provided, it may be the Finder Sync extension that you're looking for, as the documentation states for Finder Sync:
Badge local OS X folders to let users know the status of items that are remotely synced. You can also implement contextual menus to let users directly manage their synced content.

Cocoa osx: Add a menu item on dock elements for all running applications

I'm working to an application for OSX and I would to add a new menu item on the menu shown when you click on a dock icon.
The menu isn't for my application but it must appear for all running apps.
I've found only this doc http://cocoadevcentral.com/articles/000036.php but it adds to its own app.
My app will run on OSX 10.6 or superior
You can't do that with the public API. You need to inject code into the Dock. In 10.6, the standard way to inject the code is to use the OSAX loading trick, described in this blog post for that. Then you need to do Objective-C runtime hackery to replace the method, using method_exchangeImplementations.
Anyway it's a tricky process. But if you have the will, you can. SIMBL might (or might not) help you.

How do I add items to the Finder context menu in Mac OS X?

I'm in the process of porting a Windows application to OS X (we wrote it in Java so most of the code is portable), but what I'm currently unsure of is how to add context menu items in the Finder window when the user right clicks on an item (i.e. I wish to add some items to the the menu that has "Open" "Open with" , "Get Info", etc... when the user right clicks).
Most of the articles I've found deal specifically with Windows (I've searched for "context menus" and "shell extension", but I believe I may be searching the wrong terms), so I'm curious as to how to go about adding this in Mac or what literature I should be reading.
You may want to take a look at using Services. The Finder appends applicable Services to the end of its contextual menu and, depending on your needs, just fit the bill.
In each Library folder may be a "Contextual Menu Items" folder. Special plugin bundles placed in that folder will be loaded and may place items in contextual menus. Look in Menus.h for the entry points of these plugin bundles.
CMPluginExamineContext
CMPluginHandleSelection
CMPluginPostMenuCleanup
From what I have read, Contextual Menu Items are not supported for 64 bit applications. As of 10.6 most Apple applications, including the Finder, run in 64 bit when available.
There are third party applications that restore contextual menu items on 10.6 if you must have them.

How to access / embed Finder functionality?

Is it possible to embed Finder functionality in a cocoa app, now that Finder is itself cocoa (assuming the app were to function only in snow leopard)?
What I mean is to have a file browser pane as part of the app, actually browsing the file system itself (to edit in another pane), but without writing all the functionality of the Finder. Thanks!
The Finder itself is just an application. It is not a components library nor a framework. While you cannot "embed" Finder functionality in your application, you can influence Finder functionality and invoke Finder functionality.
First off, you can attach Folder Actions to folders. These will trigger when a user does something to the contents of a folder - for instance, they drop a file into it. You set this up in the Finder. You should to learn a little AppleScript, if interacting with the Finder is something you want to do.
Second, since the Finder supports AppleEvents, you can affect the Finder using AppleScript. Take a look at My First AppleScript and My First AppleScript Part II to see how to do this. Here is much more in-depth information, in AppleScript Overview: Scripting with AppleScript. Here is some More Finder Scripting.
Third, there is also support for developing ways for the Finder to do complex things for the user at the click of a button, using Automator (Mac OS X 10.5). You can also create a Service in Automator, beginning in Mac OS X 10.6 ("Snow Leopard"). Take a look at Automator and Finder Actions in Mac OS X 10.6 for an introduction to this latter technique.
Even though Finder windows themselves are not an embeddable component, if you really want to provide the ability to pen, Print, Delete, Duplicate, etc. Files/Folders, and navigate from Folder to Folder, you can develop a simple Folder browser in your application.
It should not be a huge amount of work to do this so long as you do not set your sites on mimicking the finder or duplicating all of its functionality, just the essential basics I have mentioned.
You would need to know how to program the Macintosh, however - not just use AppleScript. The normal way to do this would be to learn the Objective-C programming language and the Cocoa framework. You would need to get familiar with writing applications using a Model-View-Controller architecture.
You would create a subclass of NSObject named something like MyFile, and a subclass of a collection class named something like MyFolder. When the application creates the browsing Windows, and each time the application activates (becomes the frontmost application), you8 would refresh the contents of the browsing menu.
You could put a menu in your menu bar with commands in it: Open, Print, Delete, Duplicate. When the user does one of those commands, your application performs the appropriate actions itself or sends the request to the Finder. After the action has been completely carried out, then you refresh the browsing window for currently displayed Folder, or newly displayed Folder if the user navigated to a different Folder.
If you are familiar with design patterns, object-oriented programming, and frameworks in general - reading up on Cocoa Design Patterns will speed your learning curve immensely.
These are various techniques you can use to harness some of the power of the Finder. As you look these over, I suggest getting very clear in your mind just what benefit this brings to the user of your application. Writing down what the overall objective of this feature is, and what commands you wish to support, will make it easier to choose the path you take in developing it.
The user can always click on a Finder folder window at the click of a button, since Finder is always running. So avoid simply duplicating that functionality for its own sake. Focus on the benefit you are providing the user. Make sure that you do handle the situations where the user updates the Folder you are showing the contents of from another application and then switches back to your application.
No, they have not made Finder simply a host for a framework, like Preview. You still have to write this yourself.

Resources