How to Write OS X Finder plugin

notnoop picture notnoop · Aug 18, 2009 · Viewed 28.2k times · Source

I'm looking for a guide or sample code for writing Mac OS X Finder plugins? It would like to know how to do some simple actions:

  1. adding image overlayers to icons
  2. adding context menu items
  3. listen to file changes

I found the following two resources:

I am tempted to review the SCPlugin code, but was hoping to find an easier sample to digest.

Answer

Les Nie picture Les Nie · Jan 9, 2012

The Finder Icon Overlay example project represents a small and very basic but actually working example of the answer below.

https://github.com/lesnie/Finder-Icon-Overlay

I know this is so old, but some may be still interested in topic (?)

Here is what I have it done under Leopard (10.6). At first proper Finder's headers are needed. Use class-dump tool to get it. Then write your code as a SIMBL plugin (refer to documentation how to do it), swizzling some methods. For instance to draw something over icon in ListView, drawIconWithFrame: method of TIconAndTextCell method must be overriden.

Here's the code for method swizzling:

+ (void) Plugin_load
{
    Method old, new;
    Class self_class = [self class];
    Class finder_class = [objc_getClass("TIconAndTextCell") class];

    class_addMethod(finder_class, @selector(FT_drawIconWithFrame:),
                    class_getMethodImplementation(self_class, @selector(FT_drawIconWithFrame:)),"v@:{CGRect={CGPoint=dd}{CGSize=dd}}");

    old = class_getInstanceMethod(finder_class, @selector(drawIconWithFrame:));
    new = class_getInstanceMethod(finder_class, @selector(FT_drawIconWithFrame:));
    method_exchangeImplementations(old, new);

}

I am overriding "drawIconWithFrame:" method with my method "FT_drawIconWithFrame:". Below is sample implementation for this method.

- (void) FT_drawIconWithFrame:(struct CGRect)arg1
{
    [self FT_drawIconWithFrame:arg1];
    if ([self respondsToSelector:@selector(node)]) {
        if ([[[[NSClassFromString(@"FINode") nodeWithFENode:[(TNodeIconAndNameCell *)self node]] fullPath] lastPathComponent] hasPrefix:@"A"])
            [myPrettyIconOverlayImage drawInRect:NSMakeRect(arg1.origin.x, arg1.origin.y, arg1.size.height, arg1.size.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
    }
}

Essentially it draws "myPrettyIconOverlayImage" over every icon for file with filename starts with letter "A". This logic is up to you.

Pay attention to this line: [self FT_drawIconWithFrame:arg1]; this is how to call 'super' in order to get normal icon and name etc. I know, looks weird, like loop, but actually it isn't. Then wrap in into SIMBL plugin, install SIMBL and ...run.

Due to changes in Lion some work have to be done from scratch (make new "Finder.h" file with all declarations needed in it, find proper classess and methods to override), but this technique still works.

Happy hacking!