Jared
Jared

Reputation: 4810

NSApplication menubar does not respond as expected in nib-less Cocoa application

I have the following single file of code, in which I'm trying to create a Cocoa application with basic functionality in as little code as possible without using nibs or Xcode. I have been getting most of my information from the following blog post, in which the equivalent Objective-C code has been posted: (http://www.cocoawithlove.com/2010/09/minimalist-cocoa-programming.html). The only major change that I have made is an AppDelegate class to manage the window, which is typically what is done in Xcode projects.

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {
    var window: NSWindow

    override init() {
        self.window = NSWindow()
        self.window.setFrame(NSRect(x: 0, y: 0, width: 1280, height: 720), display: true)
        self.window.collectionBehavior = .FullScreenPrimary
        self.window.styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask
        self.window.title = "Main Window"
    }

    func applicationDidFinishLaunching(notification: NSNotification) {
        window.makeKeyAndOrderFront(self)
    }

    func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool {
        return true
    }
}

autoreleasepool {
    NSApplication.sharedApplication()
    NSApp.setActivationPolicy(.Regular)

    let delegate = AppDelegate()
    NSApp.delegate = delegate

    let mainMenu = NSMenu()
    NSApp.mainMenu = mainMenu

    let applicationMenuItem = NSMenuItem()
    mainMenu.addItem(applicationMenuItem)

    let applicationMenu = NSMenu()

    let quitMenuItem = NSMenuItem()
    quitMenuItem.action = #selector(NSApp.terminate(_:))
    quitMenuItem.keyEquivalent = "q"
    quitMenuItem.title = "Quit Cocoa Window Test"
    applicationMenu.addItem(quitMenuItem)

    applicationMenuItem.submenu = applicationMenu

    NSApp.activateIgnoringOtherApps(true)
    NSApp.run()
}

I successfully compile from Terminal with the following command:

swiftc -o bin/CocoaWindowTest -g -framework Cocoa ./src/main.swift

My issue arises with the menu. Although the ⌘Q keyboard shortcut works as expected, the application menu that I've created won't open, and I haven't been able to figure out why.

Upvotes: 0

Views: 561

Answers (2)

Jared
Jared

Reputation: 4810

Solved the problem by calling NSApp.activateIgnoringOtherApps() after NSApp.run() has already been called. To summarize, the main segment of my code now reads something like this:

autoreleasepool {
    NSApplication.sharedApplication()
    NSApp.setActivationPolicy(.Regular)

    let delegate = AppDelegate()
    NSApp.delegate = delegate

    // Menu setup here...

    NSApp.run()

    NSApp.activateIgnoringOtherApps(true)
}

Upvotes: 2

Ken Thomases
Ken Thomases

Reputation: 90681

You should use mainMenu.setSubmenu(applicationMenu, forItem:applicationMenuItem) to set the submenu. Items with submenus have a special action, submenuAction(_:), assigned, which is responsible for actually showing the submenu. The above method properly assigns that action (and is preferred to setting it yourself).

For what it's worth, I wouldn't set NSApp.mainMenu until the menu is complete.

Upvotes: 1

Related Questions