iconmaster
iconmaster

Reputation: 175

LSUIElement behaves inconsistently with activateIgnoringOtherApps

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];

}

Upvotes: 8

Views: 2227

Answers (2)

Shaun Inman
Shaun Inman

Reputation: 1968

Finally came up with a workaround for this.

Instead of popping the menu in your click handler, activate the app then schedule an NSTimer with no delay that pops the menu:

-(void)pop:(NSTimer *)timer {
    [statusItem popUpStatusItemMenu:theMenu];
}

-(void)statusItemClicked:sender {
    [NSApp activateIgnoringOtherApps:YES];
    [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(pop:) userInfo:nil repeats:NO];
}

pop: is called on the next frame so the delay is imperceptible but long enough for activateIgnoringOtherApps: to do whatever was preventing it from working as expected when popping the menu in the same frame.

Upvotes: 2

Alex
Alex

Reputation: 26859

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.

Upvotes: -1

Related Questions