[英]How to hide the Dock icon
我想优先隐藏 Dock 图标并显示NSStatusItem
。 我可以创建 StatusItem,但我不知道如何从 Dock 中删除图标。 :-/
有任何想法吗?
我认为您正在寻找 Info.plist 中的LSUIElement
LSUIElement(字符串)。 如果此键设置为“1”,则启动服务将应用程序作为代理应用程序运行。 代理应用程序不会出现在 Dock 或 Force Quit window 中。 尽管它们通常作为后台应用程序运行,但如果需要,它们可以到前台呈现用户界面。
在此处查看有关打开/关闭它的简短讨论
您可以使用所谓的激活策略:
// 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];
// 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)
这应该隐藏停靠图标。
要做到这一点,同时遵守 Apple 不修改应用程序包的指导方针并保证 Mac App Store 应用程序/(Lion 应用程序?)的签名不会被 info.plist 修改破坏,您可以将 LSUIElement 默认设置为 1,然后当应用程序启动:
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
显示它的停靠图标,或者如果用户选择不想要该图标,则绕过它。
只有一个副作用,应用程序的菜单在失去并重新获得焦点之前不会显示。
我个人不喜欢设置任何 Info.plist 选项,而是根据用户设置使用TransformProcessType(&psn, kProcessTransformToForegroundApplication)
或TransformProcessType(&psn, kProcessTransformToUIElementApplication)
。
在 Xcode 4 中,它显示为“应用程序是代理 (UIElement)”,它是 Boolean。
在您的 Info.plist 控件中单击空白区域并 select 从菜单类型“应用程序是代理(UIElement)”中“添加行”将其设置为 YES。
为了使其可选,我在我的代码中添加了以下行(感谢 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 代码就可以做到。
该文章还建议制作一个专门处理停靠图标的辅助应用程序。 然后主应用程序会根据用户的偏好启动并终止该应用程序。 这种方法让我觉得比使用 Carbon 代码更健壮,但我还没有尝试过。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.