Swift macOS:如何查找鼠标指针所在的显示器?
解决macOS下Swift获取鼠标所在显示器的问题
我刚好处理过类似的需求,确实NSScreen.main没法直接满足——它返回的是包含活动窗口的主屏幕(就是菜单栏不透明的那个),而我们需要的是鼠标指针当前停留的屏幕。下面分享两种可靠的实现方式:
方法一:通过全局坐标匹配屏幕
利用NSEvent.mouseLocation获取鼠标的全局坐标,然后遍历所有屏幕,找到包含该坐标的屏幕:
import Cocoa func screenUnderMouse() -> NSScreen? { // 获取鼠标在全局坐标系中的位置(以主屏幕左下角为原点) let mouseGlobalPoint = NSEvent.mouseLocation // 遍历所有屏幕,找到包含该点的屏幕 return NSScreen.screens.first { screen in screen.frame.contains(mouseGlobalPoint) } }
这个方法简单直观,适合大多数场景。需要注意的是,NSScreen.screens返回的屏幕顺序不一定固定,但我们只需要第一个匹配的屏幕(因为鼠标只会在一个屏幕上)。
方法二:通过Core Graphics获取显示器ID匹配
如果需要更底层的准确性,可以用Core Graphics的API先获取鼠标所在的显示器ID,再匹配对应的NSScreen:
import Cocoa import CoreGraphics func screenUnderMouse() -> NSScreen? { let mouseGlobalPoint = NSEvent.mouseLocation // 获取包含该点的显示器ID let targetDisplayID = CGDisplayWithPoint(mouseGlobalPoint) // 遍历屏幕,匹配显示器ID return NSScreen.screens.first { screen in guard let screenID = screen.deviceDescription[NSDeviceDescriptionKey(rawValue: "NSScreenNumber")] as? CGDirectDisplayID else { return false } return screenID == targetDisplayID } }
这种方法依赖Core Graphics的底层调用,在复杂的多显示器布局(比如屏幕旋转、缩放)下可能更稳定。
使用示例
拿到目标屏幕后,就可以在上面创建窗口了:
if let targetScreen = screenUnderMouse() { let window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 400, height: 300), styleMask: [.titled, .closable, .miniaturizable], backing: .buffered, defer: false, screen: targetScreen ) window.center() window.makeKeyAndOrderFront(nil) }
这样创建的窗口会直接显示在鼠标所在的显示器上,完美符合你的需求~
内容的提问来源于stack exchange,提问作者Aᴄʜᴇʀᴏɴғᴀɪʟ




