objective-cmacosfinderswizzlingsimbl

SIMBL swizzling in finder


I manages to integrate Icon Overlay like dropbox in Mac Os Finder with a SIMBL plugin ! I Use the swizzle method to override some finder function.

Here is my swizzle method :

void PluginSwizzleInstanceMethod(Class cls, SEL oldSel, SEL newSel) 
{
    Method mnew = class_getInstanceMethod(cls, newSel);
    Method mold = class_getInstanceMethod(cls, oldSel);
    method_exchangeImplementations(mnew, mold);
}

So for the moment i override the drawWithFrame method like this :

Class cls = NSClassFromString(@"TIconAndTextCell");
SEL oldSel = @selector(drawWithFrame:inView:);
SEL newSel = @selector(PluginDrawWithFrame:inView:);
PluginSwizzleInstanceMethod(cls, oldSel, newSel);

all my icons are displayed but not on my desktop or on the view that show items as icon ... Why ?

thank you ,


Solution

  • I just managed to do some stuff for the Desktop, so I'll post in case that's still relevant for someone:

    So as you experienced, Finder draws icons differently on the Desktop.
    One class that is responsible for that is TDesktopIcon.
    One can, for example, change icons by overriding the drawIconInContext: method, and setting the thumbnailImage property to whatever NSImage* he likes.

    - (void) FO_drawIconInContext:(struct CGContext *)arg1 {
        NSImage *image;
        // set image... 
        [(TDesktopIcon*)self setThumbnailImage:image];
        [self FO_drawIconInContext:arg1];
    }
    

    Getting the url for each item was not as straight forward as with TIconAndTextCell or IKImageBrowserCell.

    In order to get the URLs, you need to override the prepareToDrawNode: method of TDesktopViewController. You get the URL from arg1 as follows:

    - (void) FO_prepareToDrawNode:(const struct TFENode *)arg1 {
        struct OpaqueNodeRef *opr = arg1->fNodeRef;  
        struct FINode *fiNode = [FINode nodeFromNodeRef:opr];  
        NSURL *url = [fiNode previewItemURL];  
        // save url somewhere (I use NSUserDefaults) 
        [self FO_prepareToDrawNode:arg1];  
    }  
    

    Maybe there's a better way, but that's what I figured out...