5

我可以使用以下 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 - 为什么?

为了回答我为什么要这样做 - 我在终端窗口中打开一个命令(如上),并取回选项卡对象。但是我想移动/调整这个窗口的大小,所以我需要访问选项卡的“窗口”对象。

我正在使用 Objective-C(实际上,是从 Perl 桥接的 Objective-C),并且想坚持使用标准的 OS 组件,所以我相信我只有 NSAppleScript 和 ScriptingBridge 框架可以使用(所有 perl applescript 模块都与 64 位无关碳去除)。我会尝试 NSAppleScript,但处理返回的值似乎是一种黑色艺术。

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


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

根据下面“”的建议,我勇敢地使用了NSAppleEventDescriptor API。最初,我只能通过 NSAppleScript 的executeAndReturnError()调用来解决这个问题。但是我发现 NSAppleScript 比 ScriptingBridge 慢得多。

在使用ClassDump提取更多的 SBObject 调用后,我发现了未记录的specifierDescription()qualifiedSpecifier()调用。前者给了我很好的“窗口ID Y的标签X ”字符串。后者返回苹果事件描述符,然后我可以对其进行解码。

我的最终代码(在 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";
4

3 回答 3

4

我知道这是一个老问题,但我今天才遇到这个问题,我在网上找不到好的答案。这对我有用:

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
于 2015-07-17T18:59:07.807 回答
1

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

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

于 2010-04-26T16:57:44.207 回答
0

像这样非常简单的事情怎么样:

告诉应用程序“终端”设置 new_win 执行脚本“”设置 w_id 到前端窗口的 id end tell

于 2012-03-14T17:52:22.660 回答