【发布时间】:2012-06-08 14:29:04
【问题描述】:
我正在开发一个小型 Mac 应用程序,该应用程序通常会在后台不可见地运行。但是,当用户在桌面或 Finder 中的其他位置重命名文件时,应用程序的主要功能就会发挥作用。发生这种情况时,我想显示一个类似于用户通过 Finder 更改文件扩展名时出现的对话框。因为这需要我的应用程序获得最前面的焦点(而不是 Finder),所以当用户在我的对话框中点击“确定”时,我想将 Finder 作为最前面的应用程序返回。
我目前正在使用Apple的Process Manager函数SetFrontProcessWithOptions(),但是在以下场景中遇到了麻烦:
- 用户在其工作区的某处打开 Finder 窗口
- 然后用户单击他们的桌面,使窗口失去焦点。
- 用户重命名桌面上的文件
- 我的应用程序使用
SetFrontProcessWithOptions()使自己聚焦 - 用户在对话框中点击
OK,我的应用使用SetFrontProcessWithOptions()聚焦Finder - 当 Finder 重新聚焦时,它会聚焦用户之前打开的窗口,尽管事实上当 Finder 之前位于最前面时它没有聚焦。
如果您在重命名桌面上的文件之前在另一个空间中打开了一个 Finder 窗口,这真的很烦人:在这种情况下,在对话框中点击“确定”会导致 Finder 自动切换空间并返回到窗口。
这只是因为SetFrontProcessWithOptions() 函数的性质,它只能聚焦给定应用程序的一个窗口。由于桌面显然不算作 窗口,因此该函数会找到另一个窗口来聚焦,尽管用户之前没有聚焦该窗口。
如果有人对如何执行诸如此类的基于对话框的事情有更好的想法,那将是很棒的,甚至可能根本不需要聚焦和不聚焦 Finder。
编辑:我发现了一种在很大程度上解决此问题的方法,但它涉及到脚本桥,并且它不会重新聚焦桌面,以防从它被重命名了。这是我的代码:
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...
}
}
【问题讨论】:
-
您是否考虑过使用 AppleScript 在 Finder 的上下文中显示警报,而不是完全切换您的应用程序?
-
亚历克斯,你还在吗?
标签: objective-c cocoa nswindow