我遇到了一些后台应用程序的问题,该应用程序使用LSUIElement=1隐藏其停靠项、菜单栏,并阻止它出现在命令-选项卡应用程序切换器中。
这似乎只是雪豹的问题。
应用程序在菜单栏中放置一个NSStatusItem,并在单击时弹出一个菜单。选择“首选项...”应该会弹出一个带有首选项的NSWindow。
第一件似乎不起作用的事情是,窗口没有在前面排序,而是出现在所有其他应用程序窗口的后面。
我试着通过打电话解决这个问题
[[NSApplication sharedApplication] activateIgnoringOtherApps: YES]但这并不管用。
过了一段时间,我发现菜单阻塞了发送到run循环的消息,所以我在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];
}请注意send-every-possible-message-to-make-it-do-what-it-should-be-doing-approach.
这是可行的,在某种程度上,窗口在所有应用程序的所有其他窗口的顶部被带到最前面,但大多数时候它是不活动的,这意味着它的标题栏是灰色的。单击标题栏也不会使窗口处于活动状态。单击窗口内部将使其处于活动状态!?
这一切在Leopard中似乎都不是问题;只需调用activateIgnoringOtherApps并设置window键似乎就可以很好地工作。
在雪豹中,有一个新的应用程序接口被设计来取代LSUIElement,这应该是为了模仿它的行为:
http://developer.apple.com/mac/library/releasenotes/cocoa/appkit.html
我已经尝试过了,但它只是SL-only,而且我还无法设置LSUIElement。
发布于 2010-11-03 03:49:46
这很奇怪-我正在雪豹下编写一个LSUIElement应用程序,并且我没有您所描述的问题……我确实遇到了新创建的窗口没有出现在前面的问题,但我通过调用activateIgnoringOtherApps解决了这个问题。这就是我所要做的,让它正常工作:
[NSApp activateIgnoringOtherApps: YES];
[preferencesWindow makeKeyAndOrderFront: self];我甚至没有碰任何名字里有“政策”的东西。
发布于 2010-05-28 22:10:34
在绝望地发布了这个问题后,我继续寻找,并最终找到了解决方案。由于这让我困惑了几天,而且谷歌似乎找不到其他答案,我将为“未来的一代”解释解决方案。
雪豹增加了一个新的NSApplication presentationOptions接口:
http://developer.apple.com/mac/library/releasenotes/cocoa/appkit.html
这是为了模拟LSUIElement的工作方式,但提供了更多的开发人员控制。不幸的是,模拟并不完美,因此在10.5和10.6之间存在行为变化。
特别是,如果您的应用程序的info.plist中有LSUIElement =1行,Snow Leopard会将“应用程序的presentationOptions ..初始化为NSApplicationPresentationOptions标志的等价组合”。
只是它不是真的。它将新的NSApplication setActivationPolicy设置为NSApplicationActivationPolicyAccessory:
应用程序没有出现在停靠栏中,也没有菜单栏,但它可以通过编程或单击其中一个窗口来激活。这与应用程序的Info.plist中的LSUIElement键的值为1相对应。
尽管提到了以编程方式激活,但activateIgnoringOtherApps:被完全忽略了。
解决方案是将激活策略设置为"regular":
[[NSApplication sharedApplication] setActivationPolicy: NSApplicationActivationPolicyRegular];当然,只有当你使用10.6 SDK作为基础SDK时,你才能做到这一点,这是目前很少有人想做的事情,所以下面是一个10.5安全的方法:
NSApplication* app = [NSApplication sharedApplication];
if( [app respondsToSelector: @selector(setActivationPolicy:)] ) {
NSMethodSignature* method = [[app class] instanceMethodSignatureForSelector: @selector(setActivationPolicy:)];
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: method];
[invocation setTarget: app];
[invocation setSelector: @selector(setActivationPolicy:)];
NSInteger myNSApplicationActivationPolicyAccessory = 0;
[invocation setArgument: &myNSApplicationActivationPolicyAccessory atIndex: 2];
[invocation invoke];
}我希望有人会发现这是有用的。
https://stackoverflow.com/questions/2928695
复制相似问题