如何隐藏 Dock 图标
-
05-07-2019 - |
题
我想选择隐藏 Dock 图标并显示 NSStatusItem
。我可以创建 StatusItem,但我不知道如何从 Dock 中删除该图标。:-/
有任何想法吗?
解决方案
我认为您正在寻找Info.plist中的 LSUIElement
LSUIElement(String)。如果此键设置为“ 1”,则启动服务将应用程序作为代理应用程序运行。代理应用程序不会出现在Dock或强制退出窗口中。虽然它们通常作为后台应用程序运行,但如果需要,它们可以到前台显示用户界面。
请参阅此处的简短讨论开/关
其他提示
要遵守不修改应用程序包的Apple准则,并保证Mac App Store应用程序/(Lion应用程序?)不会被info.plist修改破坏其签名,您可以默认将LSUIElement设置为1然后当应用程序启动时:
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
显示它的停靠图标,或者如果用户选择不想要图标,则绕过它。
只有一个副作用,应用程序的菜单在丢失并重新获得焦点之前不会显示。
我个人更喜欢不设置任何Info.plist选项并使用 TransformProcessType(& psn,kProcessTransformToForegroundApplication)
或 TransformProcessType(& psn,kProcessTransformToUIElementApplication)
基于什么用户设置。
您可以使用所谓的激活策略:
Objective-C
// The application is an ordinary app that appears in the Dock and may
// have a user interface.
[NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
// The application does not appear in the Dock and does not have a menu
// bar, but it may be activated programmatically or by clicking on one
// of its windows.
[NSApp setActivationPolicy: NSApplicationActivationPolicyAccessory];
// The application does not appear in the Dock and may not create
// windows or be activated.
[NSApp setActivationPolicy: NSApplicationActivationPolicyProhibited];
雨燕4
// The application is an ordinary app that appears in the Dock and may
// have a user interface.
NSApp.setActivationPolicy(.regular)
// The application does not appear in the Dock and does not have a menu
// bar, but it may be activated programmatically or by clicking on one
// of its windows.
NSApp.setActivationPolicy(.accessory)
// The application does not appear in the Dock and may not create
// windows or be activated.
NSApp.setActivationPolicy(.prohibited)
这应该隐藏停靠图标。
也可以看看
在Xcode 4中,它显示为“Application is agent(UIElement)”。它是布尔值。
在您的Info.plist控件中 - 单击一个空白区域并选择“添加行”从菜单中 键入“Application is agent(UIElement)”。 设为是。
为了使其可选,我在代码中添加了以下行(感谢Valexa!)
// hide/display dock icon
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"hideDockIcon"]) {
//hide icon on Dock
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
}
Swift更新:(上面介绍了两种方式,结果相同)
public class func toggleDockIcon_Way1(showIcon state: Bool) -> Bool {
// Get transform state.
var transformState: ProcessApplicationTransformState
if state {
transformState = ProcessApplicationTransformState(kProcessTransformToForegroundApplication)
}
else {
transformState = ProcessApplicationTransformState(kProcessTransformToUIElementApplication)
}
// Show / hide dock icon.
var psn = ProcessSerialNumber(highLongOfPSN: 0, lowLongOfPSN: UInt32(kCurrentProcess))
let transformStatus: OSStatus = TransformProcessType(&psn, transformState)
return transformStatus == 0
}
public class func toggleDockIcon_Way2(showIcon state: Bool) -> Bool {
var result: Bool
if state {
result = NSApp.setActivationPolicy(NSApplicationActivationPolicy.Regular)
}
else {
result = NSApp.setActivationPolicy(NSApplicationActivationPolicy.Accessory)
}
return result
}
如果您想使其成为用户首选项,则无法使用UIElement。 UIElement位于应用程序包中,您不应编辑应用程序包中的任何文件,因为这将使包签名无效。
我发现的最佳解决方案基于这篇优秀的文章。我的解决方案基于Dan的评论。简而言之,Cocoa没有办法做到这一点,但只需要一点碳代码即可。
该文章还建议制作一个专门处理停靠图标的帮助应用程序。然后主应用程序启动并根据用户首选项杀死此应用程序。这种方法让我觉得比使用Carbon代码更强大,但我还没有尝试过。