Как получить идентификатор окна и номер вкладки окна терминала с помощью AppleScript через ScriptingBridge?

Я могу открыть вкладку "Терминал", используя следующий 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", Это здорово, я вижу окно с идентификатором 3263 и вкладку № 1 (хотя я не знаю, как запросить myTab, чтобы получить только эти значения).

В Cocoa ScriptingBridge я могу сделать:

SBApplication  *terminal;
SBObject       *tab;

terminal = [SBApplication applicationWithBundleIdentifier:@"com.apple.terminal"]
tab = [terminal doScript:@"exec sleep 1" in:nil]

Как получить идентификатор окна и номер вкладки из объекта вкладки?


Изменить 2009/4/27 - Почему?

В ответ на вопрос, почему я хочу это сделать - я открываю команду в окне терминала (как указано выше) и возвращаю объект табуляции. Однако я хочу переместить / изменить размер этого окна, поэтому мне нужно получить доступ к объекту "окна" вкладки.

Я использую Objective-C (ну, на самом деле, Objective-C соединился с Perl) и хочу придерживаться стандартных компонентов ОС, поэтому я считаю, что у меня есть только платформы NSAppleScript и ScriptingBridge для игры (все модули perl applecript сломались с 64bit удаление углерода). Я бы попробовал NSAppleScript, но обработка возвращаемых значений кажется чёрным искусством.

Мое текущее решение состоит в том, чтобы получить TTY объекта вкладки (гарантированно уникальный) и перечислять каждую вкладку каждого окна, пока я не найду окно, содержащее вкладку. Я предположил, что это не может быть лучшим способом (это, конечно, не быстро!).


Редактировать 2009/4/30 - Решение

Основываясь на предложениях " has" ниже, я выдержал API NSAppleEventDescriptor. Изначально я смог добраться до этого только с помощью NSAppleScript executeAndReturnError() вызов. Однако я обнаружил, что NSAppleScript был намного, намного медленнее, чем ScriptingBridge.

После использования ClassDump для извлечения дополнительных вызовов SBObject я обнаружил недокументированные specifierDescription() а также qualifiedSpecifier() звонки. Первый дает мне красивую строку "tab X of id окна Y". Последний возвращает дескриптор события 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";

3 ответа

Решение

Технически вы не можете; лучший вопрос, почему вы хотите?

(Ну, ладно, вы могли бы, если бы вы использовали API Apple Event Manager или objc-appscript, оба из которых могут дать вам сырой AEDesc/NSAppleEventDescriptor, который вы можете рекурсивно разбирать на части. Или вы можете покопаться в SB, чтобы увидеть, есть ли недокументированный API для доступа к базовому AEDesc, но, конечно, предостерегающий emptor. В качестве альтернативы может существовать лучший способ достичь своей реальной цели, не прибегая к хакерским атакам, но вам нужно будет предоставить больше информации.)

Я знаю, что это старый вопрос, но у меня сегодня была эта проблема, и я не нашел хороших ответов в Интернете. Это сработало для меня:

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

Как насчет чего-то очень простого, такого как это:

скажите приложению "Терминал", установите new_win для выполнения скрипта "", установите w_id в id переднего окна

Другие вопросы по тегам