如何确定Mac应用窗口所在的Mission Control桌面?
确定应用窗口所在的Mission Control桌面(macOS私有API实现)
问题背景
已通过CGSCopySpaces获取所有空间,但CGSSpaceCopyName始终返回null,无法通过名称判断应用窗口所在桌面,需要借助macOS私有API直接关联窗口与空间ID。
可行私有API方案
macOS私有CoreGraphics框架提供了CGSGetWindowSpace接口,可直接获取指定窗口所属的空间ID;对于全屏窗口,需额外判断空间类型(kCGSSpaceFullScreen),因为全屏窗口会独占一个独立空间。
关键API说明
CGSGetWindowSpace(CGSConnectionID connection, CGWindowID windowID, CGSSpaceID *outSpace):获取窗口对应的空间ID,输出参数outSpace返回结果CGSSpaceGetType(CGSConnectionID connection, CGSSpaceID space):判断空间类型,区分普通桌面与全屏空间
修正后的代码示例
#include <CoreGraphics/CoreGraphics.h> #include <iostream> #include <CoreFoundation/CoreFoundation.h> int main() { CGSConnectionID conn = CGSMainConnectionID(); // 获取当前应用的主窗口ID(需替换为你的目标窗口ID) CGWindowID targetWindowID = /* 你的窗口ID,可通过CGWindowListCopyWindowInfo获取 */; // 获取窗口所属空间ID CGSSpaceID windowSpaceID; OSStatus status = CGSGetWindowSpace(conn, targetWindowID, &windowSpaceID); if (status != kCGErrorSuccess) { std::cerr << "Failed to get window space: " << status << std::endl; return 1; } // 获取所有空间列表 CFArrayRef allSpaces = CGSCopySpaces(conn, kCGSAllSpacesMask); if (!allSpaces) { std::cerr << "Failed to retrieve all spaces" << std::endl; return 1; } CFIndex spaceCount = CFArrayGetCount(allSpaces); std::cout << "Target window is in space ID: " << windowSpaceID << std::endl; // 遍历空间,匹配并输出位置信息 for (CFIndex i = 0; i < spaceCount; ++i) { CGSSpaceID spaceID = (CGSSpaceID)(uintptr_t)CFArrayGetValueAtIndex(allSpaces, i); CGSSpaceType spaceType = CGSSpaceGetType(conn, spaceID); std::cout << "Space " << i + 1 << " (ID: " << spaceID << ") "; if (spaceType == kCGSSpaceFullScreen) { std::cout << "[Full Screen]"; } else { std::cout << "[Normal Desktop]"; } if (spaceID == windowSpaceID) { std::cout << " <<< Target window here"; } std::cout << std::endl; } CFRelease(allSpaces); return 0; }
注意事项
- 兼容性:私有API无官方文档,macOS版本更新可能导致接口失效(如Ventura/Sonoma部分接口签名变化),需针对目标系统版本测试
- 权限:若应用启用沙箱,需添加
com.apple.security.temporary-exception.mach-lookup.global-name权限,允许访问com.apple.CoreGraphics.server服务;同时可能需要辅助功能权限获取窗口信息 - 全屏窗口处理:全屏应用的空间类型为
kCGSSpaceFullScreen,这类空间不属于普通桌面列表,需单独判断
内容的提问来源于stack exchange,提问作者DreTaX
相关产品推荐
相关产品推荐

