当显示器连接或断开连接时通知

14

我正在开发一款OS X应用程序,该程序在所有连接的显示器的所有可用空间上显示自定义窗口。 通过调用[NSScreen screens]可以获取可用显示对象数组。

目前我需要解决的问题是如何知道用户是否连接或断开了系统中的屏幕。

我已经搜索了Cocoa文档以寻找处理此类场景的通知,但并没有太大的运气,我不相信没有某种系统通知可以在更改连接到系统的显示器数量时发布。

请问如何解决这个问题?


也许是 NSApplicationDidChangeScreenParametersNotification - Martin R
2个回答

16

有几种方法可以实现这个目标:
您可以在应用程序委托中实现applicationDidChangeScreenParameters: 方法(该方法属于NSApplicationDelegateProtocol)。
另一种方法是通过监听由默认通知中心 [NSNotificationCenter defaultCenter] 发送的NSApplicationDidChangeScreenParametersNotification 通知来实现。

每当调用您的委托方法或接收到通知时,您都可以迭代[NSScreen screens]并查看是否连接或移除了显示器(您必须维护一个在程序启动时可以检查的显示列表)。

一个非 Cocoa 的方法是通过核心图形显示服务:
您必须实现重新配置函数并使用CGDisplayRegisterReconfigurationCallback(CGDisplayReconfigurationCallBack cb, void* obj); 注册它。

在您的重新配置函数中,您可以查询所影响的显示器的状态。例如:

void DisplayReconfigurationCallBack(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void* userInfo)
{
    if(display == someDisplayYouAreInterestedIn)
    {
        if(flags & kCGDisplaySetModeFlag)
        {
            ...
        }
        if(flags & kCGDisplayRemoveFlag)
        {
            ...
        }
        if(flags & kCGDisplayDisabledFlag)
        {
           ...
        }
    }
    if(flags & kCGDisplaySetModeFlag || flags & kCGDisplayDisabledFlag || flags & kCGDisplayRemoveFlag)
    {
        ...
    }
}

感谢您的评论。使用Core Graphics显示服务相比Cocoa通知和我的Cocoa方法有什么好处?在我看来,它似乎增加了额外的复杂性,没有明显的收益。 - Gabor
唯一的好处是重新配置回调已经包含一些状态信息(作为CGDisplayChangeSummaryFlags传递),因此当重新配置发生时,您不必自己比较所有NSScreen细节。当然,Cocoa通知或委托方法也可以。 - Thomas Zoechling

3

在Swift 3.0中:

let nc = NotificationCenter.default
    nc.addObserver(self,
                   selector: #selector(screenDidChange),
                   name: NSNotification.Name.NSApplicationDidChangeScreenParameters,
                   object: nil)

NC 回调:

final func screenDidChange(notification: NSNotification){
    let userInfo = notification.userInfo
    print(userInfo)
}

显然,在Swift 5.5.1之前的某个时候,NSApplicationDidChangeScreenParameters通知被移除了。还有其他合理的方法可以检测Mac上外部显示器的连接/断开吗? - SouthernYankee65
1
未来参考,任何遇到类似问题的人可以参考 这里,这是 @SouthernYankee65 的新问题。 - George

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接