How to retrieve active window URL using Mac OS X accessibility API

Viewed 574

I was wondering if there was a way to retrieve the URL of the active window, if it has one. The following code should work, but it doesn't, the title variable becomes "", and I don't get any new information.

I'm positive that that's because I'm using kAXURLAttributes of the wrong object, but I have no clue which one should I copy it from... Apple's documentation has very few explanations.

AXUIElementRef appElem = AXUIElementCreateApplication(pid), window = nullptr;
        CFStringRef title = nullptr;
        if (!appElem) { return; }
        if (AXUIElementCopyAttributeValue (appElem, kAXFocusedWindowAttribute,
                                           reinterpret_cast<CFTypeRef*>(&window)) != kAXErrorSuccess && appElem)
            CFRelease(appElem);
        if(AXUIElementCopyAttributeValue (window, kAXTitleAttribute,
                                          reinterpret_cast<CFTypeRef*>(&title))!=kAXErrorSuccess && window)
            CFRelease(window);
        focusedAppTitle = QString::fromCFString(title);
            if(AXUIElementCopyAttributeValue (window, kAXURLAttribute,
                                              reinterpret_cast<CFTypeRef*>(&title))!=kAXErrorSuccess)
            CFRelease(window);
        }
1 Answers

There doesn't appear to be any general way to do this. For example, Firefox does not expose anything about its windows through the Accessibility API.

With Safari, I was able to find the URL, but it was a bit buried within the UI Element hierarchy. For example, in AppleScript object specifier syntax, the object is:

UI element 2 of group 2 of toolbar 1 of window 1 of ¬
    application process "Safari" of application "System Events"

The element's role is "AXSafariAddressAndSearchField" and its value is the URL. If the user is part-way through editing the content of that field, its value may show the edit and not the URL of whatever's actually displayed. I don't know.

There's also:

UI element 1 of scroll area 1 of group 1 of group 1 of ¬
    tab group 1 of splitter group 1 of window 1 of ¬
    application process "Safari" of application "System Events"

It's the element whose role is "AXWebArea". It has an "AXURL" (kAXURLAttribute) attribute whose value is the URL of the page.

Those accessibility paths may differ for other versions of Safari or different UI configurations. (For example, my window had only one tab open.)

You'll probably have to write code to enumerate the whole element hierarchy looking for the one you want by role.

I haven't tested with Chrome. I did see a reference to "AXWebArea" in its sources, though, so the same strategy may work for it.

Related