Получить заголовок текущего активного окна/документа в Mac OS X

Ссылаясь на ранее запрошенный question, я хотел бы знать, как получить заголовок текущего активного документа.

Я попытался упомянуть script в ответах на вопрос выше. Это работает, но дает мне только имя приложения. Например, я пишу этот вопрос: когда я запускаю script, он дает мне имя приложения, то есть "Firefox". Это довольно аккуратно, но на самом деле это не помогает. Я бы предпочел захватить название моего текущего активного документа. См. Изображение.

Заголовок Firefox http://img.skitch.com/20090126-nq2egknhjr928d1s74i9xixckf.jpg

Я использую Leopard, поэтому никакой обратной совместимости не требуется. Также я использую Python Appkit, чтобы получить доступ к классу NSWorkspace, но если вы скажете мне код Objective-C, я смог бы вычислить перевод на Python.


Хорошо, у меня есть решение, которое не очень удовлетворительно, вот почему я не отмечаю ответ Koen Bok. По крайней мере, пока.
tell application "System Events"
set frontApp to name of first application process whose frontmost is true
end tell
tell application frontApp
if the (count of windows) is not 0 then
    set window_name to name of front window
end if
end tell

Сохранить как script и вызвать его с помощью osascript из оболочки.

Ответ 2

В Objective-C короткий ответ с использованием небольшого Cocoa и в основном Carbon Accessibility API:

// Get the process ID of the frontmost application.
NSRunningApplication* app = [[NSWorkspace sharedWorkspace]
                              frontmostApplication];
pid_t pid = [app processIdentifier];

// See if we have accessibility permissions, and if not, prompt the user to
// visit System Preferences.
NSDictionary *options = @{(id)kAXTrustedCheckOptionPrompt: @YES};
Boolean appHasPermission = AXIsProcessTrustedWithOptions(
                             (__bridge CFDictionaryRef)options);
if (!appHasPermission) {
   return; // we don't have accessibility permissions

// Get the accessibility element corresponding to the frontmost application.
AXUIElementRef appElem = AXUIElementCreateApplication(pid);
if (!appElem) {
  return;
}

// Get the accessibility element corresponding to the frontmost window
// of the frontmost application.
AXUIElementRef window = NULL;
if (AXUIElementCopyAttributeValue(appElem, 
      kAXFocusedWindowAttribute, (CFTypeRef*)&window) != kAXErrorSuccess) {
  CFRelease(appElem);
  return;
}

// Finally, get the title of the frontmost window.
CFStringRef title = NULL;
AXError result = AXUIElementCopyAttributeValue(window, kAXTitleAttribute,
                   (CFTypeRef*)&title);

// At this point, we don't need window and appElem anymore.
CFRelease(window);
CFRelease(appElem);

if (result != kAXErrorSuccess) {
  // Failed to get the window title.
  return;
}

// Success! Now, do something with the title, e.g. copy it somewhere.

// Once we're done with the title, release it.
CFRelease(title);

В качестве альтернативы, может быть проще использовать API CGWindow, как указано в fooobar.com/info/336565/....