私は通常、バックグラウンドで目に見えない形で実行される小さなMacアプリケーションに取り組んでいます。ただし、アプリの主な機能は、ユーザーがデスクトップまたはFinderの他の場所でファイルの名前を変更したときに機能します。これが発生した場合、ユーザーがFinderを使用してファイル拡張子を変更したときに表示されるのと同様のダイアログを表示したいと思います。これには、アプリケーションが(Finderではなく)最前面のフォーカスを取得する必要があるため、ユーザーがダイアログで[OK]を押したときに、最前面のアプリケーションとしてFinderを返したいと思います。
現在、AppleのProcess Manager機能を使用SetFrontProcessWithOptions()
していますが、次のシナリオで問題が発生します。
- ユーザーがワークスペースのどこかでFinderウィンドウを開く
- 次に、ユーザーはデスクトップをクリックして、ウィンドウのフォーカスを解除します。
- ユーザーがデスクトップ上のファイルの名前を変更します
- 私のアプリケーションは、それ自体を使用して集中させます
SetFrontProcessWithOptions()
- ユーザー
OK
がダイアログを押すと、私のアプリはFinderを使用してフォーカスしますSetFrontProcessWithOptions()
- Finderが再フォーカスすると、以前はFinderが最前面にあったときにフォーカスされていなかったにもかかわらず、ユーザーが以前に開いたウィンドウにフォーカスが移ります。
デスクトップ上のファイルの名前を変更する前に別のスペースでFinderウィンドウを開いている場合、これは非常に煩わしいものになります。このシナリオでは、ダイアログで[OK]を押すと、Finderが自動的にスペースを切り替えてウィンドウに戻ります。
これは、特定のアプリケーションのウィンドウSetFrontProcessWithOptions()
にのみフォーカスできる関数の性質によるものです。デスクトップは明らかにウィンドウとしてカウントされないため、ユーザーが以前にそのウィンドウにフォーカスを設定していなかったにもかかわらず、関数は代わりにフォーカスする別のウィンドウを検索します。
ファインダーに焦点を合わせたり、焦点を外したりする必要がまったくなくても、このようなダイアログベースのことを行う方法について誰かがもっと良いアイデアを持っていれば素晴らしいでしょう。
編集:私はほとんどの部分でこの動作を修正するためのやや醜い方法を見つけましたが、それはスクリプトブリッジを含み、それからのアイテムが名前を変更された場合にデスクトップに再び焦点を合わせません。これを行うための私のコードは次のとおりです。
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...
}
}