OSX:如何检测Mission Control是否正在运行?

时间:2012-10-02 01:06:28

标签: objective-c macos cocoa

当Mission Control运行时,它会阻止应用程序接收键盘和鼠标事件。它还使最后一个应用程序运行,认为它仍然具有焦点。这对我来说是一个问题,因为如果我用鼠标按钮或按住键启动Mission Control,我就不会收到keyUp或mouseUp事件,我的应用程序就像按住鼠标按键或按键一样。

即使Mission Control处于活动状态,我想要一种方法来读取键盘和鼠标事件,或者检测Mission Control是否处于活动状态。理想情况下,我希望能够执行后者,因为在Mission Control运行时我实际上无法使用我的应用程序。

我尝试了几件没有运气的事情:

  1. 使用addGlobalMonitorForEventsMatchingMask为键盘和鼠标事件注册全局监视器。当我切换到另一个应用程序时,这会捕获鼠标事件(但不是键盘事件,尽管documentation表示应将keyDown事件发送到全局监视器),但Mission Control似乎不会将事件传播到全局监视器。
  2. 检查[[NSRunningApplication currentApplication] {isActive, ownsMenuBar}]。 显然,即使它没有收到活动,我的申请仍然有效!
  3. 检查[NSApp keyWindow] != nil。 显然,我的一个窗口应该接收关键事件。他们都不是。
  4. 检查Mission Control是否是[NSWorkspace runningApplications]返回的正在运行的应用程序之一。任务控制在运行时不会显示在此列表中。
  5. 编辑:

    我终于解决了这个问题(尽管不是很令人满意)。对于鼠标,事实证明您可以使用[NSEvent pressedMouseButtons]查询按下的按钮的状态。我只是跟踪我认为鼠标状态应该来自NSLeftMouseDown和NSLeftMouseUp事件,并经常将它与[NSEvent pressedMouseButtons]进行比较,以确保它们是一致的。如果他们不是,那么我知道有些东西劫持了我的NSLeftMouseUp事件并采取了相应的行动。

    对于键盘,我找不到查询键盘状态的方法,所以我无法做类似的解决方法。当按下键时,我最终使用presentation options禁用应用程序切换。

5 个答案:

答案 0 :(得分:2)

至少在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进程拥有的特定窗口是否在屏幕上可见,以及它是否位于特定位置。如果满足这两个条件,Mission Control将立即生效。代码将在沙盒应用程序中运行,并且不需要辅助设备的权限。

答案 1 :(得分:1)

您是否尝试使用NSTask进行bash级别?像ps -faxU <username>这样的东西应该列出所有正在运行的进程,然后你可以解析输出,或者你确实可以使用ps -faxU <username> | grep -i "mission control"(在我的头脑中,我不确定如何调用该进程,但是......像“任务控制”似乎合法)。可能不是最优雅的解决方案,但如果没有其他工作可能是值得的。

答案 2 :(得分:0)

可能我错过了什么,但您是否尝试过使用事件点击而不是全局监控?

答案 3 :(得分:0)

看来DTrace有能力看到Mission Control被激活。尝试运行:

  

sudo fs_usage -filesys | grep Mission

从命令行

,然后从/ Application文件夹启动Mission Control应用程序。

您应该会看到很多与Mission Control相关的输出启动。不幸的是,使用键盘快捷键或滑动不会出现相同的输出。当然,在生产代码中使用DTrace并不是我真正推荐的。

答案 4 :(得分:0)

C++ 和 Qt 实现适用于最新的 OS X。

firstName