Krzysztof Rosiński
Krzysztof Rosiński

Reputation: 1478

Unable to set submenu for NSMenuItem (FinderSync extension)

I'm trying to create a cascade submenu for a Finder Sync extension in Swift/Cocoa. I have the following code:

override func menuForMenuKind(menuKind: FIMenuKind) -> NSMenu! {
    let m = NSMenu(title: "")
    let mi1 = NSMenuItem(title: "item1", action: nil, keyEquivalent: "")
    let mi11 = NSMenuItem(title: "item11", action: nil, keyEquivalent: "")

    let m2 = NSMenu(title: "")
    let mi2 = NSMenuItem(title: "item2", action: nil, keyEquivalent: "")
    m2.addItem(mi2)

    m.addItem(mi1)
    m.addItem(mi11)
    m.setSubmenu(m2, forItem: mi1)
    return m
}

So what I'm trying to achieve is:

item1->
       item2 
item11

So what I actually get is a flat item1 and item11 menu list.

Any hints?


I filed a bug with Apple (#18810635), got a response that it's a duplicate of (#18531883) which is still open.

Posted the copy of the filing at OpenRadar http://openradar.appspot.com/radar?id=5772557445758976 , tweeted to a developer advocate.

If anyone knows the fate of #18531883 - this is core raison d'être for Finder Sync Extensions?

Upvotes: 25

Views: 3262

Answers (3)

pkamb
pkamb

Reputation: 35032

Finder Sync Extensions do not support submenus in versions before macOS 10.11.

This is stated in the code docs when you examine the FIFinderSyncProtocol header:

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.

optional func menu(for menu: FIMenuKind) -> NSMenu?

Upvotes: 0

Ian Thompson
Ian Thompson

Reputation: 51

func constructMenu() {
        let main = NSMenu()
        let submenu = NSMenu()
        let mainDropdown = NSMenuItem(title: "Some option group", action: nil, keyEquivalent: "")
        main.addItem(mainDropdown)
        main.setSubmenu(submenu, for: mainDropdown)


        submenu.addItem(NSMenuItem(title: "Option 1", action: nil, keyEquivalent: ""))
        submenu.addItem(NSMenuItem(title: "Option 2", action: nil, keyEquivalent: ""))




       // myList.setSubmenu(mylist2, for: myList)


        statusItem.menu = main
    }

Upvotes: 0

Krzysztof Rosiński
Krzysztof Rosiński

Reputation: 1478

I've upgraded the project to Swift 2.0, and finally made a working submenu. Posting the solution:

override func menuForMenuKind(menuKind: FIMenuKind) -> NSMenu! {
    let main = NSMenu()
    let submenu = NSMenu()
    let mainDropdown = NSMenuItem(title: "Some option group", action: nil, keyEquivalent: "")
    main.addItem(mainDropdown)
    m.setSubmenu(submenu, forItem: mainDropdown)


    submenu.addItem(NSMenuItem(title: "Option 1", action: nil, keyEquivalent: ""))
    submenu.addItem(NSMenuItem(title: "Option 2", action: nil, keyEquivalent: ""))
    return main
}

This will only work on Mac OS 10.11+, 10.10.5 still has the bug being unable to generate a submenu. So a good appraoch is generating a flat menu for < 10.11, and a cascade starting from el capitan.

Upvotes: 4

Related Questions