2010-05-28 11 views
11

Sto riscontrando qualche problema con un'applicazione di sfondo che utilizza LSUIElement = 1 per nascondere la sua voce di dock, la barra dei menu e impedirgli di apparire nel commutatore di applicazioni della scheda di comando.Snow Leopard & LSUIElement -> l'applicazione non si attiva correttamente, finestra non "attiva" nonostante sia "chiave"

Sembra essere solo un problema di Snow Leopard.

L'applicazione inserisce un NSStatusItem nella barra dei menu e fa apparire un menu quando viene cliccato. Selezionare "Preferenze ..." dovrebbe far apparire una NSWindow con le preferenze.

La prima cosa che sembra non funzionare è che la finestra non viene ordinata nella parte anteriore, ma appare dietro tutte le altre finestre dell'applicazione.

ho cercato di risolvere il problema chiamando

[[NSApplication sharedApplication] activateIgnoringOtherApps: YES] 

ma che non ha funzionato.

Dopo un po 'ho capito che il menu sta bloccando il messaggio per il ciclo di esecuzione venga inviato, così ho scritto un altro metodo sul MainController e ha inviato il messaggio con un ritardo:

[auto performSelector: @ selettore (setFront :) withObject: [preferencesController window] afterDelay: 1.0];

-(void)setFront: (id) theWindow { 

[[NSApplication sharedApplication]activateIgnoringOtherApps:YES]; 
[theWindow orderFrontRegardless]; 
[theWindow makeKeyWindow]; 
     [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; 
} 

Annotare il send-ogni-possibile-messaggio-to-make-it-do-ciò-che-deve-essere-facendo-approccio.

Questo funziona, tipo, la finestra viene portata in primo piano in cima a tutte le altre finestre da tutte le app, MA la maggior parte delle volte non è attiva, il che significa che la barra del titolo è disattivata. Fare clic sulla barra del titolo non renderà attiva la finestra. Cliccando all'interno della finestra lo renderà attivo !?

Questo non sembra essere un problema in Leopard; solo chiamando activateIgnoringOtherApps e facendo in modo che la chiave della finestra sembrasse funzionare bene.

In Snow Leopard c'è una nuova API progettato per sostituire LSUIElement che dovrebbe emulare il suo comportamento:

http://developer.apple.com/mac/library/releasenotes/cocoa/appkit.html

Ho giocato in giro con questo, ma è SL-only e mi rifugio' Sono stato in grado di impostare LSUIElement.

+0

Quello che stai cercando di fare può essere percepito come rubare la messa a fuoco, che è stata resa piuttosto difficile. Ed è una buona cosa Cosa fa il tuo menu? '[preferencesController showWindow:]'? – zneak

+0

Difficile rubare la messa a fuoco quando l'utente seleziona "Preferenze ..." e ordinate la finestra delle preferenze in primo piano e fatela diventare la chiave, ma sì, le persone simpatiche di Apple potrebbero cercare di impedirvi di farlo. –

risposta

4

Dopo aver postato la domanda in preda alla disperazione, ho continuato a cercare e alla fine ho trovato la soluzione. Dal momento che questo mi ha bloccato per qualche giorno e sembra che non ci siano altre risposte là fuori che google possa trovare, spiegherò la soluzione per le "future generazioni".

Snow Leopard aggiunge una nuova API NSApplication presentationOptions:

http://developer.apple.com/mac/library/releasenotes/cocoa/appkit.html

Questo dovrebbe simulare il modo in cui LSUIElement funziona, ma fornire un maggiore controllo degli sviluppatori. Sfortunatamente, la simulazione non è perfetta, quindi c'è un cambio di comportamento tra 10.5 e 10.6.

In particolare, se l'applicazione ha LSUIElement = 1 riga nel suo info.plist, Snow Leopard inizializzerà "presentationOptions dell'applicazione ..a una combinazione equivalente di NSApplicationPresentationOptions bandiere, invece ".

Solo che in realtà non si imposta la nuova NSApplication setActivationPolicy a NSApplicationActivationPolicyAccessory:

" L'applicazione non appare nel Dock e non ha una barra dei menu , ma può essere attivato a livello di programmazione o facendo clic su una delle sue finestre. Questo corrisponde al valore della chiave LSUIElement in Info.plist dell'applicazione essendo 1."

Nonostante la menzione essere attivati ​​programatically, activateIgnoringOtherApps: viene semplicemente ignorato completamente

La soluzione è impostare il criterio di attivazione. "regolare":

[[NSApplication sharedApplication] setActivationPolicy: NSApplicationActivationPolicyRegular]; 

Naturalmente, si può fare solo se si utilizza il 10,6 SDK come Base SDK, qualcosa che poche persone vogliono fare in questo momento, così in basso è un modo 10.5-safe di fare questo :

NSApplication* app = [NSApplication sharedApplication]; 

if([app respondsToSelector: @selector(setActivationPolicy:)]) { 

    NSMethodSignature* method = [[app class] instanceMethodSignatureForSelector: @selector(setActivationPolicy:)]; 
    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: method]; 
    [invocation setTarget: app]; 
    [invocation setSelector: @selector(setActivationPolicy:)]; 
    NSInteger myNSApplicationActivationPolicyAccessory = 0; 
    [invocation setArgument: &myNSApplicationActivationPolicyAccessory atIndex: 2]; 
    [invocation invoke]; 

} 

Spero che qualcuno lo troverà utile.

+0

Sfortunatamente, questo riporta in effetti l'icona del Dock. – stephencelis

+0

sì, sì. Bummer – david

8

Questo è strano - Sto scrivendo un'applicazione di LSUIElement sotto Snow Leopard, e non ho avuto problemi come quello che hai descritto ... Ho avuto il problema che la finestra appena creata non è stata visualizzata front, ma l'ho risolto chiamando activateIgnoringOtherApps. Questo era tutto quello che dovevo fare per farlo funzionare come si deve:

[NSApp activateIgnoringOtherApps: YES]; 
[preferencesWindow makeKeyAndOrderFront: self]; 

non ho nemmeno toccato niente che non aveva 'politica' nel nome.

+0

Penso che quello che ho vissuto sia un'interazione tra la politica di attivazione e qualcos'altro. Il codice aggiuntivo per la selezione della politica di attivazione è stato rimosso dal mio programma poche settimane fa senza effetti negativi? È una di quelle cose che semplicemente non funzionerà e poi all'improvviso inizia a funzionare di nuovo bene (potrebbe essere uno degli aggiornamenti del punto OS X, ovviamente). Forse la finestra con cui stavo lavorando non poteva diventare la chiave o il main !? –

+0

Questo ha funzionato per me. Ho avuto la stessa situazione. Ma il mio problema era un po 'più strano. Se l'ho eseguito da XCode, ha funzionato perfettamente. Se eseguissi l'applicazione dal Finder, la finestra non comparirebbe. L'aggiunta di questa linea ha aiutato così sono davvero felice. – Vojto

+0

Mi ha dato un sacco di mal di testa. Grazie per questa soluzione elegante – Tibidabo