2010-05-28 4 views
11

Ich habe ein paar Probleme mit einer Hintergrundanwendung, die LSUIElement = 1 verwendet, um seine Dock-Element, Menüleiste und verhindern Sie, dass es in der Befehls-Tab-Anwendung erscheint.Snow Leopard & LSUIElement -> Anwendung nicht richtig aktiviert, Fenster nicht "aktiv" trotz "Schlüssel"

Es scheint ein Snow Leopard nur Problem zu sein.

Die Anwendung platziert ein NSStatusItem in der Menüleiste und öffnet ein Menü, wenn darauf geklickt wird. Wenn Sie "Einstellungen ..." auswählen, sollte ein NSWindow mit den Einstellungen geöffnet werden.

Die erste Sache, die nicht zu funktionieren scheint, ist, dass das Fenster nicht an der Vorderseite geordnet wird, sondern hinter allen anderen Anwendungsfenstern erscheint.

Ich habe versucht, dieses Problem zu beheben, indem

[[NSApplication sharedApplication] activateIgnoringOtherApps: YES] 

nennen, aber das hat nicht funktioniert.

Nach einer Weile mir herausgefunden, dass das Menü aus der Nachricht an die Laufschleife blockiert gesendet werden, so habe ich ein weiteres Verfahren auf den MainController und gesendet, um die Nachricht mit einer Verzögerung:

[self perform: @ selector (setFront :) withObject: [preferencesController window] afterDelay: 1.0];

-(void)setFront: (id) theWindow { 

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

Beachten Sie die send-every-möglich-message-to-make-it-do-was-it-sollte-sein-doing-Ansatz.

Das funktioniert, irgendwie wird das Fenster über alle anderen Fenster von allen Apps nach vorne gebracht, ABER die meiste Zeit ist es nicht aktiv, was bedeutet, dass die Titelleiste ausgegraut ist. Ein Klick auf die Titelleiste macht das Fenster auch nicht aktiv. Durch Klicken auf INSIDE wird das Fenster aktiviert !?

Dies alles schien kein Problem in Leopard zu sein; nur aufrufen activateIgnoringOtherApps und die Fenster-Taste schien gut zu funktionieren.

In Snow Leopard gibt es eine neue API LSUIElement zu ersetzen entworfen, die sein Verhalten soll emulieren:

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

ich gespielt habe damit um, aber es ist SL-only und ich haven‘ Es ist mir gelungen, LSUIElement zu setzen.

+0

Was Sie versuchen zu tun, kann als Stehlen des Fokus wahrgenommen werden, der ziemlich hart gemacht wurde. Und es ist eine gute Sache. Was macht deine Speisekarte? '[preferencesController showWindow:]'? – zneak

+0

Es ist kaum schwer, den Fokus zu stehlen, wenn der Benutzer "Einstellungen ..." auswählt und das Voreinstellungsfenster nach vorne sortiert und es zu einem Schlüssel macht, aber ja, die netten Leute bei Apple könnten versuchen, das zu verhindern. –

Antwort

4

Nachdem ich die Frage in Verzweiflung gestellt hatte, schaute ich weiter und fand schließlich die Lösung. Da mich das für ein paar Tage stupste und es keine andere Antwort gibt, die Google finden kann, werde ich die Lösung für "zukünftige Generationen" erklären.

Snow Leopard fügt eine neue NSApplication presentationOptions API:

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

Dies soll die Art und Weise simulieren, dass LSUIElement funktioniert, aber mehr Entwickler Kontrolle. Leider ist die Simulation nicht perfekt, so dass sich das Verhalten zwischen 10,5 und 10,6 ändert.

Insbesondere, wenn Ihre Anwendung die Zeile LSUIElement = 1 in der Datei info.plist hat, initialisiert Snow Leopard "die Präsentationsoptionen der Anwendung."zu einer äquivalenten Kombination von NSApplicationPresentationOptions Fahnen statt „.

Nur ist es nicht wirklich Es setzt den neuen NSApplication setActivationPolicy zu NSApplicationActivationPolicyAccessory:

“ Die Anwendung im Dock nicht über eine Menüleiste hat nicht angezeigt wird und , aber es kann programmgesteuert oder durch Klicken auf eines der Fenster aktiviert werden. Dies entspricht Wert des LSUIElement Schlüssels in der Info.plist Anwendung programmatisch zu seinem 1.“

Trotz der Erwähnung aktiviert wird, activateIgnoringOtherApps: einfach komplett ignoriert

Die Lösung ist, die Aktivierungspolitik festgelegt. „regular“:

[[NSApplication sharedApplication] setActivationPolicy: NSApplicationActivationPolicyRegular]; 

natürlich können Sie dies nur tun, wenn Sie das 10.6 SDK als Basis SDK verwenden, aber nur wenige Menschen zur Zeit tun wollen, ist so unter einem 10,5-sicherer Weg, dies zu tun :

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

} 

Ich hoffe, dass jemand das nützlich finden wird.

+0

Leider bringt dies effektiv das Dock-Symbol zurück. – stephencelis

+0

ja tut es. bummer – david

8

Das ist seltsam - ich schreibe eine LSUIElement-Anwendung unter Snow Leopard, und ich hatte nicht solche Probleme, wie Sie beschrieben haben ... Ich hatte das Problem, dass das neu erstellte Fenster nicht bei der erschien Front, aber ich habe es behoben, indem ich activateIgnoringOtherApps aufgerufen habe. Das war alles, was ich tun musste, um es, wie es sollte funktioniert:

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

ich nicht einmal etwas berührt hat, die ‚Politik‘ hatte im Namen.

+0

Ich denke, was ich erlebt habe, war eine Interaktion zwischen der Aktivierungsrichtlinie und etwas anderem. Der Zusatzcode für die Auswahl der Aktivierungsrichtlinie wurde vor einigen Wochen aus meinem Programm entfernt, ohne dass es zu Beeinträchtigungen kam. Es ist eines dieser Dinge, die einfach nicht funktionieren und dann plötzlich wieder gut funktionieren (es könnte natürlich eine der OS X-Punktupdates sein). Vielleicht konnte das Fenster, mit dem ich arbeitete, nicht Schlüssel oder Haupt! –

+0

Das hat für mich funktioniert. Ich hatte die gleiche Situation. Aber mein Problem war ein wenig seltsamer. Wenn ich es von XCode lief, funktionierte es perfekt. Wenn ich die Anwendung vom Finder aus ausführen würde, würde das Fenster nicht erscheinen. Das Hinzufügen dieser Linie hat mir sehr geholfen. – Vojto

+0

Es hat mir eine Menge Kopfschmerzen bereitet. Danke für diese elegante Lösung – Tibidabo