如何确定是否在特定的NSScreen上运行全屏应用程序

时间:2014-05-24 10:56:38

标签: objective-c macos cocoa fullscreen appkit

在Cocoa / AppKit中,给定[NSScreen screens]的屏幕,我怎样才能知道是否有特定屏幕上运行的全屏应用?我最感兴趣的是那些使用Cocoa API进行全屏的应用程序,但如果有一个解决方案也包含其他类型的全屏应用程序,那就更好了。该解决方案需要能够通过Mac App Store批准。

我的具体用例涉及一个菜单栏应用程序(NSStatusItem),并确定[NSScreen mainScreen]上是否显示菜单栏,以便允许全局键盘快捷方式显示定位在状态项(如果可见)或浮动窗口(如果没有可见状态项)。

NSScreens他们自己似乎没有公开任何有关Windows /应用的信息,NSRunningApplication也没有公开这些信息。

是否有碳API可以找到这个?例如,如果我有一个窗口列表,我可以遍历它们,看看是否有任何窗口框架与屏幕相匹配。完全框架。另一方面,可能有应用程序有这样的框架,但在其他应用程序下运行(如Backdrop应用程序,https://itunes.apple.com/us/app/backdrop/id411461952?mt=12),所以这样的方法需要查看窗口级别。

3 个答案:

答案 0 :(得分:2)

这是基于Swift的CGWindowListCopyWindowInfo的解决方案。

func fullScreenWindows(fullScreen: Bool) -> [CGWindowID] {
    var winList: [CGWindowID] = []
    //If the you want to get the windows in full screen, you MUST make sure the option excluding 'optionOnScreenOnly'
    let option: CGWindowListOption = fullScreen ? .excludeDesktopElements : [.excludeDesktopElements, .optionOnScreenOnly]
    guard let winArray: CFArray = CGWindowListCopyWindowInfo(option, kCGNullWindowID) else {
        return winList
    }
    for i in 0..<CFArrayGetCount(winArray) {

        //The current window's info
        let winInfo = unsafeBitCast(CFArrayGetValueAtIndex(winArray, i), to: CFDictionary.self)

        //The current window's bounds
        guard let boundsDict = (winInfo as NSDictionary)[kCGWindowBounds],
            let bounds = CGRect.init(dictionaryRepresentation: boundsDict as! CFDictionary) else {
            continue
        }

        //Check the window is in full screen
        guard __CGSizeEqualToSize(NSScreen.main!.frame.size, bounds.size) else {
            continue
        }

        //The current window's id
        guard let winId = (winInfo as NSDictionary)[kCGWindowNumber] as? CGWindowID,
            winId == kCGNullWindowID else {
            continue
        }

        winList.append(winId)
    }
    return winList
}

答案 1 :(得分:0)

您可以尝试使用CGWindowList API,例如CGWindowListCopyWindowInfo()

如果您只是想知道菜单栏是否正在显示,您应该可以-[NSApplication currentSystemPresentationOptions]NSApplicationPresentationAutoHideMenuBar查看NSApplicationPresentationHideMenuBar。该方法还可以告诉您活动应用是否处于Cocoa全屏模式(NSApplicationPresentationFullScreen)。

答案 2 :(得分:0)

这是一个基于CGWindowListCopyWindowInfo的解决方案,正如Ken Thomases在他的回答中所建议的:

{{1}}