2009-03-06 21 views
50

Quiero hacer una preferencia para ocultar el icono de Dock y mostrar un NSStatusItem. Puedo crear el StatusItem pero no sé cómo eliminarlo de Dock. : -/Cómo ocultar el icono de Dock

¿Alguna idea?

+0

si su aplicación se basa en QT5, también es necesario para establecer el varentorno 'QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM' –

Respuesta

63

creo que busca la LSUIElement en el Info.plist

LSUIElement (String). Si esta clave se establece en "1", Launch Services ejecuta la aplicación como una aplicación de agente. Las aplicaciones del agente no aparecen en el Dock o en la ventana Force Quit. Aunque normalmente se ejecutan como aplicaciones en segundo plano, pueden aparecer en primer plano para presentar una interfaz de usuario, si así lo desean.

ver una breve discusión acerca here convirtiéndolo encendido/apagado

2

Si usted quiere que sea una preferencia de usuario, entonces no puede utilizar UIElement. UIElement reside en el paquete de la aplicación, no debe editar ninguno de los archivos en el paquete de la aplicación, ya que esto invalidará la firma de los paquetes.

La mejor solución que he encontrado se basa en this excellent article. Mi solución se basa en el comentario de Dan. En resumen, no hay forma de hacer esto con Cocoa, pero es posible con un poquito de código de carbono.

El artículo también sugiere crear una aplicación de ayuda que maneje el ícono de dock exclusivamente. La aplicación principal luego inicia y elimina esta aplicación según las preferencias de los usuarios. Este enfoque me parece más sólido que usar el código de carbono, pero aún no lo he probado.

43

Para hacerlo, respetando las directrices de Apple de no modificar paquetes de aplicaciones y garantizar que las aplicaciones Mac App Store/(aplicaciones Lion?) No tengan su firma rota por la modificación de info.plist, puede establecer LSUIElement en 1 por Preferido y cuando se inicia la aplicación hacen:

ProcessSerialNumber psn = { 0, kCurrentProcess }; 
TransformProcessType(&psn, kProcessTransformToForegroundApplication); 

a mostrar su icono del dock, o de derivación esto si el usuario ha decidido no desea que el icono.

No hay más que un efecto secundario, el menú de la aplicación no se muestra hasta que pierde y recupera el foco.

Fuente: Making a Checkbox Toggle The Dock Icon On and Off

Personalmente prefiero no establecer ninguna opción Info.plist y utilizar TransformProcessType(&psn, kProcessTransformToForegroundApplication) o TransformProcessType(&psn, kProcessTransformToUIElementApplication) basan en lo que es la configuración de usuario.

+0

Gracias! ¡Justo lo que he estado buscando! – MrMage

+0

¡Un gran consejo! ¡Gracias! Siempre querrá ocultar el icono Dock de esta manera para asegurarse de que su aplicación firmada funcione. – Form

+1

Las soluciones derivadas de este código de ruta no permiten que una aplicación * realmente desee * sea LSUIElement YES (como en, no tenga barra de menú, etc.). Alternar el proceso de esta manera hará que se muestre un menú como se indica en la respuesta. Ciertamente respeto que esto es lo más cercano a una respuesta para esta funcionalidad pasada por alto, pero no es una solución precisa. Les digo a los usuarios que simplemente agreguen manualmente la aplicación al Dock si quieren un ícono allí. – SG1

25

En Xcode 4 se muestra como "La aplicación es agente (UIElement)" y es booleana.

En su control Info.plist, haga clic en un espacio vacío y seleccione "Agregar fila" en el menú Escriba "Aplicación es agente (UIElement)" Configúrelo SÍ.

PARA hacerlo opcional Agregué la siguiente línea a mi código (¡gracias Valexa!)

// hide/display dock icon 
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"hideDockIcon"]) { 
    //hide icon on Dock 
    ProcessSerialNumber psn = { 0, kCurrentProcess }; 
    TransformProcessType(&psn, kProcessTransformToForegroundApplication); 
} 
33

motivados de here, que puede hacer:

[NSApp setActivationPolicy: NSApplicationActivationPolicyAccessory]; 

o

[NSApp setActivationPolicy: NSApplicationActivationPolicyProhibited]; 

Esto debería ocultar el icono de la base. Consulte here para obtener documentación acerca de NSApplicationActivationPolicy.

Véase también la pregunta relacionada "Start a GUI process in Mac OS X without dock icon".

+2

Esta es definitivamente la solución más elegante. Funciona perfectamente. – codingFriend1

+1

+1. 'NSApplicationActivationPolicyAccessory' en realidad permite que aparezca el menú principal. –

+1

De los documentos de Apple: actualmente, NSApplicationActivationPolicyNone y NSApplicationActivationPolicyAccessory pueden cambiarse a NSApplicationActivationPolicyRegular, pero otras modificaciones no son compatibles. –

9

Actualización para Swift: (Use las dos maneras se ha presentado arriba, tienen el mismo resultado)

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 
} 
Cuestiones relacionadas