FinderSync context menu calls action in wrong class

190 views Asked by At

I've got a really weird issue here: I'm writing a FinderSync extension, more specific, I'm adding elements to the context menu. Now if I'm packing everything into one class, it runs fine:

1) I've got the main extension class, called FinderSync

2) In this class, I implement

- (NSMenu *)menuForMenuKind:(FIMenuKind)whichMenu

3) In this method, I'm writing (among other things):

NSMenuItem *myItem = [[NSMenuItem alloc]
            initWithTitle:@"myTitle" 
            action:@selector(myAction:)
            keyEquivalent:@""];

4) In the FinderSync class, there exists the method

- (IBAction)myAction:(id)sender;

5) This method is called as expected when the user clicks on the menu item.

Now: I'm trying to outsource the context menu functionality to an other class, called ContextMenuHandler. Situation now:

1) I've got the main extension class, called FinderSync, and another class called ContextMenuHandler. FinderSync creates an instance of ContextMenuHandler and keeps a reference (_contextMenuHandler) to it.

2) Both classes implement

- (NSMenu *)menuForMenuKind:(FIMenuKind)whichMenu

3) The FinderSync implementation of menuForMenuKind does nothing but call

return [_contextMenuHandler menuForMenuKind:whichMenu];

4) The ContextMenuHandler creates the NSMenuItem. (Exactly same code). I've even tried to add:

[myItem setTarget:self];
[myItem setAction:@selector(myAction:)];

Both classes implement myAction.

5) Expected: myAction of the ContextMenuHandler will be called after clicking on the menu item Observed: myAction of FinderSync is called...

I'm also restarting finder after updates and the breakpoint in the ContextMenuHandler is hit correctly, so it doesn't seem to be an "running old FinderSync version" issue.

Does anybody have an explanation (or fix) for this weird behaviour?

1

There are 1 answers

0
pkamb On

The FIFinderSyncProtocol docs include some useful context:

menu(for menu: FIMenuKind)

The extension's principal object provides a method for each menu item's assigned action.

Which states that the "extension's principal object" provides the action method, as you observed.

Specific menu item properties are used: title, action, image, and enabled.

Starting in 10.11: tag, state, and indentationLevel also work, and submenus are allowed.

Notably absent from this list of supported NSMenuItem properties is target. A specified target for the action cannot be set, so Apple simply calls the action on the FinderSync subclass.

I just ran into a similar issue with property representedObject. Not persisted by the time we get the menu item as the sender.