popUpMenuPositionItem: atLocation: inView: зависает при переключении на другое приложение - PullRequest
2 голосов
/ 02 апреля 2011

Я работаю над приложением без док-станции (LSUIElement true).В приложении появляется меню, когда пользователь нажимает на соответствующий NSStatusItem или когда используется сочетание клавиш.

Моя проблема заключается в том, что все методы, вызывающие всплывающее меню, программно зависают при каждом переключении пользователя на другое.приложение (используя ⌘-TAB), не закрывая меню в первую очередь.Я пробовал popUpMenuPositioningItem:atLocation:inView:, popUpContextMenu:withEvent:forView: и соответствующий метод на NSStatusItem (popUpStatusItemMenu:).

Если пользователь закрывает меню с помощью клавиши ESC, все работает нормально, но если пользователь переключаетсяв другое приложение вышеупомянутые методы никогда не возвращаются (кажется, они работают синхронно и возвращаются, когда меню закрывается).Приложение не аварийно завершает работу, и есть несколько приемов, чтобы восстановить контроль (вызов разоблачения или нажатие на любой NSStatusItem, который открывает меню).

Проблема исчезает, если в приложении есть значок закрепления(т. е. установка LSUIElement в значение false).

Этот код появляется в меню при использовании сочетания клавиш:

[mainMenu popUpMenuPositioningItem:[mainMenu itemAtIndex:0]
                        atLocation:[NSEvent mouseLocation]
                            inView:nil];

И этот код отображается в меню, когдаNSStatusItem нажимается:

- (void)mouseDown:(NSEvent *)event
{
    [statusItem popUpStatusItemMenu:[statusItem menu]];
}

Метод mouseDown: находится в пользовательском NSView, прикрепленном к NSStatusItem.

Есть идеи, как это исправить?

Спасибо за вашу помощь.

Обновление

Проблема также связана с активацией приложения (я использую [NSApp activateIgnoringOtherApps:YES]; перед отображением меню, или в некоторых случаях этоневозможно перемещаться по меню с помощью клавиатуры).

1 Ответ

4 голосов
/ 06 апреля 2011

Похоже, проблема в том, что активация приложения и popUpMenu происходят в одном и том же цикле событий.Я нашел обходной путь, более подробно описанный в этом сообщении .

Это резюме, сначала необходимо активировать приложение (с помощью [NSApp activateIgnoringOtherApps:YES];), а затем открыть всплывающее меню,чтобы убедиться, что это происходит в новом цикле событий: вы можете добиться этого, используя NSTimer для вызова меню.

- (void) someMethod {
    // Some code
    [NSApp activateIgnoringOtherApps:YES];
    [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(showMenu) userInfo:nil repeats:NO];
    //Some other code
}

- (void) showMenu {
    // This will show the menu at the current mouse position
    [aMenu popUpMenuPositioningItem:[mainMenu itemAtIndex:0] atLocation:[NSEvent mouseLocation] inView:nil];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...