You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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ᴄʜᴇʀᴏɴғᴀɪʟ

火山引擎 最新活动