12

LSUIElement=1 を使用してドック項目、メニュー バーを非表示にし、Command-Tab アプリケーション スイッチャーに表示されないようにするバックグラウンド アプリケーションでいくつかの問題が発生しています。

Snow Leopard のみの問題のようです。

アプリケーションは NSStatusItem をメニュー バーに配置し、クリックするとメニューをポップアップします。「設定...」を選択すると、設定を含む NSWindow が表示されます。

機能していないように見える最初のことは、ウィンドウが前面に配置されず、他のすべてのアプリケーション ウィンドウの背後に表示されることです。

電話してこれを修正しようとしました

[[NSApplication sharedApplication] activateIgnoringOtherApps: YES]

しかし、それはうまくいきませんでした。

しばらくして、メニューが実行ループへのメッセージの送信をブロックしていることがわかったので、MainController に別のメソッドを記述し、遅延してメッセージを送信しました。

[self performSelector:@selector(setFront:) withObject: [preferencesController ウィンドウ] afterDelay:1.0];

-(void)setFront: (id) theWindow {

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

send-every-possible-message-to-make-it-do-what-it-should-be-doing-approach に注意してください。

これは機能しますが、ウィンドウはすべてのアプリの他のすべてのウィンドウの上に前面に表示されますが、ほとんどの場合、アクティブではなく、タイトル バーがグレー表示されます。タイトル バーをクリックしても、ウィンドウはアクティブになりません。ウィンドウの INSIDE をクリックするとアクティブになる!?

これはすべて、Leopard では問題ではないように思われました。activateIgnoringOtherApps を呼び出してウィンドウ キーを作成するだけで問題なく動作するように見えました。

Snow Leopard には、その動作をエミュレートすることになっている LSUIElement を置き換えるように設計された新しい API があります。

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

私はそれをいじってみましたが、それは SL のみであり、LSUIElement を設定することができませんでした。

4

2 に答える 2

8

それは奇妙です-私はSnow LeopardでLSUIElementアプリケーションを書いていますが、あなたが説明したような問題はありませんでした...新しく作成されたウィンドウが前面に表示されないという問題がありましたが、 activateIgnoringOtherApps を呼び出して修正しました。これは、正常に機能させるために私がしなければならなかったすべてです。

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

名前に「ポリシー」が含まれているものには触れませんでした。

于 2010-11-02T19:49:46.497 に答える
4

絶望的に質問を投稿した後、私は探し続け、最終的に解決策を見つけました. これは数日間私を困惑させ、Googleが見つけることができる他の答えがないように見えるので、「将来の世代」の解決策を説明します.

Snow Leopard は、新しい NSApplication presentationOptions API を追加します。

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

これは、LSUIElement が機能する方法をシミュレートすることになっていますが、より多くの開発者制御を提供します。残念ながら、シミュレーションは完全ではないため、10.5 と 10.6 の間で動作が変更されています。

特に、アプリケーションの info.plist に LSUIElement = 1 行がある場合、Snow Leopard は「アプリケーションの presentationOptions .. 代わりに NSApplicationPresentationOptions フラグの同等の組み合わせに」初期化します。

ただ、そうではありません。新しい NSApplication setActivationPolicy を NSApplicationActivationPolicyAccessory に設定します。

「アプリケーションは Dock に表示されず、メニュー バーもありませんが、プログラムによって、またはウィンドウの 1 つをクリックすることによってアクティブ化される可能性があります。これは、アプリケーションの Info.plist の LSUIElement キーの値が 1 であることに対応します。」

プログラムでアクティブ化するという言及にもかかわらず、 activateIgnoringOtherApps: は単に完全に無視されます。

解決策は、アクティベーション ポリシーを「通常」に設定することです。

[[NSApplication sharedApplication] setActivationPolicy: NSApplicationActivationPolicyRegular];

もちろん、10.6 SDK を Base SDK として使用する場合にのみこれを行うことができますが、現時点ではこれを行う人はほとんどいないため、以下は 10.5 で安全な方法です。

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

}

誰かがこれが役に立つことを願っています。

于 2010-05-28T14:10:34.043 に答える