检查应用程序的主窗口是否已打开并加载

时间:2016-03-18 18:28:57

标签: objective-c macos cocoa window mainwindow

我的应用程序的一部分是打开应用程序并保留他们打开的工作空间。我的问题是检查主应用程序窗口是否已打开,以便我可以切换到下一个工作区。通常,我可以检查一个窗口是否该应用程序是打开的,但对于某些应用程序,如IntelliJ IDEA,有一个加载窗口不是主要的,但仍显示在CGWindowListCopyWindowInfo()。我检查应用程序的窗口是否打开,然后检查它是否有标题。这适用于IntelliJ IDEA应用程序,但是像计算器这样的应用程序具有没有窗口标题的应用程序的主窗口,代码进入无限等待循环。我已经google了一下,并没有想出任何东西,这是我的应用程序中需要修复的最后一件事。

稍后会添加代码(当我有我的电脑时)

TL; DR:

我需要检查应用程序的主窗口是否打开。 (像INtelliJ IDEA这样的应用程序有一个加载窗口,窗口需要保存在工作区中。

1 个答案:

答案 0 :(得分:1)

经过多次测试后,如果有其他人需要,我会给出答案。

我使用了辅助功能框架,代码如下:

- (NSInteger)numberOfWindowsOpenFromApplicationWithPID:(NSInteger)PID
{
    NSInteger count = 0; // For return.
    AXUIElementRef anApp = AXUIElementCreateApplication((pid_t)PID);
    CFTypeRef aChildren;
    AXUIElementCopyAttributeValue(anApp, kAXChildrenAttribute, &aChildren);

    SafeCFRelease(anApp);
    if (aChildren) {
        for (NSInteger i = 0; i < CFArrayGetCount(aChildren); i++) {
            AXUIElementRef aChild = CFArrayGetValueAtIndex(aChildren, i);
            // Get subrole
            CFTypeRef aSubrole;
            AXUIElementCopyAttributeValue(aChild, kAXSubroleAttribute, &aSubrole);

            NSString *aSubroleString = CFBridgingRelease(aSubrole);
            if (aSubroleString) {
                // Not a menu :3
                if ([aSubroleString isEqualToString:@"AXStandardWindow"]) {
                    count++;
                }
            }
        }

        SafeCFRelease(aChildren);
    } else {
        return 0;
    }
    return count;
}

此代码返回当前工作空间中具有PID的应用程序打开的(主)窗口数。然后我从PID中获取AXApplication,然后我从中获取子项。如辅助功能检查器中所示:

inspector

孩子们是窗户和菜单栏。主窗口的子角色为AXStandardWindow。我的代码循环遍历子进程,然后检查子角色。