26

Mission Control が実行されると、アプリケーションがキーボード イベントとマウス イベントを受信できなくなります。また、最後のアプリケーションがまだフォーカスを持っていると考えて、実行中のアプリケーションを残します。マウス ボタンまたはキーを押したまま Mission Control を起動すると、keyUp または mouseUp イベントを受信せず、アプリケーションがそのマウス ボタンまたはキーを押した場合のように動作するため、これは私にとって問題です。

ミッション コントロールがアクティブな場合でもキーボード イベントとマウス イベントの両方を読み取る方法、またはミッション コントロールがアクティブであることを検出する方法が必要です。理想的には、Mission Control の実行中はアプリケーションを実質的に使用できないため、後者を実行できるようにしたいと考えています。

私は運がないことをいくつか試しました:

  1. addGlobalMonitorForEventsMatchingMask を使用して、キーボード イベントとマウス イベントのグローバル モニターを登録します。これは、別のアプリケーションに切り替えたときにマウス イベントをキャプチャします (キーボード イベントはキャプチャしませんが、ドキュメントには keyDown イベントをグローバル モニタに送信する必要があると記載されています) が、Mission Control はイベントをグローバル モニタに伝播させないようです。
  2. 確認してください[[NSRunningApplication currentApplication] {isActive, ownsMenuBar}]。どうやら、私のアプリケーションはイベントを受信して​​いなくてもアクティブです!
  3. 確認してください[NSApp keyWindow] != nil。どうやら、私のウィンドウの 1 つが重要なイベントを受信して​​いるはずです。それらのどれもありません。
  4. によって返された実行中のアプリケーションの 1 つに Mission Control があるかどうかを確認し[NSWorkspace runningApplications]ます。Mission Control は、実行中はこのリストに表示されません。

編集:

私は最終的にこの問題を回避しました (あまり満足のいく方法ではありませんが)。マウスの場合、押されたボタンの状態を で照会できることがわかりました[NSEvent pressedMouseButtons]。NSLeftMouseDown および NSLeftMouseUp イベントから、マウスの状態がどうあるべきかを追跡し、それを頻繁に比較して[NSEvent pressedMouseButtons]、それらが一貫していることを確認します。そうでない場合は、何かが私の NSLeftMouseUp イベントをハイジャックしたことがわかり、それに応じて行動します。

キーボードについては、キーボードの状態を照会する方法が見つからなかったため、同様の回避策を実行できませんでした。キーが押されたときにプレゼンテーションオプションを使用してアプリケーションの切り替えを無効にすることになりました。

4

5 に答える 5

3

少なくとも OS X 10.10 では、このコードを使用して Mission Control がアクティブかどうかを確認できます。

func missionControlIsActive() -> Bool
{
    var result: Bool = false
    let windowInfosRef = CGWindowListCopyWindowInfo(CGWindowListOption(kCGWindowListOptionOnScreenOnly), CGWindowID(0)) // CGWindowID(0) is equal to kCGNullWindowID
    let windowList: NSArray = windowInfosRef.takeRetainedValue() // We own the returned CFArrayRef
    for entry in windowList
    {
        if (entry.objectForKey("kCGWindowOwnerName") as! String) == "Dock"
        {
            var bounds: NSDictionary = entry.objectForKey("kCGWindowBounds") as! NSDictionary
            if (bounds.objectForKey("Y") as! NSNumber) == -1
            {
                result = true
            }
        }
    }
    return result
}

簡単に言えば、このコードは、OS X Dock プロセスが所有する特定のウィンドウが画面に表示されているかどうか、およびそれが特定の位置にあるかどうかをチェックします。両方の条件が満たされている場合、ミッション コントロールはすぐにアクティブになります。コードはサンドボックス化されたアプリで機能し、補助デバイスの権限は必要ありません。

于 2015-07-27T23:42:23.560 に答える
1

NSTask を使用して bash レベルで試しましたか? 実行中のすべてのプロセスをリストする必要があるようなものps -faxU <username>で、出力を解析するか、実際に使用できますps -faxU <username> | grep -i "mission control"(頭のてっぺんでは、プロセスがどのように呼び出されるかわかりませんが、「ミッションコントロール」のようなものは合法のようです)。おそらく最もエレガントなソリューションではありませんが、他に何も機能しない場合は、それだけの価値があるかもしれません.

于 2012-10-29T22:08:17.303 に答える
0

何かが足りないのかもしれませんが、グローバル モニタリングの代わりにイベント タップを使用しようとしましたか?

于 2012-10-25T21:01:05.750 に答える
0

DTrace には、Mission Control がアクティブになっていることを確認する機能があるようです。実行してみてください:

sudo fs_usage -filesys | grep ミッション

コマンド ラインから、/Application フォルダーから Mission Control アプリを起動します。

Mission Control の起動に関連する多くの出力が表示されるはずです。残念ながら、これと同じ出力は、キーボード ショートカットまたはスワイプを使用しても表示されませんでした。もちろん、実稼働コードで DTrace を使用することは、実際にはお勧めできません。

于 2013-03-02T20:58:36.343 に答える