2010-05-28 11 views
11

Tengo algunos problemas con una aplicación en segundo plano que usa LSUIElement = 1 para ocultar su elemento de base, barra de menú y evitar que aparezca en el selector de aplicaciones Command-Tab.Snow Leopard & LSUIElement -> la aplicación no se activa correctamente, la ventana no está "activa" a pesar de ser "clave"

Parece ser solo un problema de Snow Leopard.

La aplicación coloca un NSStatusItem en la barra de menú y aparece un menú cuando se hace clic en él. Seleccionar "Preferencias ..." debería mostrar una ventana NSW con las preferencias.

Lo primero que no parece funcionar es que la Ventana no se ordena en el frente, sino que aparece detrás de todas las demás ventanas de la aplicación.

Me trataron de solucionar este problema llamando

[[NSApplication sharedApplication] activateIgnoringOtherApps: YES] 

pero eso no funcionó.

Después de un tiempo me di cuenta de que el menú está bloqueando el mensaje al bucle de ejecución de ser enviado, por lo que escribió otro método en el MainController y envió el mensaje con un retraso:

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

-(void)setFront: (id) theWindow { 

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

Nota del send-cada-posible-mensaje-a-hacer-que-hacer-lo-que-debe-ser-haciendo-enfoque.

Esto funciona, tipo de, la ventana se pone al frente sobre todas las demás ventanas de todas las aplicaciones, PERO la mayoría de las veces no está activa, lo que significa que su barra de título está atenuada. Al hacer clic en la barra de título, tampoco se activará la ventana. Al hacer clic dentro de la ventana, ¿se activará?

Todo esto no parecía ser un problema en Leopard; solo llamar a activateIgnoringOtherApps y hacer que la tecla de ventana pareciera funcionar bien.

En Snow Leopard no es una nueva API diseñado para sustituir LSUIElement que se supone para emular su comportamiento:

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

He jugado un poco con eso, pero es SL-solamente y refugio I' He podido configurar LSUIElement.

+0

Lo que estás tratando de hacer se puede percibir como un robo del enfoque, que se hizo bastante difícil. Y es algo bueno ¿Qué hace tu menú? '[preferencesController showWindow:]'? – zneak

+0

No se trata de robar el foco cuando el usuario selecciona "Preferencias ..." y ordena la ventana de preferencias al frente y la convierte en clave, pero sí, la buena gente de Apple podría intentar evitar que lo haga. –

Respuesta

4

Después de publicar la pregunta en la desesperación, seguí buscando y finalmente encontré la solución. Como esto me dejó perplejo durante unos días y parece que no hay otra respuesta que pueda encontrar Google, explicaré la solución para "futuras generaciones".

Snow Leopard añade una nueva API NSApplication presentationOptions:

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

Esto se supone para simular la forma en que funciona LSUIElement, pero proporcionan un mayor control del desarrollador. Lamentablemente, la simulación no es perfecta, por lo que hay un cambio de comportamiento entre 10.5 y 10.6.

En particular, si su aplicación tiene la línea LSUIElement = 1 en su info.plist, Snow Leopard inicializará "las opciones de presentación de la aplicación ...a una combinación equivalente de banderas NSApplicationPresentationOptions lugar ".

Sólo que en realidad no se establece el nuevo NSApplication setActivationPolicy a NSApplicationActivationPolicyAccessory:

" La aplicación no aparece en el Dock y no tiene una barra de menú , pero puede activarse mediante programación o haciendo clic en una de sus ventanas. Esto corresponde a valor de la clave LSUIElement en Info.plist de la aplicación siendo 1."

A pesar de la mención de ser activado mediante programación, activateIgnoringOtherApps: simplemente se ignora completamente

La solución es establecer la política de activación a. "regular":

[[NSApplication sharedApplication] setActivationPolicy: NSApplicationActivationPolicyRegular]; 

por supuesto, sólo se puede hacer esto si se utiliza el 10,6 SDK como Base SDK, algo que pocas personas quieren hacer en el momento, por lo que a continuación es una manera de 10,5 segura de hacer esto :

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]; 

} 

Espero que alguien lo encuentre útil.

+0

Desafortunadamente, esto efectivamente devuelve el ícono Dock. – stephencelis

+0

sí lo hace. Bummer – david

8

Eso es extraño: estoy escribiendo una aplicación LSUIElement bajo Snow Leopard, y no tuve los problemas que usted ha descrito ... Tuve el problema de que la ventana recién creada no aparecía en el frontal, pero lo arreglé llamando a activateIgnoringOtherApps. Esto era todo lo que tenía que hacer para que funcione como es debido:

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

Ni siquiera tocar nada de lo que tenía 'política' en el nombre.

+0

Creo que lo que experimenté fue una interacción entre la política de activación y algo más. El código adicional para seleccionar la política de activación fue eliminado de mi programa hace unas semanas sin efectos nocivos. Es una de esas cosas que simplemente no funciona y luego, de repente, comienza a funcionar bien nuevamente (podría ser una de las actualizaciones de punto de OS X, por supuesto). ¡¿Tal vez la ventana con la que estaba trabajando no podría ser clave o principal ?! –

+0

Esto funcionó para mí. Tuve la misma situación. Pero mi problema era un poco más extraño. Si lo ejecuté desde XCode, funcionó perfectamente. Si ejecutaba la aplicación desde Finder, la ventana no aparecería. Agregar esta línea me ayudó, así que estoy muy feliz. – Vojto

+0

Me ha estado dando muchos dolores de cabeza. Gracias por esta elegante solución – Tibidabo

Cuestiones relacionadas