获取Mac OS X中当前活动窗口/文档的标题

时间:2009-01-26 18:32:53

标签: python objective-c macos

参考之前提到的question,我想知道如何获取当前活动文档的标题。

我在上面问题的答案中尝试了脚本。这有效,但只给出了应用程序的名称。例如,我正在写这个问题:当我启动脚本时它会给我应用程序的名称,即“Firefox”。这很整洁,但并没有真正帮助。我想要捕获我当前活动文档的标题。看图像。

Firefox title 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

另存为脚本并使用shell中的osascript调用它。

2 个答案:

答案 0 :(得分:7)

据我所知,你最好的选择是包装AppleScript。但AppleScript对我来说是神奇的,所以我把它作为提问者的练习:-)

这可能有点帮助:A script to resize frontmost two windows to fill screen - Mac OS X Hints

答案 1 :(得分: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);

或者,使用CGWindow API可能更简单,如this StackOverflow answer中提到的那样。