Snow Leopard&LSUIElement - >应用程序无法正常激活,窗口不是"活动",尽管是"关键"

Fra*_* R. 12 cocoa appkit nswindow

我遇到了一个问题,后台应用程序使用LSUIElement = 1隐藏其停靠项,菜单栏并阻止它出现在Command-Tab应用程序切换器中.

它似乎只是雪豹的问题.

应用程序在菜单栏中放置一个NSStatusItem,并在单击时弹出一个菜单.选择"首选项..."应该会显示带有首选项的NSWindow.

第一件似乎不起作用的是Window没有在前面订购,而是出现在所有其他应用程序窗口后面.

我试着通过打电话来解决这个问题

[[NSApplication sharedApplication] activateIgnoringOtherApps: YES]
Run Code Online (Sandbox Code Playgroud)

但那没用.

过了一会儿,我发现菜单阻止了发送到运行循环的消息,所以我在MainController上编写了另一个方法,并发送了延迟消息:

[self performSelector:@selector(setFront :) withObject:[preferencesController window] afterDelay:1.0];

-(void)setFront: (id) theWindow {

 [[NSApplication sharedApplication]activateIgnoringOtherApps:YES];
 [theWindow orderFrontRegardless];
 [theWindow makeKeyWindow]; 
        [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
}
Run Code Online (Sandbox Code Playgroud)

请注意send-every-possible-message-to-make-it-do-it-it-it-doing-doing方法.

这种方式有点好,窗口在所有应用程序的所有其他窗口的顶部被带到前面,但大部分时间它都不活动,这意味着它的标题栏是灰色的.单击标题栏也不会使窗口处于活动状态.单击窗口的内部将激活它!?

这一切似乎都不是豹子的问题; 只是调用activateIgnoringOtherApps并使窗口键似乎工作正常.

在Snow Leopard中有一个新的API,用于替换应该模拟其行为的LSUIElement:

http://developer.apple.com/mac/library/releasenotes/cocoa/appkit.html

我玩过这个,但它只是SL而且我无法设置LSUIElement.

Kub*_*der 8

这很奇怪 - 我正在Snow Leopard下写一个LSUIElement应用程序,我没有你所描述的问题......我确实遇到了新创建的窗口没有出现在前面的问题,但是我通过调用activateIgnoringOtherApps修复它.这就是我必须做的就是让它按原样运作:

[NSApp activateIgnoringOtherApps: YES];
[preferencesWindow makeKeyAndOrderFront: self];
Run Code Online (Sandbox Code Playgroud)

我甚至没有触及名字中有"政策"的任何东西.


Fra*_* R. 4

在绝望中发布问题后,我继续寻找并最终找到了解决方案。由于这困扰了我几天,而且谷歌似乎找不到其他答案,我将向“后代”解释解决方案。

\n\n

Snow Leopard 添加了新的 NSApplicationpresentationOptions API:

\n\n

http://developer.apple.com/mac/library/releasenotes/cocoa/appkit.html

\n\n

这应该模拟 LSUIElement 的工作方式,但提供更多的开发人员控制。不幸的是,模拟并不完美,因此 10.5 和 10.6 之间的行为发生了变化。

\n\n

特别是,如果您的应用程序的 info.plist 中有 LSUIElement = 1 行,Snow Leopard 将初始化“application\xe2\x80\x99spresentationOptions .. 为 NSApplicationPresentationOptions 标志的等效组合”。

\n\n

只是事实并非如此。它将新的 NSApplication setActivationPolicy 设置为 NSApplicationActivationPolicyAccessory:

\n\n

“该应用程序不会出现在 Dock 中,也没有菜单栏,但可以通过编程方式或通过单击其窗口之一来激活它。这对应于应用程序\xe2\x80\x99s Info 中 LSUIElement 键的值.plist 为 1。”

\n\n

尽管提到了以编程方式激活,但 activateIgnoringOtherApps: 完全被忽略了。

\n\n

解决方案是将激活策略设置为“常规”:

\n\n
[[NSApplication sharedApplication] setActivationPolicy: NSApplicationActivationPolicyRegular];\n
Run Code Online (Sandbox Code Playgroud)\n\n

当然,只有使用 10.6 SDK 作为 Base SDK 才能执行此操作,目前很少有人愿意这样做,因此下面是执行此操作的 10.5 安全方法:

\n\n
NSApplication* app = [NSApplication sharedApplication];\n\nif( [app respondsToSelector: @selector(setActivationPolicy:)] ) {\n\n    NSMethodSignature* method = [[app class] instanceMethodSignatureForSelector: @selector(setActivationPolicy:)];\n    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: method];\n    [invocation setTarget: app];\n    [invocation setSelector: @selector(setActivationPolicy:)];\n    NSInteger myNSApplicationActivationPolicyAccessory = 0;\n    [invocation setArgument: &myNSApplicationActivationPolicyAccessory atIndex: 2];\n    [invocation invoke];\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我希望有人会发现这很有用。

\n