Изящное получение и отмена фокуса фонового приложения для диалогового окна

Я работаю над небольшим приложением для Mac, которое обычно работает незаметно в фоновом режиме, однако основная функциональность приложения вступает в игру, когда пользователь переименовывает файл на своем рабочем столе или в другом месте в Finder. Когда это происходит, я хотел бы представить диалоговое окно, подобное тому, которое появляется, когда пользователь изменяет расширение файла через Finder.Поскольку это потребует, чтобы мое приложение получило самый передний фокус (а не Finder), я хотел бы вернуть Finder как самое переднее приложение, когда пользователь нажимает «ОК» в моем диалоговом окне

. Я использую функцию Apple Process ManagerSetFrontProcessWithOptions(), но у меня возникают проблемы в следующем сценарии:

  • Пользователь открывает окно Finder где-то в своей рабочей области
  • Пользователь затем щелкает по рабочему столу, расфокусируя окно.
  • Пользователь переименовывает файл на своем рабочем столе.
  • Мое приложение вызывает фокусировку с помощью SetFrontProcessWithOptions()
  • Пользователь нажимает OKв диалоговом окне, мое приложение фокусирует Finder с помощью SetFrontProcessWithOptions()
  • Когда Finder перефокусируется, он фокусирует окно, которое пользователь открывал ранее, несмотря на то, что оно не было сфокусировано, когда Finder ранее был самым передним.

Это становится очень раздражающим, если окно Finder открыто в другом пространстве перед тем, как вы переименуете файл на рабочем столе: в этом случае нажатие «ОК» в диалоговом окне заставляет Finder автоматически переключать пробелы и возвращаться к окну.

Это происходит только из-за природы функции SetFrontProcessWithOptions(), которая может фокусировать только окноданного приложения. Поскольку рабочий стол явно не считается окном, функция вместо этого находит другое окно для фокусировки, несмотря на то, что пользователь ранее не фокусировал это окно.

Было бы здорово, если бы у кого-нибудь были лучшие идеи о том, как сделать своего рода основанную на диалогах вещь, такую ​​как эта, может быть, даже вообще без необходимости фокусировать и расфокусировать Finder.

РЕДАКТИРОВАТЬ: я нашел довольно уродливый способ исправить это поведение по большей части, но он включает в себя Scripting Bridge и не перефокусирует рабочий стол в случае, если элемент из него был переименован. Вот мой код для этого:

FinderApplication * app = [SBApplication applicationWithBundleIdentifier:@"com.apple.finder"];
if (!app || ![app isRunning]) {
    SetFrontProcessWithOptions(&processSerial, kSetFrontProcessFrontWindowOnly);
    return;
}
SBElementArray * selArray = app.selection.get;
if ([selArray count] == 0) {
    SetFrontProcessWithOptions(&processSerial, kSetFrontProcessFrontWindowOnly);
    return;
} else {
    FinderWindow * window = [[[selArray objectAtIndex:0] container].get containerWindow].get;
    if ([window isKindOfClass:NSClassFromString(@"FinderFinderWindow")]) {
        SetFrontProcessWithOptions(&processSerial, kSetFrontProcessFrontWindowOnly);
    } else {
        // TODO: this is where I'd insert code to select the item
        // on the desktop...
    }
}

9
задан Alex Nichol 8 June 2012 в 19:30
поделиться