Я хочу сделать предпочтение скрывать значок док-станции и показывать NSStatusItem
.
Я могу создать StatusItem, но я не знаю, как удалить значок из Dock.: -/
Любые идеи?
Я хочу сделать предпочтение скрывать значок док-станции и показывать NSStatusItem
.
Я могу создать StatusItem, но я не знаю, как удалить значок из Dock.: -/
Любые идеи?
Я думаю, что вы ищете LSUIElement
в Info.plist
LSUIElement (String). Если для этого ключа установлено значение "1", Launch Services запускает приложение в качестве приложения-агента. Приложения-агенты не отображаются в док-станции или в окне принудительного закрытия. Хотя они обычно работают в качестве фоновых приложений, они могут выходить на передний план, чтобы при желании представить пользовательский интерфейс.
См. краткое обсуждение здесь о включении/выключении
Чтобы сделать это, соблюдая правила Apple, не изменяя пакеты приложений и гарантируя, что приложения Mac App Store/(приложения Lion?) не будут иметь свою подпись, нарушенную модификацией info.plist, вы можете установить LSUIElement в 1 по умолчанию то при запуске приложения выполните:
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
чтобы показать значок док-станции или обходить это, если пользователь решил не хотеть значок.
Есть только один побочный эффект, меню приложения не отображается до тех пор, пока оно не потеряет и не восстановит фокус.
Источник: Создание флажка Включить и отключить значок док-станции
Лично я предпочитаю не устанавливать какую-либо опцию Info.plist и использовать TransformProcessType(&psn, kProcessTransformToForegroundApplication)
или TransformProcessType(&psn, kProcessTransformToUIElementApplication)
в зависимости от пользовательских настроек.
Вы можете использовать так называемую политику активации:
// 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)
Это должно скрыть значок док-станции.
NSRunningApplicationActivationPolicy
.В Xcode 4 он отображается как "Application is agent (UIElement)", и он является логическим.
В вашем элементе управления Info.plist щелкните пустое место и выберите "Добавить строку" в меню Тип "Приложение является агентом (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 находится в комплекте приложений, и вы не должны редактировать какие-либо файлы в комплекте приложения, так как это приведет к аннулированию сигнатуры пакетов.
Лучшее решение, которое я нашел, основано на этой превосходной статье. Мое решение основано на комментарии Дэна. Короче говоря, нет способа сделать это с помощью Cocoa, но это возможно с небольшим количеством кода Carbon.
В статье также предлагается создать вспомогательное приложение, которое обрабатывает только значок док-станции. Затем основное приложение запускается и убивает это приложение в зависимости от предпочтений пользователей. Этот подход кажется мне более надежным, чем использование кода Carbon, но я еще не пробовал его.