如何通过ScriptingBridge使用AppleScript获取终端窗口的窗口ID和标签号?

Gav*_*ock 5 cocoa applescript appleevents scripting-bridge

我可以使用以下AppleScript打开终端选项卡:

tell application "Terminal"
    set myTab to do script "exec sleep 1"
    get myTab
end tell
Run Code Online (Sandbox Code Playgroud)

这将返回一个字符串,如:tab 1 of window id 3263 of application "Terminal".这很好,我可以看到窗口ID 3263和标签号1(虽然我不知道如何查询myTab只获取这些值).

在Cocoa ScriptingBridge中,我可以这样做:

SBApplication  *terminal;
SBObject       *tab;

terminal = [SBApplication applicationWithBundleIdentifier:@"com.apple.terminal"]
tab = [terminal doScript:@"exec sleep 1" in:nil]
Run Code Online (Sandbox Code Playgroud)

如何从选项卡对象中获取窗口ID和选项卡编号?


编辑2009/4/27 - 为什么?

为了回答我为什么要这样做 - 我在终端窗口中打开一个命令(如上所述),然后我回到了tab对象.但是我想移动/调整此窗口的大小,因此我需要访问选项卡的"窗口"对象.

我正在使用Objective-C(实际上,从Perl桥接的Objective-C),并且希望坚持使用标准的OS组件,因此我相信我只能使用NSAppleScript和ScriptingBridge框架(所有perl applescript模块都打破了64位除碳).我会尝试NSAppleScript,但处理返回的值似乎是一个黑暗的艺术.

我目前的解决方案是获取选项卡对象的TTY(保证唯一)并枚举每个窗口的每个选项卡,直到找到包含选项卡的窗口.我认为这不是最好的方法(肯定不是很快!).


编辑2009/4/30 - 解决方案

根据下面" has " 的建议,我了一个NSAppleEventDescriptor API.最初,我只能通过NSAppleScript的executeAndReturnError()调用来实现这一目标.但是我发现NSAppleScript比ScriptingBridge慢得多.

使用后ClassDump提取一些更SBObject电话,我发现无证specifierDescription()qualifiedSpecifier()电话.前者给了我很好的" 窗口ID Y的标签X "字符串.后者返回apple事件描述符,然后我可以解码.

我的最终代码(在perl中)是:

use Foundation;

NSBundle->bundleWithPath_('/System/Library/Frameworks/ScriptingBridge.framework')->load;

# Create an OSType (bid endian long) from a string
sub OSType ($) { return unpack('N', $_[0]) }

my $terminal = SBApplication->applicationWithBundleIdentifier_("com.apple.terminal");

my $tab         = $terminal->doScript_in_("exec sleep 1", undef);
my $tab_ev_desc = $tab->qualifiedSpecifier;
my $tab_id      = $tab_ev_desc->descriptorForKeyword_(OSType 'seld')->int32Value;
my $win_ev_desc = $tab_ev_desc->descriptorForKeyword_(OSType 'from');
my $window_id   = $win_ev_desc->descriptorForKeyword_(OSType 'seld')->int32Value;

print "Window:$window_id Tab:$tab_id\n";
Run Code Online (Sandbox Code Playgroud)

has*_*has 1

从技术上讲你不能;更好的问题是为什么要这样做?

(好吧,如果你使用 Apple Event Manager API 或objc-appscript,你就可以,这两者都可以给你一个原始的 AEDesc/NSAppleEventDescriptor ,你可以自己递归地拆开它。或者你可以在 SB 中看看是否有一个未记录的 API 来获取底层 AEDesc,但当然要买者自负。或者,可能有更好的方法来实现您的实际目标,而无需诉诸黑客手段,但您需要提供更多信息。)