首页 文章

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

提问于
浏览
24

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

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

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

  • 使用addGlobalMonitorForEventsMatchingMask为键盘和鼠标事件注册全局监视器 . 当我切换到另一个应用程序时,这会捕获鼠标事件(但不捕获键盘事件,尽管documentation表示应将keyDown事件发送到全局监视器),但Mission Control似乎不会将事件传播到全局监视器 .

  • 检查 [[NSRunningApplication currentApplication] {isActive, ownsMenuBar}] . 显然,我的应用程序是活跃的,即使它没有收到事件!

  • 检查 [NSApp keyWindow] != nil . 显然,我的一个窗口应该接收关键事件 . 他们都不是 .

  • 检查Mission Control是否是 [NSWorkspace runningApplications] 返回的正在运行的应用程序之一 . 任务控制在运行时不会显示在此列表中 .

提前致谢!

编辑:

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

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

4 回答

  • 1

    至少在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将立即生效 . 代码将在沙盒应用程序中运行,并且不需要辅助设备的权限 .

  • 0

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

  • 0

    可能是我错过了一些东西,但是你试过使用事件点击而不是全局监控吗?

  • 2

    看来DTrace有能力看到Mission Control被激活 . 试试跑步:

    sudo fs_usage -filesys | grep使命

    从命令行,然后从/ Application文件夹启动Mission Control应用程序 .

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

相关问题