我可以使用以下 AppleScript 打开“终端”选项卡:
tell application "Terminal"
set myTab to do script "exec sleep 1"
get myTab
end tell
这将返回一个字符串,例如:
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]
如何从选项卡对象中获取窗口 ID 和选项卡编号?
编辑2009/4/27 - 为什么?
回答我为什么要这样做 - 我在终端窗口中打开一个命令(如上所述),并返回 tab 对象。但是我想移动/调整此窗口的大小,因此我需要访问选项卡的“窗口”对象。
我正在使用 Objective-C(实际上,Objective-C 从 Perl 桥接),并且想要坚持使用标准操作系统组件,所以我相信我只有 NSAppleScript 和 ScriptingBridge 框架可以使用(所有 perl applescript 模块都与64位除碳)。我会尝试 NSAppleScript,但处理返回值似乎是一种黑术。
我当前的解决方案是获取选项卡对象的TTY(保证唯一)并枚举每个窗口的每个选项卡,直到找到包含该选项卡的窗口。我认为这不是最好的方法(它肯定不快!)。
编辑2009/4/30 - 解决方案
根据下面“has”的建议,我勇敢地使用了NSAppleEventDescriptor API。最初,我只能通过 NSAppleScript 的
executeAndReturnError()
调用来实现这一点。然而我发现 NSAppleScript 比 ScriptingBridge 慢得多。
使用 ClassDump 提取更多 SBObject 调用后,我发现了未记录的
specifierDescription()
和 qualifiedSpecifier()
调用。前者给了我漂亮的“tab X of window id Y”字符串。后者返回苹果事件描述符,然后我可以对其进行解码。
我的最终代码(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";
我知道这是一个老问题,但我今天才遇到这个问题,并且在网上找不到好的答案。这对我有用:
tell application "Terminal"
set newTab to do script "echo hello"
set theWindow to first window of (every window whose tabs contains newTab)
set windowId to theWindow's id
repeat with i from 1 to the count of theWindow's tabs
if item i of theWindow's tabs is newTab then set tabNumber to i
end repeat
get {windowId, tabNumber}
end tell
从技术上讲你不能;更好的问题是为什么要这么做?
(好吧,如果你使用Apple Event Manager API或objc-appscript,你就可以,这两者都可以给你一个原始的AEDesc/NSAppleEventDescriptor,你可以递归地自己拆开。或者你可以在SB 看看是否有一个未记录的 API 可以获取底层 AEDES,但买者自负,当然,或者,可能有更好的方法来实现您的实际目标,而无需诉诸黑客,但您需要提供更多信息。 )
像这样非常简单的事情怎么样:
tell application "Terminal"
set new_win to do script ""
set w_id to id of front window
end tell