在可可的实际模态窗口前打开帐户首选项面板

时间:2013-06-12 16:05:42

标签: objective-c macos cocoa

我有一个带有偏好设置窗口的Mac应用。首选项窗口以模态方式打开

-(IBAction)displayPreferencesWindow:(id)sender{
    if (!pc) {
        pc = [[PreferencesController alloc] initWithWindowNibName:@"PreferencesController"];
        pc.delegate = self;
    }
    NSWindow *pcWindow = [pc window];

    [NSApp runModalForWindow: pcWindow];

    [NSApp endSheet: pcWindow];

    [pcWindow orderOut: self];
}

在首选项窗口中,我有一个用于打开帐户首选项面板的按钮

- (IBAction)openSystemPrefs:(id)sender {
    [[NSWorkspace sharedWorkspace] openFile:@"/System/Library/PreferencePanes/Accounts.prefPane"];
}

问题是帐户首选项面板无法在实际窗口前打开。我怎样才能做到这一点?

enter image description here

2 个答案:

答案 0 :(得分:0)

这有点奇怪,并且反对标题中的注释,但请尝试使用它:

- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;

来自那里的评论:

  

在某个路径上打开文件。如果你使用没有的变体   withApplication:参数,或者如果为此参数传递nil,则为   使用默认应用程序。 appName参数可以是完整路径   应用程序,或只是应用程序的名称,有或没有   .app扩展名。如果您为andDeactivate:传递YES,或调用变体   如果没有此参数,调用应用程序将在新的之前停用   应用程序启动,以便新的应用程序可能会出现在前台,除非   用户在此期间切换到另一个应用程序。通过是   for andDeactivate:通常建议使用。

所以听起来你的应用应该停用(因为你正在调用没有andDeactivate:参数的变体)但是我会尝试使用该参数显式使用变体,只是为了一定不会。

答案 1 :(得分:0)

根据经验,如果启动应用程序呈现模态UI,则启动的应用程序似乎不会激活,至少在使用NSWorkspace API时不会。我能够使用似乎可以达到预期效果的AppleScript来解决问题:

- (IBAction)doStuff:(id)sender
{
    [[NSWorkspace sharedWorkspace] openFile:@"/System/Library/PreferencePanes/Accounts.prefPane"];

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSString* s = @"tell application \"System Preferences\" to activate";
        NSAppleScript* as = [[[NSAppleScript alloc] initWithSource: s] autorelease];
        NSDictionary* error = nil;
        if ([as compileAndReturnError: &error])
        {
            (void)[as executeAndReturnError: &error];
        }
    });
}

我将它发送到后台队列,因为编译和运行AppleScript需要几百毫秒,如果同步完成它会有点显眼(按钮保持突出显示的时间超出预期)。

如果你感觉真的很自虐,你可能会通过编造等效的AppleEvents并直接发送它来让脚本编译阶段(即更快),但这似乎达到了预期的效果,即使在呈现模态UI时也是如此在启动应用程序中。