2009-03-06 22 views
50

Desidero fare una preferenza per nascondere l'icona del Dock e mostrare un NSStatusItem. Posso creare StatusItem ma non so come rimuovere l'icona dal Dock. : -/Come nascondere l'icona del Dock

Qualche idea?

+0

se la vostra applicazione è basata su QT5, è anche necessario impostare l'envvar 'QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM' –

risposta

63

Penso che si sta cercando il LSUIElement in Info.plist

LSUIElement (String). Se questa chiave è impostata su "1", Launch Services esegue l'applicazione come applicazione agente. Le applicazioni dell'agente non vengono visualizzate nel Dock o nella finestra Uscita forzata. Sebbene in genere vengano eseguiti come applicazioni in background, possono essere visualizzati in primo piano per presentare un'interfaccia utente, se lo si desidera.

Vedi una breve discussione su here accenderlo/off

2

Se si vuole rendere una preferenza utente, allora non è possibile utilizzare UIElement. UIElement risiede nel pacchetto di applicazioni, non dovresti modificare nessuno dei file nel pacchetto di app in quanto ciò invaliderà la firma dei bundle.

La soluzione migliore che ho trovato si basa su this excellent article. La mia soluzione è basata sul commento di Dan. In breve, non c'è modo di farlo con Cocoa, ma è possibile con un po 'di codice del carbonio.

L'articolo suggerisce anche di creare un'app helper che gestisca esclusivamente l'icona del dock. L'app principale quindi avvia e uccide questa app in base alle preferenze degli utenti. Questo approccio mi sembra più robusto rispetto all'uso del codice Carbon, ma non l'ho ancora provato.

43

Per farlo rispettando le linee guida Apple relative alla non modifica dei pacchetti di applicazioni e per garantire che le app/app (app Lion) di Mac App non abbiano la firma spezzata dalla modifica info.plist, è possibile impostare LSUIElement su 1 di predefinito poi, quando si avvia l'applicazione fanno:

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

per mostrare che è icona del dock, o bypass questo se l'utente ha scelto di non volere l'icona.

C'è solo un effetto collaterale, il menu dell'applicazione non viene visualizzato finché non perde e riprende la messa a fuoco.

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

Personalmente preferisco non impostare alcuna opzione Info.plist e utilizzare TransformProcessType(&psn, kProcessTransformToForegroundApplication) o TransformProcessType(&psn, kProcessTransformToUIElementApplication) basano su quello che è l'impostazione utente.

+0

Grazie! Proprio quello che stavo cercando! – MrMage

+0

Ottimo consiglio! Grazie! Dovrai sempre nascondere l'icona del Dock in questo modo per assicurarti che l'app firmata funzioni. – Form

+1

Le soluzioni derivate da questo codepath non consentono un'app che * in realtà desidera * essere LSUIElement YES (come in, non avere la barra dei menu, ecc.). Commutare il processo in questo modo farà apparire un menu come indicato nella risposta. Sicuramente rispondo che questa è la cosa più vicina a una risposta per questa funzionalità trascurata, ma non è una soluzione precisa. Dico agli utenti di aggiungere manualmente l'app al Dock se vogliono un'icona lì. – SG1

25

In Xcode 4 è indicato come "L'applicazione è agente (UIElement)" ed è booleano.

Nella tua Info.plist control-click a uno spazio vuoto e selezionare "Aggiungi riga" dal menu di tipo "L'applicazione è l'agente (UIElement)" Set è SI.

Per renderlo opzionale ho aggiunto la seguente riga al mio codice (grazie Valexa!)

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

Motivato da here, si può fare:

[NSApp setActivationPolicy: NSApplicationActivationPolicyAccessory]; 

o

[NSApp setActivationPolicy: NSApplicationActivationPolicyProhibited]; 

Questo dovrebbe nascondere l'icona del dock. Vedere here per alcuni documenti su NSApplicationActivationPolicy.

Vedere anche la domanda relativa "Start a GUI process in Mac OS X without dock icon".

+2

Questa è sicuramente la soluzione più elegante. Funziona perfettamente. – codingFriend1

+1

+1. 'NSApplicationActivationPolicyAccessory' consente in effetti di visualizzare il menu principale. –

+1

Da documenti Apple: Attualmente, NSApplicationActivationPolicyNone e NSApplicationActivationPolicyAccessory possono essere modificati in NSApplicationActivationPolicyRegular, ma non sono supportate altre modifiche. –

9

Aggiornamento per Swift: (usate in entrambe le direzioni è stato presentato sopra, hanno lo stesso risultato)

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 
} 
Problemi correlati