views:

580

answers:

2

I have a statusItem application written in PyObjC. The statusItem has a menuItem which is supposed to launch a new window when it is clicked:

# Create statusItem
statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
statusItem.setHighlightMode_(TRUE)
statusItem.setEnabled_(TRUE)
statusItem.retain()

# Create menuItem
menu = NSMenu.alloc().init()
menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Preferences', 'launchPreferences:', '')
menu.addItem_(menuitem)
statusItem.setMenu_(menu)

The launchPreferences: method is:

def launchPreferences_(self, notification):
    preferences = Preferences.alloc().initWithWindowNibName_('Preferences')
    preferences.showWindow_(self)

Preferences is an NSWindowController class:

class Preferences(NSWindowController):

When I run the application in XCode (Build & Go), this works fine. However, when I run the built .app file externally from XCode, the statusItem and menuItem appear as expected but when I click on the Preferences menuItem the window does not appear. I have verified that the launchPreferences code is running by checking console output.

Further, if I then double click the .app file again, the window appears but if I change the active window away by clicking, for example, on a Finder window, the preferences window disappears. This seems to me to be something to do with the active window.

Update 1 I have tried these two answers but neither work. If I add in to the launchPreferences method:

preferences.makeKeyAndOrderFront_()

or

preferences.setLevel_(NSNormalWindowLevel)

then I just get an error:

'Preferences' object has no attribute

+3  A: 

You need to send the application an activateIgnoringOtherApps: message and then send the window makeKeyAndOrderFront:.

In Objective-C this would be:

[NSApp activateIgnoringOtherApps:YES];
[[self window] makeKeyAndOrderFront:self];
Nathan Kinsinger
+1  A: 

I have no idea of PyObjC, never used that, but if this was Objective-C code, I'd say you should call makeKeyAndOrderFront: on the window object if you want it to become the very first front window. A newly created window needs to be neither key, nor front, unless you make it either or like in this case, both.

The other issue that worries me is that you say the window goes away (gets invisible) when it's not active anymore. This sounds like your window is no real window. Have you accidentally set it to be a "Utility Window" in Interface Builder? Could you try to manually set the window level, using setLevel: to NSNormalWindowLevel before the window is displayed on screen for the first time whether it still goes away when becoming inactive?

Mecki
makeKeyAndOrderFront has no effect and setLevel results in a "'Preferences' object has no attribute 'setLevel_'" error.
DavidM
Actually, makeKeyAndOrderFront also the the same error:'Preferences' object has no attribute 'makeKeyAndOrderFront_'
DavidM