我正在研究一个简单的Mac应用程序,可以检测外部屏幕何时拔出,保存所有窗口的位置,再次插入外部屏幕后,将所有窗口恢复到原始位置。 (我知道那里已有应用程序,我只是很好奇这是怎么做的)
经过大量搜索后,我终于设法通过
获取所有窗口NSArray *openWindows = [[NSWorkspace sharedWorkspace] runningApplications];
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
这会返回类似
的内容{
kCGWindowAlpha = 1;
kCGWindowBounds = {
Height = 22;
Width = 279;
X = 1559;
Y = 0;
};
kCGWindowIsOnscreen = 1;
kCGWindowLayer = 25;
kCGWindowMemoryUsage = 13596;
kCGWindowName = "";
kCGWindowNumber = 18;
kCGWindowOwnerName = SystemUIServer;
kCGWindowOwnerPID = 260;
kCGWindowSharingState = 1;
kCGWindowStoreType = 2;
},
{
kCGWindowAlpha = 0;
kCGWindowBounds = {
Height = 22;
Width = 1920;
X = 0;
Y = 0;
};
kCGWindowIsOnscreen = 1;
kCGWindowLayer = 25;
kCGWindowMemoryUsage = 5404;
kCGWindowNumber = 19;
kCGWindowOwnerName = SystemUIServer;
kCGWindowOwnerPID = 260;
kCGWindowSharingState = 1;
kCGWindowStoreType = 2;
},
然后我会遍历数组并查看每个单独的窗口
for (int i = 0; i < CFArrayGetCount(windowList); i++) {
CFDictionaryRef ref = CFArrayGetValueAtIndex(windowList, i);
NSLog(@"%@", CFDictionaryGetValue(ref, kCGWindowBounds));
}
但这就是我遇到的问题,在使用多个屏幕时,我怎么能首先知道窗口在哪个屏幕上。 其次,我怎样才能在以后调整窗口界限?每个应用程序都有自己的ID吗?或者我可以使用另一种方法吗?
答案 0 :(得分:2)
由于CGWindowList
API不公开屏幕ID,您必须根据屏幕边界检查窗口边界:
NSArray* windowList = (__bridge NSArray*)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
uint32_t maxDisplayCount = 10;
CGDirectDisplayID onlineDisplayIDs[maxDisplayCount];
uint32_t displayCount;
CGGetOnlineDisplayList(maxDisplayCount, (CGDirectDisplayID*)&onlineDisplayIDs, &displayCount);
for(uint32_t i = 0; i < displayCount; ++i)
{
CGRect dspyRect = CGDisplayBounds(onlineDisplayIDs[i]);
for(NSDictionary* windowDict in windowList)
{
CGRect windowRect;
CGRectMakeWithDictionaryRepresentation((__bridge CFDictionaryRef)(windowDict[(id)kCGWindowBounds]), &windowRect);
if(CGRectContainsRect(dspyRect, windowRect))
{
NSLog(@"window %@ is on screen with ID:%d", windowDict[(id)kCGWindowName], onlineDisplayIDs[i]);
}
}
}
上面的代码执行一个天真的检查,测试一个窗口是否完整在特定的屏幕上 如果窗口的某个部分覆盖该屏幕,则OS X认为属于屏幕的窗口。 (OS X版本之间的这种行为也略有改变)
要移动窗口,您可以使用Apple Events或Cocoa Accessibility APIs 请注意,Cocoa Accessibility要求您使用“系统偏好设置”中的“启用辅助设备访问” 启用App Sandboxing时,这两种技术都可能出现问题。