首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >雪豹和LSUIElement ->应用程序未正确激活,窗口不是“活动”的,尽管是“键”

雪豹和LSUIElement ->应用程序未正确激活,窗口不是“活动”的,尽管是“键”
EN

Stack Overflow用户
提问于 2010-05-28 19:52:42
回答 2查看 3.7K关注 0票数 12

我遇到了一些后台应用程序的问题,该应用程序使用LSUIElement=1隐藏其停靠项、菜单栏,并阻止它出现在命令-选项卡应用程序切换器中。

这似乎只是雪豹的问题。

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

第一件似乎不起作用的事情是,窗口没有在前面排序,而是出现在所有其他应用程序窗口的后面。

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

代码语言:javascript
复制
[[NSApplication sharedApplication] activateIgnoringOtherApps: YES]

但这并不管用。

过了一段时间,我发现菜单阻塞了发送到run循环的消息,所以我在MainController上编写了另一个方法,并延迟发送消息:

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

代码语言:javascript
复制
-(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。

EN

回答 2

Stack Overflow用户

发布于 2010-11-03 03:49:46

这很奇怪-我正在雪豹下编写一个LSUIElement应用程序,并且我没有您所描述的问题……我确实遇到了新创建的窗口没有出现在前面的问题,但我通过调用activateIgnoringOtherApps解决了这个问题。这就是我所要做的,让它正常工作:

代码语言:javascript
复制
[NSApp activateIgnoringOtherApps: YES];
[preferencesWindow makeKeyAndOrderFront: self];

我甚至没有碰任何名字里有“政策”的东西。

票数 8
EN

Stack Overflow用户

发布于 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":

代码语言:javascript
复制
[[NSApplication sharedApplication] setActivationPolicy: NSApplicationActivationPolicyRegular];

当然,只有当你使用10.6 SDK作为基础SDK时,你才能做到这一点,这是目前很少有人想做的事情,所以下面是一个10.5安全的方法:

代码语言:javascript
复制
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];

}

我希望有人会发现这是有用的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2928695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档