views:

147

answers:

1

Specifically, it behaves inconsistently regarding text field focus.

I have an LSUIElement popping up a status menu. Within that menu there is a view containing a text field. The text field needs to be selectable -- not necessarily selected by default, but whichever.

When the status item is clicked, it triggers

[NSApp activateIgnoringOtherApps:YES];

And it works, about half the time.* The other half the status menu seems to consider itself "in the background" and won't let me put focus on the text field even by clicking on it. (I know the status item click-trigger is firing b/c there's an NSLog on it.)

Is this a bug in the way Apple handles these status items, or am I mishandling activateIgnoringOtherApps?

*In fact, it seems to fail only the first time after another app is activated. After that it works fine.

The complete snippet:

-(void)statusItemClicked:(id)sender {
    //show the popup menu associated with the status item.
    [statusItem popUpStatusItemMenu:statusMenu];

    //activate *after* showing the popup menu to obtain focus for the text field.
    [NSApp activateIgnoringOtherApps:YES];

}
A: 

I know from experience that you have to call activateIgnoringOtherApps: after you've popped up the menu that contains your text field. So you would need to do it in this order:

- (void)statusItemClicked:sender {
    [statusItem popUpStatusItemMenu:theMenu];
    [NSApp activateIgnoringOtherApps:YES]; // FYI, NSApp is shorthand for [NSApplication sharedApplication]
}

Based on what you've said, it sounds like your application is activating too late, so that it's not getting activated the first time you click on the item, but it is already activated on subsequent clicks.

Alex
It's definitely activating too late, but the code was already structured as you suggest. It almost seems like the activate method isn't getting called until that status menu has been dismissed (NSLog testing seems to bear this out).I don't understand why that'd be happening.
iconmaster
So does `activateIgnoringOtherApps:` get called immediately after `popUpStatusItemMenu:`, or does that method not return until the menu is dismissed? You might try setting a breakpoint and running through the debugger to see what happens.
Alex
Yup, using breakpoints it definitely gets called only after the menu is dismissed. Adding my code to the first post, though it looks almost exactly like your suggestion.
iconmaster
Does it work if you reverse those two lines? If you activate the application before you pop up the menu? Obviously it doesn't do you any good to activate the app only after the menu is dismissed, and I can't think of another hook that would be called when the menu appears.
Alex
Reversing them still leaves the text filed unselectable, as well as throwing some errors after the menu is dismissed. statusItemClicked is being set as statusMenu's selector from within awakeFromNib -- could that be part of the delay?
iconmaster